Skip to content

Commit b7859e7

Browse files
authored
examples: Add a JWT authentication example (#5915)
1 parent 58e6ad7 commit b7859e7

File tree

13 files changed

+861
-0
lines changed

13 files changed

+861
-0
lines changed

RELEASING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ $ VERSION_FILES=(
4545
examples/example-alts/build.gradle
4646
examples/example-gauth/build.gradle
4747
examples/example-gauth/pom.xml
48+
examples/example-jwt-auth/build.gradle
49+
examples/example-jwt-auth/pom.xml
4850
examples/example-hostname/build.gradle
4951
examples/example-hostname/pom.xml
5052
examples/example-kotlin/build.gradle

examples/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ $ bazel-bin/hello-world-client
156156

157157
- [Google Authentication](example-gauth)
158158

159+
- [JWT-based Authentication](example-jwt-auth)
160+
159161
- [Kotlin examples](example-kotlin)
160162

161163
- [Kotlin Android examples](example-kotlin/android)

examples/example-jwt-auth/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
Authentication Example
2+
==============================================
3+
4+
This example illustrates a simple JWT-based authentication implementation in gRPC using
5+
server interceptor. It uses the JJWT library to create and verify JSON Web Tokens (JWTs).
6+
7+
The example requires grpc-java to be pre-built. Using a release tag will download the relevant binaries
8+
from a maven repository. But if you need the latest SNAPSHOT binaries you will need to follow
9+
[COMPILING](../../COMPILING.md) to build these.
10+
11+
The source code is [here](src/main/java/io/grpc/examples/jwtauth).
12+
To build the example, run in this directory:
13+
```
14+
$ ../gradlew installDist
15+
```
16+
The build creates scripts `auth-server` and `auth-client` in the `build/install/example-jwt-auth/bin/` directory
17+
which can be used to run this example. The example requires the server to be running before starting the
18+
client.
19+
20+
Running auth-server is similar to the normal hello world example and there are no arguments to supply:
21+
22+
**auth-server**:
23+
24+
The auth-server accepts optional argument for port on which the server should run:
25+
26+
```text
27+
USAGE: auth-server [port]
28+
```
29+
30+
The auth-client accepts optional arguments for server-host, server-port, user-name and client-id:
31+
32+
**auth-client**:
33+
34+
```text
35+
USAGE: auth-client [server-host [server-port [user-name [client-id]]]]
36+
```
37+
38+
The `user-name` value is simply passed in the `HelloRequest` message as payload and the value of
39+
`client-id` is included in the JWT claims passed in the metadata header.
40+
41+
42+
#### How to run the example:
43+
44+
```bash
45+
# Run the server:
46+
./build/install/example-jwt-auth/bin/auth-server 50051
47+
# In another terminal run the client
48+
./build/install/example-jwt-auth/bin/auth-client localhost 50051 userA clientB
49+
```
50+
51+
That's it! The client will show the user-name reflected back in the message from the server as follows:
52+
```
53+
INFO: Greeting: Hello, userA
54+
```
55+
56+
And on the server side you will see the message with the client's identifier:
57+
```
58+
Processing request from clientB
59+
```
60+
61+
## Maven
62+
63+
If you prefer to use Maven follow these [steps](../README.md#maven). You can run the example as follows:
64+
65+
```
66+
$ # Run the server
67+
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.authentication.AuthServer -Dexec.args="50051"
68+
$ # In another terminal run the client
69+
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.authentication.AuthClient -Dexec.args="localhost 50051 userA clientB"
70+
```
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
plugins {
2+
// Provide convenience executables for trying out the examples.
3+
id 'application'
4+
// ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier gradle versions
5+
id 'com.google.protobuf' version '0.8.8'
6+
// Generate IntelliJ IDEA's .idea & .iml project files
7+
id 'idea'
8+
}
9+
10+
repositories {
11+
maven { // The google mirror is less flaky than mavenCentral()
12+
url "https://maven-central.storage-download.googleapis.com/repos/central/data/"
13+
}
14+
mavenLocal()
15+
}
16+
17+
sourceCompatibility = 1.7
18+
targetCompatibility = 1.7
19+
20+
// IMPORTANT: You probably want the non-SNAPSHOT version of gRPC. Make sure you
21+
// are looking at a tagged version of the example and not "master"!
22+
23+
// Feel free to delete the comment at the next line. It is just for safely
24+
// updating the version in our release process.
25+
def grpcVersion = '1.29.0-SNAPSHOT' // CURRENT_GRPC_VERSION
26+
def protobufVersion = '3.11.0'
27+
def protocVersion = protobufVersion
28+
29+
dependencies {
30+
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
31+
implementation "io.grpc:grpc-stub:${grpcVersion}"
32+
implementation "io.jsonwebtoken:jjwt:0.9.1"
33+
implementation "javax.xml.bind:jaxb-api:2.3.1"
34+
35+
compileOnly "javax.annotation:javax.annotation-api:1.2"
36+
37+
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
38+
39+
testImplementation "io.grpc:grpc-testing:${grpcVersion}"
40+
testImplementation "junit:junit:4.12"
41+
testImplementation "org.mockito:mockito-core:2.28.2"
42+
}
43+
44+
protobuf {
45+
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
46+
plugins {
47+
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
48+
}
49+
generateProtoTasks {
50+
all()*.plugins { grpc {} }
51+
}
52+
}
53+
54+
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
55+
sourceSets {
56+
main {
57+
java {
58+
srcDirs 'build/generated/source/proto/main/grpc'
59+
srcDirs 'build/generated/source/proto/main/java'
60+
}
61+
}
62+
}
63+
64+
startScripts.enabled = false
65+
66+
task hellowWorldJwtAuthServer(type: CreateStartScripts) {
67+
mainClassName = 'io.grpc.examples.jwtauth.AuthServer'
68+
applicationName = 'auth-server'
69+
outputDir = new File(project.buildDir, 'tmp')
70+
classpath = startScripts.classpath
71+
}
72+
73+
task hellowWorldJwtAuthClient(type: CreateStartScripts) {
74+
mainClassName = 'io.grpc.examples.jwtauth.AuthClient'
75+
applicationName = 'auth-client'
76+
outputDir = new File(project.buildDir, 'tmp')
77+
classpath = startScripts.classpath
78+
}
79+
80+
applicationDistribution.into('bin') {
81+
from(hellowWorldJwtAuthServer)
82+
from(hellowWorldJwtAuthClient)
83+
fileMode = 0755
84+
}

examples/example-jwt-auth/pom.xml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>io.grpc</groupId>
6+
<artifactId>example-jwt-auth</artifactId>
7+
<packaging>jar</packaging>
8+
<!-- Feel free to delete the comment at the end of these lines. It is just
9+
for safely updating the version in our release process. -->
10+
<version>1.29.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
11+
<name>example-jwt-auth</name>
12+
<url>https://github.com/grpc/grpc-java</url>
13+
14+
<properties>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
<grpc.version>1.29.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
17+
<protobuf.version>3.11.0</protobuf.version>
18+
<protoc.version>3.11.0</protoc.version>
19+
<!-- required for jdk9 -->
20+
<maven.compiler.source>1.7</maven.compiler.source>
21+
<maven.compiler.target>1.7</maven.compiler.target>
22+
</properties>
23+
24+
<dependencyManagement>
25+
<dependencies>
26+
<dependency>
27+
<groupId>io.grpc</groupId>
28+
<artifactId>grpc-bom</artifactId>
29+
<version>${grpc.version}</version>
30+
<type>pom</type>
31+
<scope>import</scope>
32+
</dependency>
33+
</dependencies>
34+
</dependencyManagement>
35+
36+
<dependencies>
37+
<dependency>
38+
<groupId>io.grpc</groupId>
39+
<artifactId>grpc-netty-shaded</artifactId>
40+
<scope>runtime</scope>
41+
</dependency>
42+
<dependency>
43+
<groupId>io.grpc</groupId>
44+
<artifactId>grpc-protobuf</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>io.grpc</groupId>
48+
<artifactId>grpc-stub</artifactId>
49+
</dependency>
50+
<dependency>
51+
<groupId>io.jsonwebtoken</groupId>
52+
<artifactId>jjwt</artifactId>
53+
<version>0.9.1</version>
54+
</dependency>
55+
<dependency>
56+
<groupId>javax.xml.bind</groupId>
57+
<artifactId>jaxb-api</artifactId>
58+
<version>2.3.1</version>
59+
</dependency>
60+
<dependency>
61+
<groupId>javax.annotation</groupId>
62+
<artifactId>javax.annotation-api</artifactId>
63+
<version>1.2</version>
64+
<scope>provided</scope> <!-- not needed at runtime -->
65+
</dependency>
66+
<dependency>
67+
<groupId>io.grpc</groupId>
68+
<artifactId>grpc-testing</artifactId>
69+
<scope>test</scope>
70+
</dependency>
71+
<dependency>
72+
<groupId>junit</groupId>
73+
<artifactId>junit</artifactId>
74+
<version>4.12</version>
75+
<scope>test</scope>
76+
</dependency>
77+
<dependency>
78+
<groupId>org.mockito</groupId>
79+
<artifactId>mockito-core</artifactId>
80+
<version>2.28.2</version>
81+
<scope>test</scope>
82+
</dependency>
83+
</dependencies>
84+
85+
<build>
86+
<extensions>
87+
<extension>
88+
<groupId>kr.motd.maven</groupId>
89+
<artifactId>os-maven-plugin</artifactId>
90+
<version>1.5.0.Final</version>
91+
</extension>
92+
</extensions>
93+
<plugins>
94+
<plugin>
95+
<groupId>org.xolstice.maven.plugins</groupId>
96+
<artifactId>protobuf-maven-plugin</artifactId>
97+
<version>0.5.1</version>
98+
<configuration>
99+
<protocArtifact>
100+
com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
101+
</protocArtifact>
102+
<pluginId>grpc-java</pluginId>
103+
<pluginArtifact>
104+
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
105+
</pluginArtifact>
106+
</configuration>
107+
<executions>
108+
<execution>
109+
<goals>
110+
<goal>compile</goal>
111+
<goal>compile-custom</goal>
112+
</goals>
113+
</execution>
114+
</executions>
115+
</plugin>
116+
<plugin>
117+
<groupId>org.apache.maven.plugins</groupId>
118+
<artifactId>maven-enforcer-plugin</artifactId>
119+
<version>1.4.1</version>
120+
<executions>
121+
<execution>
122+
<id>enforce</id>
123+
<goals>
124+
<goal>enforce</goal>
125+
</goals>
126+
<configuration>
127+
<rules>
128+
<requireUpperBoundDeps/>
129+
</rules>
130+
</configuration>
131+
</execution>
132+
</executions>
133+
</plugin>
134+
</plugins>
135+
</build>
136+
</project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pluginManagement {
2+
repositories {
3+
maven { // The google mirror is less flaky than mavenCentral()
4+
url "https://maven-central.storage-download.googleapis.com/repos/central/data/"
5+
}
6+
gradlePluginPortal()
7+
}
8+
}

0 commit comments

Comments
 (0)