diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel index 30352e262b7f..7586cfb3f07d 100644 --- a/examples/BUILD.bazel +++ b/examples/BUILD.bazel @@ -99,24 +99,6 @@ java_binary( ], ) -java_binary( - name = "auth-client", - testonly = 1, - main_class = "io.grpc.examples.authentication.AuthClient", - runtime_deps = [ - ":examples", - ], -) - -java_binary( - name = "auth-server", - testonly = 1, - main_class = "io.grpc.examples.authentication.AuthServer", - runtime_deps = [ - ":examples", - ], -) - java_binary( name = "route-guide-client", testonly = 1, diff --git a/examples/README.md b/examples/README.md index a125cd8e6536..184577deb32b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -25,8 +25,6 @@ before trying out the examples. - [Json serialization](src/main/java/io/grpc/examples/advanced) -- [Authentication](AUTHENTICATION_EXAMPLE.md) - -
Hedging @@ -161,6 +159,8 @@ $ bazel-bin/hello-world-client - [Google Authentication](example-gauth) +- [JWT-based Authentication](example-jwt-auth/README.md) + - [Kotlin examples](example-kotlin) - [Kotlin Android examples](example-kotlin/android) diff --git a/examples/build.gradle b/examples/build.gradle index 0c4d5cc9573f..219b5fc110a2 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -32,11 +32,7 @@ dependencies { // examples/advanced need this for JsonFormat implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}" - - // examples/authentication need this to create and verify JSON Web Tokens (JWTs) - implementation "io.jsonwebtoken:jjwt:0.9.1" - implementation "javax.xml.bind:jaxb-api:2.3.1" - + runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}" testImplementation "io.grpc:grpc-testing:${grpcVersion}" @@ -108,20 +104,6 @@ task hedgingHelloWorldClient(type: CreateStartScripts) { classpath = startScripts.classpath } -task authServer(type: CreateStartScripts) { - mainClassName = 'io.grpc.examples.authentication.AuthServer' - applicationName = 'auth-server' - outputDir = new File(project.buildDir, 'tmp') - classpath = startScripts.classpath -} - -task authClient(type: CreateStartScripts) { - mainClassName = 'io.grpc.examples.authentication.AuthClient' - applicationName = 'auth-client' - outputDir = new File(project.buildDir, 'tmp') - classpath = startScripts.classpath -} - task compressingHelloWorldClient(type: CreateStartScripts) { mainClassName = 'io.grpc.examples.experimental.CompressingHelloWorldClient' applicationName = 'compressing-hello-world-client' @@ -136,8 +118,6 @@ applicationDistribution.into('bin') { from(helloWorldClient) from(hedgingHelloWorldClient) from(hedgingHelloWorldServer) - from(authServer) - from(authClient) from(compressingHelloWorldClient) fileMode = 0755 } diff --git a/examples/AUTHENTICATION_EXAMPLE.md b/examples/example-jwt-auth/README.md similarity index 74% rename from examples/AUTHENTICATION_EXAMPLE.md rename to examples/example-jwt-auth/README.md index 124a89991959..13a6c8092525 100644 --- a/examples/AUTHENTICATION_EXAMPLE.md +++ b/examples/example-jwt-auth/README.md @@ -6,10 +6,10 @@ This example illustrates a simple JWT-based authentication implementation in gRP The example requires grpc-java to be pre-built. Using a release tag will download the relevant binaries from a maven repository. But if you need the latest SNAPSHOT binaries you will need to follow -[COMPILING](../COMPILING.md) to build these. +[COMPILING](../../COMPILING.md) to build these. The source code is [here](src/main/java/io/grpc/examples/authentication). Please follow the -[steps](./README.md#to-build-the-examples) to build the examples. The build creates scripts +[steps](../README.md#to-build-the-examples) to build the examples. The build creates scripts `auth-server` and `auth-client` in the `build/install/examples/bin/` directory which can be used to run this example. The example requires the server to be running before starting the client. @@ -38,9 +38,9 @@ The `user-name` value is simply passed in the `HelloRequest` message as payload ```bash # Run the server: -./build/install/examples/bin/auth-server +./build/install/example-jwt-auth/bin/auth-server # In another terminal run the client -./build/install/examples/bin/auth-client userA clientB +./build/install/example-jwt-auth/bin/auth-client userA clientB ``` That's it! The client will show the user-name reflected back in the message from the server as follows: @@ -55,22 +55,11 @@ Processing request from clientB ## Maven -If you prefer to use Maven follow these [steps](./README.md#maven). You can run the example as follows: +If you prefer to use Maven follow these [steps](../README.md#maven). You can run the example as follows: ``` $ # Run the server $ mvn exec:java -Dexec.mainClass=io.grpc.examples.authentication.AuthServer $ # In another terminal run the client -$ mvn exec:java -Dexec.mainClass=io.grpc.examples.authentication.AuthClient -Dexec.args="client-userA token-valueB" -``` - -## Bazel - -If you prefer to use Bazel: -``` -$ bazel build :auth-server :auth-client -$ # Run the server -$ bazel-bin/auth-server -$ # In another terminal run the client -$ bazel-bin/auth-client client-userA token-valueB +$ mvn exec:java -Dexec.mainClass=io.grpc.examples.authentication.AuthClient -Dexec.args="userA clientB" ``` diff --git a/examples/example-jwt-auth/build.gradle b/examples/example-jwt-auth/build.gradle new file mode 100644 index 000000000000..1e36048f3931 --- /dev/null +++ b/examples/example-jwt-auth/build.gradle @@ -0,0 +1,84 @@ +plugins { + // Provide convenience executables for trying out the examples. + id 'application' + // ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier gradle versions + id 'com.google.protobuf' version '0.8.8' + // Generate IntelliJ IDEA's .idea & .iml project files + id 'idea' +} + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url "https://maven-central.storage-download.googleapis.com/repos/central/data/" + } + mavenLocal() +} + +sourceCompatibility = 1.7 +targetCompatibility = 1.7 + +// IMPORTANT: You probably want the non-SNAPSHOT version of gRPC. Make sure you +// are looking at a tagged version of the example and not "master"! + +// Feel free to delete the comment at the next line. It is just for safely +// updating the version in our release process. +def grpcVersion = '1.23.0-SNAPSHOT' // CURRENT_GRPC_VERSION +def protobufVersion = '3.7.1' +def protocVersion = protobufVersion + +dependencies { + implementation "io.grpc:grpc-protobuf:${grpcVersion}" + implementation "io.grpc:grpc-stub:${grpcVersion}" + implementation "io.jsonwebtoken:jjwt:0.9.1" + implementation "javax.xml.bind:jaxb-api:2.3.1" + + compileOnly "javax.annotation:javax.annotation-api:1.2" + + runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}" + + testImplementation "io.grpc:grpc-testing:${grpcVersion}" + testImplementation "junit:junit:4.12" + testImplementation "org.mockito:mockito-core:2.25.1" +} + +protobuf { + protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" } + plugins { + grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } + } + generateProtoTasks { + all()*.plugins { grpc {} } + } +} + +// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code. +sourceSets { + main { + java { + srcDirs 'build/generated/source/proto/main/grpc' + srcDirs 'build/generated/source/proto/main/java' + } + } +} + +startScripts.enabled = false + +task authServer(type: CreateStartScripts) { + mainClassName = 'io.grpc.examples.authentication.AuthServer' + applicationName = 'auth-server' + outputDir = new File(project.buildDir, 'tmp') + classpath = startScripts.classpath +} + +task authClient(type: CreateStartScripts) { + mainClassName = 'io.grpc.examples.authentication.AuthClient' + applicationName = 'auth-client' + outputDir = new File(project.buildDir, 'tmp') + classpath = startScripts.classpath +} + +applicationDistribution.into('bin') { + from(authServer) + from(authClient) + fileMode = 0755 +} diff --git a/examples/example-jwt-auth/pom.xml b/examples/example-jwt-auth/pom.xml new file mode 100644 index 000000000000..f5a018f23924 --- /dev/null +++ b/examples/example-jwt-auth/pom.xml @@ -0,0 +1,136 @@ + + 4.0.0 + io.grpc + example-jwt-auth + jar + + 1.23.0-SNAPSHOT + example-jwt-auth + https://github.com/grpc/grpc-java + + + UTF-8 + 1.23.0-SNAPSHOT + 3.7.1 + 3.7.1 + + 1.7 + 1.7 + + + + + + io.grpc + grpc-bom + ${grpc.version} + pom + import + + + + + + + io.grpc + grpc-netty-shaded + runtime + + + io.grpc + grpc-protobuf + + + io.grpc + grpc-stub + + + io.jsonwebtoken + jjwt + 0.9.1 + + + javax.xml.bind + jaxb-api + 2.3.1 + + + javax.annotation + javax.annotation-api + 1.2 + provided + + + io.grpc + grpc-testing + test + + + junit + junit + 4.12 + test + + + org.mockito + mockito-core + 2.25.1 + test + + + + + + + kr.motd.maven + os-maven-plugin + 1.5.0.Final + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.5.1 + + + com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + + grpc-java + + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + + compile + compile-custom + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.4.1 + + + enforce + + enforce + + + + + + + + + + + + diff --git a/examples/example-jwt-auth/settings.gradle b/examples/example-jwt-auth/settings.gradle new file mode 100644 index 000000000000..59ef05d47dd3 --- /dev/null +++ b/examples/example-jwt-auth/settings.gradle @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + maven { // The google mirror is less flaky than mavenCentral() + url "https://maven-central.storage-download.googleapis.com/repos/central/data/" + } + gradlePluginPortal() + } +} diff --git a/examples/src/main/java/io/grpc/examples/authentication/AuthClient.java b/examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/AuthClient.java similarity index 100% rename from examples/src/main/java/io/grpc/examples/authentication/AuthClient.java rename to examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/AuthClient.java diff --git a/examples/src/main/java/io/grpc/examples/authentication/AuthServer.java b/examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/AuthServer.java similarity index 100% rename from examples/src/main/java/io/grpc/examples/authentication/AuthServer.java rename to examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/AuthServer.java diff --git a/examples/src/main/java/io/grpc/examples/authentication/BearerToken.java b/examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/BearerToken.java similarity index 100% rename from examples/src/main/java/io/grpc/examples/authentication/BearerToken.java rename to examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/BearerToken.java diff --git a/examples/src/main/java/io/grpc/examples/authentication/Constant.java b/examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/Constant.java similarity index 100% rename from examples/src/main/java/io/grpc/examples/authentication/Constant.java rename to examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/Constant.java diff --git a/examples/src/main/java/io/grpc/examples/authentication/JwtServerInterceptor.java b/examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/JwtServerInterceptor.java similarity index 100% rename from examples/src/main/java/io/grpc/examples/authentication/JwtServerInterceptor.java rename to examples/example-jwt-auth/src/main/java/io/grpc/examples/authentication/JwtServerInterceptor.java diff --git a/examples/example-jwt-auth/src/main/proto/helloworld.proto b/examples/example-jwt-auth/src/main/proto/helloworld.proto new file mode 100644 index 000000000000..c60d9416f1fc --- /dev/null +++ b/examples/example-jwt-auth/src/main/proto/helloworld.proto @@ -0,0 +1,37 @@ +// Copyright 2015 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.examples.helloworld"; +option java_outer_classname = "HelloWorldProto"; +option objc_class_prefix = "HLW"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/examples/src/test/java/io/grpc/examples/authentication/AuthClientTest.java b/examples/example-jwt-auth/src/test/java/io/grpc/examples/authentication/AuthClientTest.java similarity index 100% rename from examples/src/test/java/io/grpc/examples/authentication/AuthClientTest.java rename to examples/example-jwt-auth/src/test/java/io/grpc/examples/authentication/AuthClientTest.java