├── .gitignore ├── API-Gateway-service ├── .gitignore ├── Dockerfile ├── build.gradle ├── docker-compose.yml ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── umesh │ │ │ └── gateway │ │ │ ├── ApiGatewayServiceApplication.java │ │ │ ├── config │ │ │ ├── AuthFilter.java │ │ │ ├── AuthFilterConfig.java │ │ │ ├── FeignConfig.java │ │ │ └── RouteConfig.java │ │ │ ├── controller │ │ │ └── HystrixController.java │ │ │ ├── model │ │ │ └── AuthTokenModel.java │ │ │ └── service │ │ │ └── AuthService.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── umesh │ └── gateway │ └── ApiGatewayServiceApplicationTests.java ├── ClientService ├── .gitignore ├── Dockerfile ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── umesh │ │ │ └── client │ │ │ ├── ClientServiceApplication.java │ │ │ ├── config │ │ │ ├── PropertySource.java │ │ │ └── SecurityConfig.java │ │ │ ├── controller │ │ │ └── FirstController.java │ │ │ ├── exception │ │ │ └── AuthException.java │ │ │ ├── security │ │ │ ├── AuthAccessDeniedHandler.java │ │ │ ├── AuthProvider.java │ │ │ ├── AuthRoleModel.java │ │ │ ├── AuthUserModel.java │ │ │ ├── AuthenticationFilter.java │ │ │ ├── AuthenticationModel.java │ │ │ └── JwtAuthManager.java │ │ │ └── util │ │ │ └── TokenClaim.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── umesh │ └── client │ └── ClientServiceApplicationTests.java ├── EurekaDiscoveryServer ├── .gitignore ├── Dockerfile ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ └── main │ ├── java │ └── com │ │ └── umesh │ │ └── eureka │ │ └── discovery │ │ └── EurekaDiscoveryServerApplication.java │ └── resources │ └── application.properties ├── JWT-Auth-service ├── .gitignore ├── Dockerfile ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── umesh │ │ │ └── auth │ │ │ ├── JwtAuthServiceApplication.java │ │ │ ├── config │ │ │ └── PropertySource.java │ │ │ ├── controller │ │ │ ├── AuthController.java │ │ │ └── ControllerHandler.java │ │ │ ├── exception │ │ │ └── AuthException.java │ │ │ ├── model │ │ │ └── AuthTokenModel.java │ │ │ ├── repo │ │ │ └── DataStore.java │ │ │ ├── service │ │ │ ├── AuthService.java │ │ │ └── AuthServiceImpl.java │ │ │ └── utils │ │ │ ├── JWTHelper.java │ │ │ └── TokenClaim.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── umesh │ └── auth │ └── JwtAuthServiceApplicationTests.java ├── README.md ├── client-service-call-via-apigateway.JPG └── eureka-server.JPG /.gitignore: -------------------------------------------------------------------------------- 1 | .metadata 2 | .recommenders 3 | .sonarlint 4 | RemoteSystemsTempFiles/ -------------------------------------------------------------------------------- /API-Gateway-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | bin/ 5 | !gradle/wrapper/gradle-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | out/ 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /API-Gateway-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | EXPOSE 8500 3 | ADD /build/libs/API-Gateway-service-0.0.1-SNAPSHOT.jar API-Gateway-service-0.0.1-SNAPSHOT.jar 4 | ENTRYPOINT ["java","-jar","API-Gateway-service-0.0.1-SNAPSHOT.jar"] -------------------------------------------------------------------------------- /API-Gateway-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.0.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.umesh.gateway' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url 'https://repo.spring.io/milestone' } 14 | } 15 | 16 | ext { 17 | set('springCloudVersion', "Hoxton.RC1") 18 | } 19 | 20 | dependencies { 21 | implementation 'org.springframework.cloud:spring-cloud-starter-gateway' 22 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' 23 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix' 24 | implementation 'org.springframework.cloud:spring-cloud-starter-feign:1.4.7.RELEASE' 25 | 26 | testImplementation('org.springframework.boot:spring-boot-starter-test') { 27 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 28 | } 29 | } 30 | 31 | dependencyManagement { 32 | imports { 33 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" 34 | } 35 | } 36 | 37 | test { 38 | useJUnitPlatform() 39 | } 40 | -------------------------------------------------------------------------------- /API-Gateway-service/docker-compose.yml: -------------------------------------------------------------------------------- 1 | eureka-service: 2 | image: eureka-server 3 | ports: 4 | - "8761:8761" 5 | auth-service: 6 | image: auth-server 7 | ports: 8 | - "8800:8800" 9 | links: 10 | - eureka-service 11 | environment: 12 | EUREKA_CLIENT_SERVICEURL_DEFALTZONE: http://eureka-server:8761/eureka 13 | gateway-service: 14 | image: gateway-server 15 | ports: 16 | - "8500:8500" 17 | links: 18 | - eureka-service 19 | environment: 20 | EUREKA_CLIENT_SERVICEURL_DEFALTZONE: http://eureka-server:8761/eureka 21 | client-service: 22 | image: cleint-server 23 | ports: 24 | - "8700:8700" 25 | links: 26 | - eureka-service 27 | environment: 28 | EUREKA_CLIENT_SERVICEURL_DEFALTZONE: http://eureka-server:8761/eureka -------------------------------------------------------------------------------- /API-Gateway-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/API-Gateway-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /API-Gateway-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /API-Gateway-service/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /API-Gateway-service/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /API-Gateway-service/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'API-Gateway-service' 2 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/ApiGatewayServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @EnableFeignClients 11 | public class ApiGatewayServiceApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ApiGatewayServiceApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/config/AuthFilter.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.cloud.gateway.filter.GatewayFilter; 7 | import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; 8 | import org.springframework.context.annotation.Lazy; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.server.reactive.ServerHttpRequest; 11 | import org.springframework.http.server.reactive.ServerHttpResponse; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.server.ServerWebExchange; 15 | 16 | import com.umesh.gateway.model.AuthTokenModel; 17 | import com.umesh.gateway.service.AuthService; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | @Component 22 | public class AuthFilter extends AbstractGatewayFilterFactory { 23 | 24 | @Autowired 25 | @Lazy 26 | private AuthService authService; 27 | 28 | private static Logger log = LoggerFactory.getLogger(AuthFilter.class); 29 | 30 | @SuppressWarnings("deprecation") 31 | @Override 32 | public GatewayFilter apply(final AuthFilterConfig config) { 33 | return (exchange, chain) -> { 34 | final ServerHttpRequest request = exchange.getRequest(); 35 | 36 | final boolean authorization = request.getHeaders().containsKey("Authorization"); 37 | log.debug("authorization " + authorization); 38 | 39 | if (!request.getHeaders().containsKey("apikey")) 40 | return this.onError(exchange, "No API KEY header", HttpStatus.UNAUTHORIZED); 41 | 42 | final String apiValue = request.getHeaders().get("apikey").get(0); 43 | if (StringUtils.isEmpty(apiValue)) 44 | return this.onError(exchange, "Invalid API KEY", HttpStatus.UNAUTHORIZED); 45 | 46 | final AuthTokenModel authTokenModel = getAuthorizationToken(apiValue); 47 | log.debug("Gateway Auth ApiKey {} JWT {}", apiValue, authTokenModel.getToken()); 48 | try { 49 | final ServerHttpRequest modifiedRequest = exchange.getRequest().mutate() 50 | .header("Authorization", authTokenModel.getType() + " " + authTokenModel.getToken()).build(); 51 | return chain.filter(exchange.mutate().request(modifiedRequest).build()); 52 | } catch (Exception e) { 53 | log.error(e.getMessage()); 54 | return this.onError(exchange, "Modified Request " + e.getMessage(), HttpStatus.UNAUTHORIZED); 55 | } 56 | }; 57 | } 58 | 59 | private Mono onError(final ServerWebExchange exchange, final String err, final HttpStatus httpStatus) { 60 | log.error("Gateway Auth Error {}", err); 61 | ServerHttpResponse response = exchange.getResponse(); 62 | response.setStatusCode(httpStatus); 63 | return response.setComplete(); 64 | } 65 | 66 | private AuthTokenModel getAuthorizationToken(final String apiValue) { 67 | log.debug("Gateway Auth ApiKey {}", apiValue); 68 | return authService.getJWTToken(apiValue); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/config/AuthFilterConfig.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.config; 2 | 3 | import org.springframework.cloud.gateway.support.Configurable; 4 | 5 | public class AuthFilterConfig implements Configurable { 6 | 7 | @Override 8 | public Class getConfigClass() { 9 | return String.class; 10 | } 11 | 12 | @Override 13 | public String newConfig() { 14 | return "Authorization"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/config/FeignConfig.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.config; 2 | 3 | import org.springframework.beans.factory.ObjectFactory; 4 | import org.springframework.boot.autoconfigure.http.HttpMessageConverters; 5 | import org.springframework.cloud.openfeign.EnableFeignClients; 6 | import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; 7 | import org.springframework.cloud.openfeign.support.SpringDecoder; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 11 | 12 | import com.fasterxml.jackson.databind.ObjectMapper; 13 | 14 | import feign.codec.Decoder; 15 | 16 | @Configuration 17 | @EnableFeignClients 18 | public class FeignConfig { 19 | 20 | @Bean 21 | public Decoder feignDecoder() { 22 | ObjectFactory objectFactory = () -> new HttpMessageConverters( 23 | new MappingJackson2HttpMessageConverter(customObjectMapper())); 24 | return new ResponseEntityDecoder(new SpringDecoder(objectFactory)); 25 | } 26 | 27 | @Bean 28 | public ObjectMapper customObjectMapper() { 29 | return new ObjectMapper(); 30 | } 31 | 32 | /*@Bean 33 | public RestTemplate restTemplate(RestTemplateBuilder builder) { 34 | return builder.build(); 35 | }*/ 36 | } 37 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/config/RouteConfig.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.config; 2 | 3 | import java.util.function.Function; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.cloud.gateway.route.Route.AsyncBuilder; 7 | import org.springframework.cloud.gateway.route.RouteLocator; 8 | import org.springframework.cloud.gateway.route.builder.PredicateSpec; 9 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | @Configuration 14 | public class RouteConfig { 15 | 16 | @Autowired 17 | private AuthFilter authFilter; 18 | 19 | @Bean 20 | public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) { 21 | return builder.routes().route(firstServiceRouting()).build(); 22 | } 23 | 24 | private final Function firstServiceRouting() { 25 | return r -> r.path("/api/v1/**") 26 | // 27 | .filters(f -> f 28 | // 29 | //.rewritePath("/api/v1/(?.*)", "/service/api/v1/${segment}") 30 | // 31 | .removeRequestHeader("Authorization") 32 | // 33 | .filter(authFilter.apply(new AuthFilterConfig()))) 34 | // 35 | .uri("lb://client-service/") 36 | // 37 | .id("client-service"); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/controller/HystrixController.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.cloud.context.config.annotation.RefreshScope; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import com.umesh.gateway.model.AuthTokenModel; 10 | import com.umesh.gateway.service.AuthService; 11 | 12 | @RefreshScope 13 | @RestController 14 | @RequestMapping("/fallback") 15 | public class HystrixController { 16 | 17 | @Autowired 18 | private AuthService authService; 19 | 20 | @GetMapping("/first") 21 | public String firstServiceFallback() { 22 | return "This is a fallback for first service."; 23 | } 24 | 25 | @GetMapping("/second") 26 | public String secondServiceFallback() { 27 | return "Second Server overloaded! Please try after some time."; 28 | } 29 | 30 | @GetMapping("/test") 31 | public AuthTokenModel testServiceFallback() { 32 | return authService.getJWTToken("1231"); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/model/AuthTokenModel.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.model; 2 | 3 | 4 | 5 | public class AuthTokenModel { 6 | 7 | private String type; 8 | 9 | 10 | private String token; 11 | 12 | 13 | public String getType() { 14 | return type; 15 | } 16 | 17 | 18 | public void setType(String type) { 19 | this.type = type; 20 | } 21 | 22 | 23 | public String getToken() { 24 | return token; 25 | } 26 | 27 | 28 | public void setToken(String token) { 29 | this.token = token; 30 | } 31 | 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /API-Gateway-service/src/main/java/com/umesh/gateway/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway.service; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestHeader; 6 | 7 | import com.umesh.gateway.config.FeignConfig; 8 | import com.umesh.gateway.model.AuthTokenModel; 9 | 10 | 11 | 12 | @FeignClient(name = "${auth.serviceid}", configuration = FeignConfig.class) 13 | public interface AuthService { 14 | 15 | @GetMapping(value = "/auth/generate") 16 | public AuthTokenModel getJWTToken(@RequestHeader("apikey") String apiKey); 17 | 18 | } -------------------------------------------------------------------------------- /API-Gateway-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=api-gateway-service 2 | server.port=8500 3 | 4 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka 5 | eureka.client.register-with-eureka=false 6 | eureka.client.fetchRegistry=true 7 | eureka.instance.preferIpAddress=true 8 | 9 | management.endpoints.web.exposure.include=hystrix.stream 10 | 11 | ######AUTH SERVER############# 12 | auth.serviceid=auth-service 13 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=30000 14 | ribbon.ReadTimeout=60000 15 | ribbon.connection-timeout=3000 16 | -------------------------------------------------------------------------------- /API-Gateway-service/src/test/java/com/umesh/gateway/ApiGatewayServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.umesh.gateway; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ApiGatewayServiceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ClientService/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | bin/ 5 | !gradle/wrapper/gradle-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | out/ 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /ClientService/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | EXPOSE 8700 3 | ADD /build/libs/ClientService-0.0.1-SNAPSHOT.jar ClientService-0.0.1-SNAPSHOT.jar 4 | ENTRYPOINT ["java","-jar","ClientService-0.0.1-SNAPSHOT.jar"] -------------------------------------------------------------------------------- /ClientService/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.umesh.client' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url 'https://repo.spring.io/milestone' } 14 | } 15 | 16 | ext { 17 | set('springCloudVersion', "Hoxton.RC2") 18 | } 19 | 20 | dependencies { 21 | implementation 'org.springframework.boot:spring-boot-starter-web' 22 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' 23 | implementation 'org.springframework.boot:spring-boot-starter-security' 24 | implementation 'io.jsonwebtoken:jjwt:0.9.1' 25 | testImplementation('org.springframework.boot:spring-boot-starter-test') { 26 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 27 | } 28 | } 29 | 30 | dependencyManagement { 31 | imports { 32 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" 33 | } 34 | } 35 | 36 | test { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /ClientService/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/ClientService/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ClientService/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ClientService/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /ClientService/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ClientService/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'ClientService' 2 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/ClientServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class ClientServiceApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ClientServiceApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/config/PropertySource.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | 7 | 8 | @Configuration 9 | public class PropertySource { 10 | 11 | 12 | 13 | 14 | 15 | @Value("${app.auth.jwt.secret}") 16 | private String appAuthJwtSecret; 17 | 18 | @Value("${app.auth.role.allowed}") 19 | private String appAuthRoleAllowed; 20 | 21 | 22 | public String getAppAuthSecret() { 23 | return appAuthJwtSecret; 24 | } 25 | 26 | public void setAppAuthSecret(String appAuthSecret) { 27 | this.appAuthJwtSecret = appAuthSecret; 28 | } 29 | 30 | public String getAppAuthRoleAllowed() { 31 | return appAuthRoleAllowed; 32 | } 33 | 34 | public void setAppAuthRoleAllowed(String appAuthRoleAllowed) { 35 | this.appAuthRoleAllowed = appAuthRoleAllowed; 36 | } 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 9 | import org.springframework.security.config.http.SessionCreationPolicy; 10 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 11 | 12 | import com.umesh.client.security.AuthAccessDeniedHandler; 13 | import com.umesh.client.security.AuthProvider; 14 | import com.umesh.client.security.AuthenticationFilter; 15 | 16 | @Configuration 17 | @EnableWebSecurity 18 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 19 | 20 | 21 | @Autowired 22 | private AuthProvider authProvider; 23 | 24 | @Autowired 25 | private AuthenticationFilter authenticationFilter; 26 | 27 | @Autowired 28 | private AuthAccessDeniedHandler accessDeniedHanlder; 29 | 30 | @Override 31 | public void configure(AuthenticationManagerBuilder auth) throws Exception { 32 | auth.authenticationProvider(authProvider); 33 | } 34 | 35 | @Override 36 | public void configure(HttpSecurity http) throws Exception { 37 | http.addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class); 38 | http.authenticationProvider(authProvider); 39 | http.authorizeRequests().anyRequest().authenticated(); 40 | http.exceptionHandling().accessDeniedHandler(accessDeniedHanlder); 41 | http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 42 | http.csrf().disable(); 43 | http.httpBasic().disable(); 44 | } 45 | 46 | 47 | } -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/controller/FirstController.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.controller; 2 | 3 | import org.springframework.http.ResponseEntity; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | 10 | 11 | @RestController 12 | @RequestMapping("first") 13 | public class FirstController { 14 | 15 | 16 | 17 | @GetMapping("test") 18 | public ResponseEntity readFirst(Authentication authentication) { 19 | 20 | return ResponseEntity.ok("{\"status\":\"access granted\"}"); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/exception/AuthException.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.exception; 2 | 3 | @SuppressWarnings("serial") 4 | public class AuthException extends RuntimeException { 5 | 6 | public AuthException() { 7 | super(); 8 | } 9 | 10 | public AuthException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public AuthException(String message) { 15 | super(message); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.security.access.AccessDeniedException; 11 | import org.springframework.security.web.access.AccessDeniedHandler; 12 | import org.springframework.stereotype.Component; 13 | 14 | @Component 15 | public class AuthAccessDeniedHandler implements AccessDeniedHandler{ 16 | 17 | @Override 18 | public void handle(HttpServletRequest request, HttpServletResponse response, 19 | AccessDeniedException accessDeniedException) throws IOException, ServletException { 20 | response.sendError(HttpStatus.UNAUTHORIZED.value(), accessDeniedException.getMessage()); 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthProvider.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.authentication.AuthenticationProvider; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.util.ObjectUtils; 12 | 13 | import com.umesh.client.config.PropertySource; 14 | import com.umesh.client.exception.AuthException; 15 | import com.umesh.client.util.TokenClaim; 16 | 17 | import io.jsonwebtoken.Claims; 18 | import io.jsonwebtoken.Jws; 19 | 20 | @Component 21 | public class AuthProvider implements AuthenticationProvider { 22 | 23 | @Autowired 24 | private JwtAuthManager jwtAuthManager; 25 | 26 | @Autowired 27 | private PropertySource propertySource; 28 | 29 | @Override 30 | public Authentication authenticate(final Authentication authentication) { 31 | final AuthenticationModel authenticationModel = (AuthenticationModel) authentication; 32 | try { 33 | doAuthorization(authenticationModel); 34 | SecurityContextHolder.getContext().setAuthentication(authenticationModel); 35 | } catch (Exception e) { 36 | final String msg = String.format("Authorization Failed %s", e.getMessage()); 37 | throw new AuthException(msg, e); 38 | } 39 | return authenticationModel; 40 | } 41 | 42 | @Override 43 | public boolean supports(Class authentication) { 44 | return AuthenticationModel.class.isAssignableFrom(authentication); 45 | } 46 | 47 | private final void doAuthorization(final AuthenticationModel appAuthUserModel) { 48 | final String cleansedToken = validateToken(appAuthUserModel.getCredentials()); 49 | final Jws claims = jwtAuthManager.validateToken(cleansedToken); 50 | 51 | appAuthUserModel.setAuthorities(getAuthorities(claims)); 52 | appAuthUserModel.setCredentials("TBS"); 53 | appAuthUserModel.setDetails(claims.getBody().get(TokenClaim.USER_ID.getKey(), String.class)); 54 | appAuthUserModel.setName(claims.getBody().get(TokenClaim.USER_INFO.getKey(), String.class)); 55 | appAuthUserModel.setPrincipal(getAuthUserModel(claims)); 56 | appAuthUserModel.setAuthenticated(true); 57 | } 58 | 59 | private final String validateToken(final String headerValue) { 60 | if (ObjectUtils.isEmpty(headerValue)) throw new AuthException("Authorization Header is empty"); 61 | 62 | final String token = headerValue.replace("Bearer", ""); 63 | if (ObjectUtils.isEmpty(token)) throw new AuthException("Token is Empty"); 64 | return token; 65 | } 66 | 67 | @SuppressWarnings("unchecked") 68 | private final List getAuthorities(Jws claims) { 69 | List authorities = claims.getBody().get(TokenClaim.AUTHORITIES.getKey(), List.class); 70 | if (ObjectUtils.isEmpty(authorities) || !authorities.contains(propertySource.getAppAuthRoleAllowed())) 71 | throw new AuthException("Invalid Role"); 72 | return authorities.stream().map(AuthRoleModel::new).collect(Collectors.toList()); 73 | } 74 | 75 | private final AuthUserModel getAuthUserModel(Jws claims) { 76 | final AuthUserModel authUserModel = new AuthUserModel(); 77 | authUserModel.setUserName(claims.getBody().get(TokenClaim.USER_INFO.getKey(), String.class)); 78 | return authUserModel; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthRoleModel.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | 5 | 6 | 7 | @SuppressWarnings("serial") 8 | 9 | public class AuthRoleModel implements GrantedAuthority { 10 | 11 | private String authority; 12 | 13 | @Override 14 | public String getAuthority() { 15 | // TODO Auto-generated method stub 16 | return authority; 17 | } 18 | 19 | public AuthRoleModel(String authority) { 20 | super(); 21 | this.authority = authority; 22 | } 23 | 24 | public void setAuthority(String authority) { 25 | this.authority = authority; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthUserModel.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | @SuppressWarnings("serial") 7 | public class AuthUserModel implements Serializable { 8 | 9 | public AuthUserModel() { 10 | super(); 11 | } 12 | 13 | private String userName; 14 | 15 | public String getUserName() { 16 | return userName; 17 | } 18 | 19 | public void setUserName(String userName) { 20 | this.userName = userName; 21 | } 22 | 23 | public AuthUserModel(String userName) { 24 | super(); 25 | this.userName = userName; 26 | } 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.security.core.context.SecurityContextHolder; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.web.filter.OncePerRequestFilter; 14 | 15 | import com.umesh.client.config.PropertySource; 16 | import com.umesh.client.exception.AuthException; 17 | 18 | 19 | 20 | @Component 21 | 22 | public class AuthenticationFilter extends OncePerRequestFilter { 23 | 24 | @Autowired 25 | private PropertySource propertySource; 26 | 27 | 28 | 29 | @Override 30 | public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 31 | throws ServletException, IOException { 32 | try { 33 | SecurityContextHolder.getContext().setAuthentication(getUser(request)); 34 | } catch (Exception e) { 35 | final String msg = String.format("Authorization Failed %s", e.getMessage()); 36 | //log.error(msg); 37 | throw new AuthException(msg, e); 38 | } 39 | filterChain.doFilter(request, response); 40 | } 41 | 42 | private final AuthenticationModel getUser(HttpServletRequest request) { 43 | final AuthenticationModel authenticationModel = new AuthenticationModel(); 44 | authenticationModel.setAuthenticated(false); 45 | authenticationModel.setCredentials(request.getHeader("Authorization")); 46 | return authenticationModel; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/AuthenticationModel.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.GrantedAuthority; 8 | 9 | 10 | @SuppressWarnings("serial") 11 | public class AuthenticationModel implements Authentication { 12 | 13 | private String name; 14 | 15 | private List authorities; 16 | 17 | private String credentials; 18 | 19 | private String details; 20 | 21 | private AuthUserModel principal; 22 | 23 | private boolean authenticated; 24 | 25 | @Override 26 | public String getName() { 27 | 28 | return name; 29 | } 30 | 31 | @Override 32 | public Collection getAuthorities() { 33 | 34 | return authorities; 35 | } 36 | 37 | @Override 38 | public String getCredentials() { 39 | 40 | return credentials; 41 | } 42 | 43 | @Override 44 | public String getDetails() { 45 | 46 | return details; 47 | } 48 | 49 | @Override 50 | public AuthUserModel getPrincipal() { 51 | 52 | return principal; 53 | } 54 | 55 | @Override 56 | public boolean isAuthenticated() { 57 | 58 | return this.authenticated; 59 | } 60 | 61 | @Override 62 | public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { 63 | 64 | this.authenticated = isAuthenticated; 65 | } 66 | 67 | public void setName(String name) { 68 | this.name = name; 69 | } 70 | 71 | public void setAuthorities(List authorities) { 72 | this.authorities = authorities; 73 | } 74 | 75 | public void setCredentials(String credentials) { 76 | this.credentials = credentials; 77 | } 78 | 79 | public void setDetails(String details) { 80 | this.details = details; 81 | } 82 | 83 | public void setPrincipal(AuthUserModel principal) { 84 | this.principal = principal; 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/security/JwtAuthManager.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.security; 2 | 3 | import javax.xml.bind.DatatypeConverter; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.umesh.client.config.PropertySource; 9 | 10 | import io.jsonwebtoken.Claims; 11 | import io.jsonwebtoken.Jws; 12 | import io.jsonwebtoken.Jwts; 13 | 14 | @Component 15 | public class JwtAuthManager { 16 | 17 | @Autowired 18 | private PropertySource propertySource; 19 | 20 | public Jws validateToken(final String token) { 21 | // TODO: PERFORMANCE 22 | final byte[] encodedSecretBytes = DatatypeConverter.parseBase64Binary(propertySource.getAppAuthSecret()); 23 | return Jwts.parser().setSigningKey(encodedSecretBytes).parseClaimsJws(token); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ClientService/src/main/java/com/umesh/client/util/TokenClaim.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client.util; 2 | 3 | public enum TokenClaim { 4 | 5 | USER_ID("userId"), USER_INFO("UserInfo"), AUTHORITIES("authorities"); 6 | 7 | private String key; 8 | 9 | private TokenClaim(final String key) { 10 | this.key = key; 11 | } 12 | 13 | public String getKey() { 14 | return key; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ClientService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=client-service 2 | server.port=8700 3 | server.servlet.context-path=/api/v1 4 | 5 | eureka.client.service-url.defaultZone=http://localhost:8761/eureka 6 | eureka.instance.preferIpAddress=true 7 | 8 | app.auth.jwt.secret=test 9 | app.auth.role.allowed=ROLE_USER 10 | -------------------------------------------------------------------------------- /ClientService/src/test/java/com/umesh/client/ClientServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.umesh.client; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ClientServiceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | bin/ 5 | !gradle/wrapper/gradle-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | out/ 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | EXPOSE 8761 3 | ADD /build/libs/EurekaDiscoveryServer-0.0.1-SNAPSHOT.jar EurekaDiscoveryServer-0.0.1-SNAPSHOT.jar 4 | ENTRYPOINT ["java","-jar","EurekaDiscoveryServer-0.0.1-SNAPSHOT.jar"] -------------------------------------------------------------------------------- /EurekaDiscoveryServer/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.0.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.umesh' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url 'https://repo.spring.io/milestone' } 14 | } 15 | 16 | ext { 17 | set('springCloudVersion', "Hoxton.RC1") 18 | } 19 | 20 | dependencies { 21 | //implementation 'org.springframework.boot:spring-boot-starter-web' 22 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' 23 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 24 | 25 | 26 | } 27 | 28 | dependencyManagement { 29 | imports { 30 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/EurekaDiscoveryServer/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /EurekaDiscoveryServer/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EurekaDiscoveryServer' 2 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/src/main/java/com/umesh/eureka/discovery/EurekaDiscoveryServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.umesh.eureka.discovery; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | @EnableEurekaServer 7 | @SpringBootApplication 8 | public class EurekaDiscoveryServerApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(EurekaDiscoveryServerApplication.class, args); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /EurekaDiscoveryServer/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=eureka-service-discovery 2 | server.port=8761 3 | eureka.client.register-with-eureka=false 4 | eureka.client.fetch-registry=false 5 | -------------------------------------------------------------------------------- /JWT-Auth-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | bin/ 5 | !gradle/wrapper/gradle-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | out/ 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /JWT-Auth-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | EXPOSE 8761 3 | ADD /build/libs/JWT-Auth-service-0.0.1-SNAPSHOT.jar JWT-Auth-service-0.0.1-SNAPSHOT.jar 4 | ENTRYPOINT ["java","-jar","JWT-Auth-service-0.0.1-SNAPSHOT.jar"] -------------------------------------------------------------------------------- /JWT-Auth-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.0.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.umesh.auth' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url 'https://repo.spring.io/milestone' } 14 | } 15 | 16 | ext { 17 | set('springCloudVersion', "Hoxton.RC1") 18 | } 19 | 20 | dependencies { 21 | implementation 'org.springframework.boot:spring-boot-starter-web' 22 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' 23 | implementation 'io.jsonwebtoken:jjwt:0.9.1' 24 | 25 | testImplementation('org.springframework.boot:spring-boot-starter-test') { 26 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 27 | } 28 | } 29 | 30 | dependencyManagement { 31 | imports { 32 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" 33 | } 34 | } 35 | 36 | test { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /JWT-Auth-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/JWT-Auth-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /JWT-Auth-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /JWT-Auth-service/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /JWT-Auth-service/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /JWT-Auth-service/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'JWT-Auth-service' 2 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/JwtAuthServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class JwtAuthServiceApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(JwtAuthServiceApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/config/PropertySource.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | 7 | 8 | @Configuration 9 | public class PropertySource { 10 | 11 | @Value("${spring.application.name}") 12 | private String appName; 13 | 14 | @Value("${app.auth.apikey.key}") 15 | private String appAuthApiKey; 16 | 17 | @Value("${app.auth.token.type}") 18 | private String appAuthTokenType; 19 | 20 | @Value("${app.auth.secret}") 21 | private String appAuthSecret; 22 | 23 | @Value("${app.auth.ttl}") 24 | private long appTimeToLive; 25 | 26 | @Value("${app.auth.header.key}") 27 | private String appAuthHeaderKey; 28 | 29 | public String getAppName() { 30 | return appName; 31 | } 32 | 33 | public void setAppName(String appName) { 34 | this.appName = appName; 35 | } 36 | 37 | public String getAppAuthApiKey() { 38 | return appAuthApiKey; 39 | } 40 | 41 | public void setAppAuthApiKey(String appAuthApiKey) { 42 | this.appAuthApiKey = appAuthApiKey; 43 | } 44 | 45 | 46 | 47 | public String getAppAuthTokenType() { 48 | return appAuthTokenType; 49 | } 50 | 51 | public void setAppAuthTokenType(String appAuthTokenType) { 52 | this.appAuthTokenType = appAuthTokenType; 53 | } 54 | 55 | public String getAppAuthSecret() { 56 | return appAuthSecret; 57 | } 58 | 59 | public void setAppAuthSecret(String appAuthSecret) { 60 | this.appAuthSecret = appAuthSecret; 61 | } 62 | 63 | public long getAppTimeToLive() { 64 | return appTimeToLive; 65 | } 66 | 67 | public void setAppTimeToLive(long appTimeToLive) { 68 | this.appTimeToLive = appTimeToLive; 69 | } 70 | 71 | public String getAppAuthHeaderKey() { 72 | return appAuthHeaderKey; 73 | } 74 | 75 | public void setAppAuthHeaderKey(String appAuthHeaderKey) { 76 | this.appAuthHeaderKey = appAuthHeaderKey; 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/controller/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestHeader; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import com.umesh.auth.model.AuthTokenModel; 10 | import com.umesh.auth.service.AuthService; 11 | 12 | 13 | 14 | @RestController 15 | public class AuthController { 16 | 17 | @Autowired 18 | private AuthService authService; 19 | 20 | @GetMapping(value = "generate", produces = "application/json") 21 | public ResponseEntity getJWTToken(@RequestHeader("apikey") String apiKey) { 22 | return ResponseEntity.ok(authService.validateApiKeyAndGetJwtToken(apiKey)); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/controller/ControllerHandler.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.controller; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.http.HttpServletResponse; 6 | 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.web.bind.annotation.ControllerAdvice; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 11 | 12 | import com.umesh.auth.exception.AuthException; 13 | 14 | 15 | 16 | @ControllerAdvice 17 | public class ControllerHandler extends ResponseEntityExceptionHandler{ 18 | 19 | @ExceptionHandler(AuthException.class) 20 | public void handleAuthException(HttpServletResponse response) throws IOException { 21 | response.sendError(HttpStatus.UNAUTHORIZED.value()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/exception/AuthException.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.exception; 2 | 3 | @SuppressWarnings("serial") 4 | public class AuthException extends RuntimeException { 5 | 6 | public AuthException() { 7 | super(); 8 | } 9 | 10 | public AuthException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public AuthException(String message) { 15 | super(message); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/model/AuthTokenModel.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.model; 2 | 3 | 4 | 5 | public class AuthTokenModel { 6 | 7 | private String type; 8 | 9 | 10 | private String token; 11 | 12 | public String getType() { 13 | return type; 14 | } 15 | 16 | public void setType(String type) { 17 | this.type = type; 18 | } 19 | 20 | 21 | 22 | public String getToken() { 23 | return token; 24 | } 25 | 26 | public void setToken(String token) { 27 | this.token = token; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/repo/DataStore.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.repo; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class DataStore { 10 | 11 | private static final Map USERAPIENTITY = new HashMap<>(); 12 | 13 | private static final Map USERINFOENTITY = new HashMap<>(); 14 | 15 | private static final Map USERROLEENTITY = new HashMap<>(); 16 | 17 | static { 18 | USERAPIENTITY.put("1231", "u1"); 19 | USERAPIENTITY.put("7891", "u2"); 20 | USERAPIENTITY.put("8901", "u3"); 21 | 22 | USERINFOENTITY.put("u1", "name1"); 23 | USERINFOENTITY.put("u2", "name2"); 24 | USERINFOENTITY.put("u3", "name3"); 25 | 26 | USERROLEENTITY.put("u1", "ROLE_USER"); 27 | USERROLEENTITY.put("u2", "ROLE_ADMIN"); 28 | USERROLEENTITY.put("u3", "ROLE_MANAGER"); 29 | 30 | } 31 | 32 | public String getUserIdForApikey(final String apiKey) { 33 | return USERAPIENTITY.get(apiKey); 34 | } 35 | 36 | public String getUserInfo(final String userId) { 37 | return USERINFOENTITY.get(userId); 38 | } 39 | 40 | public String getUserRole(final String userId) { 41 | return USERROLEENTITY.get(userId); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.service; 2 | 3 | import com.umesh.auth.model.AuthTokenModel; 4 | 5 | public interface AuthService { 6 | 7 | public AuthTokenModel validateApiKeyAndGetJwtToken(String apiKey); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/service/AuthServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Optional; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | import com.umesh.auth.config.PropertySource; 13 | import com.umesh.auth.exception.AuthException; 14 | import com.umesh.auth.model.AuthTokenModel; 15 | import com.umesh.auth.repo.DataStore; 16 | import com.umesh.auth.utils.JWTHelper; 17 | import com.umesh.auth.utils.TokenClaim; 18 | 19 | 20 | 21 | @Service 22 | public class AuthServiceImpl implements AuthService { 23 | 24 | @Autowired 25 | private DataStore dataStore; 26 | 27 | @Autowired 28 | private PropertySource propertySource; 29 | 30 | @Override 31 | public AuthTokenModel validateApiKeyAndGetJwtToken(final String apiKey) { 32 | try { 33 | final String userId = validateApiKeyAndGetUserId(apiKey); 34 | final Map claims = getUserInfo(userId); 35 | final String jwtTokenValue = JWTHelper.createJWT(claims, propertySource.getAppName(), 36 | propertySource.getAppAuthSecret(), propertySource.getAppTimeToLive()); 37 | return getTokenModel(jwtTokenValue); 38 | } catch (Exception e) { 39 | throw new AuthException("Unauthorized API key : " + apiKey, e); 40 | } 41 | } 42 | 43 | private final String validateApiKeyAndGetUserId(final String apiKey) { 44 | return Optional.ofNullable(dataStore.getUserIdForApikey(apiKey)) 45 | .orElseThrow(() -> new AuthException("InValid API Key")); 46 | } 47 | 48 | private final Map getUserInfo(final String userId) { 49 | final Map claims = new HashMap<>(); 50 | final String userInfo = dataStore.getUserInfo(userId); 51 | final String userRole = dataStore.getUserRole(userId); 52 | final List authorities = new ArrayList<>(); 53 | authorities.add(userRole); 54 | claims.put(TokenClaim.USER_ID.getKey(), userId); 55 | claims.put(TokenClaim.USER_INFO.getKey(), userInfo); 56 | claims.put(TokenClaim.AUTHORITIES.getKey(), authorities); 57 | return claims; 58 | } 59 | 60 | private final AuthTokenModel getTokenModel(final String jwtTokenValue) { 61 | final AuthTokenModel tokenModel = new AuthTokenModel(); 62 | tokenModel.setType(propertySource.getAppAuthTokenType()); 63 | tokenModel.setToken(jwtTokenValue); 64 | return tokenModel; 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/utils/JWTHelper.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.utils; 2 | 3 | import java.security.Key; 4 | import java.util.Date; 5 | import java.util.Map; 6 | 7 | import javax.crypto.spec.SecretKeySpec; 8 | import javax.xml.bind.DatatypeConverter; 9 | 10 | import io.jsonwebtoken.JwtBuilder; 11 | import io.jsonwebtoken.Jwts; 12 | import io.jsonwebtoken.SignatureAlgorithm; 13 | 14 | public class JWTHelper { 15 | 16 | private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256; 17 | 18 | private JWTHelper() { 19 | } 20 | 21 | public static String createJWT(Map claims, String issuer, String secretKey, long ttl) { 22 | 23 | final JwtBuilder builder = Jwts.builder(); 24 | 25 | final String id = (String) claims.get("userId"); 26 | final String subject = (String) claims.get("userInfo"); 27 | final long nowMillis = System.currentTimeMillis(); 28 | final Date now = new Date(nowMillis); 29 | // TODO: PERFORMANCE 30 | final byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey); 31 | final Key signingKey = new SecretKeySpec(apiKeySecretBytes, SIGNATURE_ALGORITHM.getJcaName()); 32 | 33 | builder.setId(id).setIssuedAt(now).setIssuer(issuer).setSubject(subject).addClaims(claims) 34 | .signWith(SIGNATURE_ALGORITHM, signingKey); 35 | // TODO: ELSE SCENARIO 36 | if (ttl >= 0) { 37 | long expMillis = nowMillis + ( ttl * 60 * 1000); 38 | Date exp = new Date(expMillis); 39 | builder.setExpiration(exp); 40 | } 41 | 42 | return builder.compact(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/java/com/umesh/auth/utils/TokenClaim.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth.utils; 2 | 3 | public enum TokenClaim { 4 | 5 | USER_ID("userId"), USER_INFO("UserInfo"), AUTHORITIES("authorities"); 6 | 7 | private String key; 8 | 9 | private TokenClaim(final String key) { 10 | this.key = key; 11 | } 12 | 13 | public String getKey() { 14 | return key; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=auth-service 2 | server.port=8800 3 | server.servlet.context-path=/auth 4 | 5 | eureka.client.service-url.defaultZone=http://localhost:8761/eureka 6 | eureka.instance.preferIpAddress=true 7 | 8 | app.auth.apikey.key=apikey 9 | app.auth.token.type=Bearer 10 | app.auth.secret=test 11 | #Time To Live in minutes 12 | app.auth.ttl=1800 13 | app.auth.header.key=Authorization 14 | -------------------------------------------------------------------------------- /JWT-Auth-service/src/test/java/com/umesh/auth/JwtAuthServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.umesh.auth; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class JwtAuthServiceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroServiceWithSpringCloudGateway 2 | This is a sample application to create and demonstrate the micro-service architecture with spring cloud gateway, eureka server, 3 | eureka client, ribbon and feign. 4 | 5 | Eureka server 6 | ![Alt text](eureka-server.JPG "Eureka Server") 7 | 8 | Call client service Rest API via API gateway using Postman 9 | ![Alt text](client-service-call-via-apigateway.JPG ) 10 | -------------------------------------------------------------------------------- /client-service-call-via-apigateway.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/client-service-call-via-apigateway.JPG -------------------------------------------------------------------------------- /eureka-server.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umesh-kushwaha/jwt-authentication-with-spring-cloud-gateway-sample/98caacc31c47d018bef8ca5c3bdcf6792a8b8800/eureka-server.JPG --------------------------------------------------------------------------------