| 
  
   Size: 8107 
  
  Comment:  
 | 
  
   Size: 17849 
  
  Comment:  
 | 
| Deletions are marked like this. | Additions are marked like this. | 
| Line 227: | Line 227: | 
| }}} | mkdir -p ~/Documents/test-springboot-keycloak/proj cd ~/Documents/test-springboot-keycloak/proj touch pom.xml touch src/main/java/com/example/demo/UserRole.java touch src/main/java/com/example/demo/RolesAspect.java touch src/main/java/com/example/demo/SecurityConfiguration.java touch src/main/java/com/example/demo/AdminRole.java touch src/main/java/com/example/demo/DemoApplication.java touch src/main/resources/application.properties }}} === pom.xml === {{{#!highlight xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> }}} === src/main/java/com/example/demo/UserRole.java === {{{#!highlight java package com.example.demo; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; /** * Annotation to identify code associated with USER role * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface UserRole { } }}} === src/main/java/com/example/demo/RolesAspect.java === {{{#!highlight java package com.example.demo; import java.util.List; import java.util.ArrayList; import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.jwt.Jwt; @Aspect @Component public class RolesAspect { private boolean hasRole(String role, ProceedingJoinPoint joinPoint) { if (joinPoint.getArgs() != null && joinPoint.getArgs().length >= 1) { Object authArg = joinPoint.getArgs()[0]; if (Authentication.class.isAssignableFrom(authArg.getClass())) { Jwt jwt = (Jwt) ((Authentication) authArg).getCredentials(); Map<String, Object> realmAccess = jwt.getClaimAsMap("realm_access"); List<String> roles = (ArrayList<String>) realmAccess.get("roles"); if (roles.contains(role)) { return true; } } } return false; } /** * Intercept stuff annotated with UserRole annotation * * @param joinPoint * @return * @throws Throwable */ @Around("@annotation(UserRole)") public Object interceptUserRoleAnnotation(ProceedingJoinPoint joinPoint) throws Throwable { if (hasRole("USER", joinPoint)) { return joinPoint.proceed(); } else { System.out.println("USER role not found"); return null; } } /** * Intercept stuff annotated with AdminRole annotation * * @param joinPoint * @return * @throws Throwable */ @Around("@annotation(AdminRole)") public Object interceptAdminRoleAnnotation(ProceedingJoinPoint joinPoint) throws Throwable { if (hasRole("ADMIN", joinPoint)) { return joinPoint.proceed(); } else { System.out.println("ADMIN role not found"); return null; } } } }}} === src/main/java/com/example/demo/SecurityConfiguration.java === {{{#!highlight java package com.example.demo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfiguration { @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.oauth2ResourceServer( (oauth2ResourceServer) -> { oauth2ResourceServer.jwt((jwt) -> { jwt.decoder(null); }); }).build(); } @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring().requestMatchers("/otherhello**").requestMatchers("/static**"); } } }}} === src/main/java/com/example/demo/AdminRole.java === {{{#!highlight java package com.example.demo; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; /** * Annotation to identify code associated with ADMIN role * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AdminRole { } }}} === src/main/java/com/example/demo/DemoApplication.java === {{{#!highlight java package com.example.demo; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; @RestController @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @GetMapping("/otherhello") public String otherHello() { return "other hello"; } @GetMapping("/hello") @UserRole public String hello(Authentication authentication) { String authorities = ""; for (int authorityIndex = 0; authorityIndex < authentication.getAuthorities().size(); authorityIndex++) { GrantedAuthority ga = (GrantedAuthority) authentication.getAuthorities().toArray()[authorityIndex]; authorities += ga.getAuthority() + " "; } Jwt jwt = (Jwt) authentication.getCredentials(); Object[] keys = jwt.getClaims().keySet().toArray(); String allkeys = ""; String preferredUsername = jwt.getClaim("preferred_username").toString(); Map<String, Object> realmAccess = jwt.getClaimAsMap("realm_access"); List<String> roles = (ArrayList<String>) realmAccess.get("roles"); System.out.println("Contains USER " + roles.contains("USER")); for (int j = 0; j < keys.length; j++) { allkeys = allkeys + " " + (String) keys[j] + ":" + jwt.getClaims().get(keys[j]).toString() + " "; } return "I am authenticated with user " + authentication.getName() + " Authorities: " + authorities + " Details: " + authentication.getDetails().toString() + " allKeys: " + allkeys + " ... " + preferredUsername + " ... " + roles; } @GetMapping("/helloAdmin") @AdminRole public String helloAdmin(Authentication authentication) { return "Hello ADMIN"; } @GetMapping("/helloUser/{text}") @UserRole public String helloUser(Authentication authentication, @PathVariable String text) { return "Hello USER " + text; } } }}} === src/main/resources/application.properties === {{{#!highlight sh server.port=8081 spring.security.oauth2.resourceserver.jwt.issuer-uri=http://debian:8080/realms/MyRealm #logging.level.root=DEBUG logging.level.root=INFO logging.file=/tmp/testout.log }}}  | 
keycloak
Open Source Identity and Access Management.
OIDC
OpenID Connect (OIDC) provides a simple identity layer on top of the OAuth 2.0 protocol, enabling Single Sign-On (SSO) and API access in one round trip. It brings the missing user authentication story and identity layer to OAuth.
Steps setup realm
Create admin user
- Administration Console
 - User: admin
 - Password: admin
 - Password confirmation: admin
 - Click on Create
 
Create realm
http://localhost:8080/auth/admin/master/console/#/realms/master
- login with admin:admin
 http://localhost:8080/auth/admin/master/console/#/create/realm
Name: MyRealm
- Enabled: On
 - Click on Create
 
Add user myuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm
- Go to Users
 - Click on Add user
 - Username: myuser
 - User enabled: ON
 - Save
 
Add user mysubtaskuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm
- Go to Users
 - Click on Add user
 - Username: mysubtaskuser
 - User enabled: ON
 - Save
 
Set user password myuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm/users
- Select user myuser
 - Select credentials tab
 - Password: mypwd
 - Password confirmation: mypwd
 - Temporary: off
 - Click on "Set Password"
 
Set user password mysubtaskuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm/users
- Select user mysubtaskuser
 - Select credentials tab
 - Password: mypwd2
 - Password confirmation: mypwd2
 - Temporary: off
 - Click on "Set Password"
 
Create role USER
http://localhost:8080/auth/admin/master/console/#/create/role/MyRealm
Add role USER to MyRealm
- Role name: USER
 - Click on Save
 
Create role USERSUBTASK
http://localhost:8080/auth/admin/master/console/#/create/role/MyRealm
Add role USERSUBTASK to MyRealm
- Role name: USERSUBTASK
 - Click on Save
 
Associate role to user myuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm/users
- select user myuser
 - select tab Role mappings
 - select USER role and click on add selected
 
Associate role to user mysubtaskuser
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm/users
- select user mysubtaskuser
 - select tab Role mappings
 - select USERSUBTASK role and click on add selected
 
Create keycloak client
http://localhost:8080/auth/admin/master/console/#/realms/MyRealm/clients
- click on create
 - client id: curl_confidential
 - client protocol: openid-connect
 root url: http://localhost:8080
- Click on save
 - Clients Curl_confidential settings:
 - access-type: confidential
 - Should appear tab Credentials
 - Client authenticator: Client ID and secret
 - Click on "Regenerate Secret"
 - # 3a862f1b-6687-4f7a-8e04-be494fca99e0
 - Clients Curl_confidential Mappers Add builtin "realm roles", "groups"
 - add selected
 - For each map add "Add to userinfo"
 - Clients Curl_confidential Scope,
 - select full scope allowed: ON
 
client data
realm: MyRealm
- user pwd: myuser mypwd
 - client id: curl_confidential
 - protocol: openid-connect
 - Curl_confidential settings:
 - access-type confidential
 valid redirect url http://localhost:8080
- tab credentials: regenerate secret 3a862f1b-6687-4f7a-8e04-be494fca99e0
 
Signout
cUrl calls to test keycloak
   1 ACCESS_TOKEN=$(curl -d 'client_id=curl_confidential' -d 'client_secret=3a862f1b-6687-4f7a-8e04-be494fca99e0' -d 'username=myuser' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/token' | json_reformat | jq -r '.access_token')
   2 echo $ACCESS_TOKEN
   3 
   4 curl -X POST -d "access_token=$ACCESS_TOKEN" http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/userinfo | json_reformat
   5 
   6 curl -X GET -d "access_token=$ACCESS_TOKEN" http://localhost:8080/auth/realms/MyRealm/.well-known/openid-configuration | json_reformat 
   1 CLIENT_ID="curl_confidential"
   2 CLIENT_SECRET="3a862f1b-6687-4f7a-8e04-be494fca99e0"
   3 TOKEN=$(curl -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" -d 'username=myuser' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/token' | json_reformat)
   4 
   5 ACCESS_TOKEN=$(echo $TOKEN | jq -r '.access_token')
   6 REFRESH_TOKEN=$(echo $TOKEN | jq -r '.refresh_token')
   7 
   8 curl -X POST -d "access_token=$ACCESS_TOKEN" http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/userinfo
   9 
  10 curl -vvv -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" -d "refresh_token=$REFRESH_TOKEN" -H "Bearer: $ACCESS_TOKEN" 'http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/logout'
  11 
  12 curl -X POST -d "access_token=$ACCESS_TOKEN" http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/userinfo
  13 #
  14 
Setup keycloak as service in Raspberry pi
- /etc/init.d/keycloak
 
   1 #! /bin/sh
   2 ### BEGIN INIT INFO
   3 # Provides:          keycloak
   4 # Default-Start:     2 3 4 5
   5 # Default-Stop:
   6 # Short-Description: keycloak
   7 # Description:       keycloak
   8 ### END INIT INFO
   9 #
  10 # Some things that run always
  11 touch /var/lock/keycloak
  12 # Carry out specific functions when asked to by the system
  13 case "$1" in
  14   start)
  15     echo "Starting script keycloak "
  16     su pi -c "nohup /home/pi/keycloak-14.0.0/bin/standalone.sh &"
  17     ;;
  18   stop)
  19     echo "Stopping script keycloak"
  20     kill $(ps uax | grep keycloak | grep java | awk '//{print $2}')
  21     ;;
  22   status)
  23     echo "keycloak PID: $(ps uax | grep keycloak | grep java | awk '//{print $2}')"
  24     ;;
  25   *)
  26     echo "Usage: /etc/init.d/keycloak {start|stop|status}"
  27     exit 1
  28     ;;
  29 esac
  30 
  31 exit 0
Keycloak 21.1.1
   1 cd ~
   2 wget https://github.com/keycloak/keycloak/releases/download/21.1.1/keycloak-21.1.1.zip
   3 unzip keycloak-21.1.1.zip
   4 cd keycloak-21.1.1/bin
   5 bash kc.sh start 
   6 bash kc.sh show-config
   7 keytool -genkeypair -alias debian -keyalg RSA -keysize 2048 -validity 365 -keystore server.keystore -dname "cn=Server Administrator,o=Keycloak,c=PT" -keypass secret -storepass secret
   8 cp server.keystore ../conf
   9 ./kc.sh start-dev --hostname=debian --https-key-store-password=secret
  10 #Sign in to your account 
  11 #Master, Create realm, MyRealm , Create 
  12 #Users, Create new user, myuser, create 
  13 #select user, credentials, set password,  mypwd mypwd, temporary off , save, save password
  14 #Realm roles, create role, USER, save 
  15 #Users, myuser, role mapping, assign role USER 
  16 #signout
  17 #http://debian:8080/admin/master/console/#/MyRealm
  18 #My realm, clients, create client 
  19 #  client type: openid connect 
  20 #  client id:  curl_confidential
  21 #  next 
  22 #  client authentication: on 
  23 #  standard flow, direct access grants 
  24 #  next 
  25 #  valid redirect url http://localhost:8080
  26 #  save 
  27 #  tab credentials of curl_confidential 
  28 #  client secret regenerate -> Cymorm3jWN2b5z49dNASwPWwgY5zAsdV
  29   
  30 curl -d 'client_id=curl_confidential' -d 'client_secret=Cymorm3jWN2b5z49dNASwPWwgY5zAsdV' -d 'usr' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/realms/MyRealm/protocol/openid-connect/token'
  31 sudo apt install jq 
  32 
  33 TOKEN=$(curl -d 'client_id=curl_confidential' -d 'client_secret=Cymorm3jWN2b5z49dNASwPWwgY5zAsdV' -d 'username=myuser' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/realms/MyRealm/protocol/openid-connect/token')
  34 echo $TOKEN 
  35 
  36 mkdir -p ~/Documents/test-springboot-keycloak/proj
  37 cd ~/Documents/test-springboot-keycloak/proj
  38 touch pom.xml
  39 touch src/main/java/com/example/demo/UserRole.java
  40 touch src/main/java/com/example/demo/RolesAspect.java
  41 touch src/main/java/com/example/demo/SecurityConfiguration.java
  42 touch src/main/java/com/example/demo/AdminRole.java
  43 touch src/main/java/com/example/demo/DemoApplication.java
  44 touch src/main/resources/application.properties
pom.xml
   1 <?xml version="1.0" encoding="UTF-8"?>
   2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   4         <modelVersion>4.0.0</modelVersion>
   5         <parent>
   6                 <groupId>org.springframework.boot</groupId>
   7                 <artifactId>spring-boot-starter-parent</artifactId>
   8                 <version>3.1.0</version>
   9                 <relativePath/> <!-- lookup parent from repository -->
  10         </parent>
  11         <groupId>com.example</groupId>
  12         <artifactId>demo</artifactId>
  13         <version>0.0.1-SNAPSHOT</version>
  14         <name>demo</name>
  15         <description>Demo project for Spring Boot</description>
  16         <properties>
  17                 <java.version>17</java.version>
  18         </properties>
  19         <dependencies>
  20                 <dependency>
  21                         <groupId>org.springframework.boot</groupId>
  22                         <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
  23                 </dependency>
  24                 <dependency>
  25                         <groupId>org.springframework.boot</groupId>
  26                         <artifactId>spring-boot-starter-security</artifactId>
  27                 </dependency>
  28                 <dependency>
  29                         <groupId>org.springframework.boot</groupId>
  30                         <artifactId>spring-boot-starter-web</artifactId>
  31                 </dependency>
  32                 <dependency>
  33                         <groupId>org.springframework.boot</groupId>
  34                         <artifactId>spring-boot-starter-aop</artifactId>
  35                 </dependency>                
  36         </dependencies>
  37         <build>
  38                 <plugins>
  39                         <plugin>
  40                                 <groupId>org.springframework.boot</groupId>
  41                                 <artifactId>spring-boot-maven-plugin</artifactId>
  42                         </plugin>
  43                 </plugins>
  44         </build>
  45 </project>
src/main/java/com/example/demo/UserRole.java
   1 package com.example.demo;
   2 
   3 import java.lang.annotation.Retention;
   4 import java.lang.annotation.Target;
   5 import java.lang.annotation.ElementType;
   6 import java.lang.annotation.RetentionPolicy;
   7 
   8 /**
   9  * Annotation to identify code associated with USER role
  10  * 
  11  */
  12 @Retention(RetentionPolicy.RUNTIME)
  13 @Target(ElementType.METHOD)
  14 public @interface UserRole {
  15 }
src/main/java/com/example/demo/RolesAspect.java
   1 package com.example.demo;
   2 
   3 import java.util.List;
   4 import java.util.ArrayList;
   5 import java.util.Map;
   6 
   7 import org.aspectj.lang.ProceedingJoinPoint;
   8 import org.aspectj.lang.annotation.Around;
   9 import org.aspectj.lang.annotation.Aspect;
  10 import org.springframework.stereotype.Component;
  11 import org.springframework.security.core.Authentication;
  12 import org.springframework.security.oauth2.jwt.Jwt;
  13 
  14 @Aspect
  15 @Component
  16 public class RolesAspect {
  17 
  18     private boolean hasRole(String role, ProceedingJoinPoint joinPoint) {
  19         if (joinPoint.getArgs() != null && joinPoint.getArgs().length >= 1) {
  20             Object authArg = joinPoint.getArgs()[0];
  21             if (Authentication.class.isAssignableFrom(authArg.getClass())) {
  22                 Jwt jwt = (Jwt) ((Authentication) authArg).getCredentials();
  23                 Map<String, Object> realmAccess = jwt.getClaimAsMap("realm_access");
  24                 List<String> roles = (ArrayList<String>) realmAccess.get("roles");
  25                 if (roles.contains(role)) {
  26                     return true;
  27                 }
  28             }
  29         }
  30 
  31         return false;
  32     }
  33 
  34     /**
  35      * Intercept stuff annotated with UserRole annotation
  36      * 
  37      * @param joinPoint
  38      * @return
  39      * @throws Throwable
  40      */
  41     @Around("@annotation(UserRole)")
  42     public Object interceptUserRoleAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  43 
  44         if (hasRole("USER", joinPoint)) {
  45             return joinPoint.proceed();
  46         } else {
  47             System.out.println("USER role not found");
  48             return null;
  49         }
  50     }
  51 
  52     /**
  53      * Intercept stuff annotated with AdminRole annotation
  54      * 
  55      * @param joinPoint
  56      * @return
  57      * @throws Throwable
  58      */
  59     @Around("@annotation(AdminRole)")
  60     public Object interceptAdminRoleAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  61 
  62         if (hasRole("ADMIN", joinPoint)) {
  63             return joinPoint.proceed();
  64         } else {
  65             System.out.println("ADMIN role not found");
  66             return null;
  67         }
  68     }
  69 }
src/main/java/com/example/demo/SecurityConfiguration.java
   1 package com.example.demo;
   2 
   3 import org.springframework.context.annotation.Bean;
   4 import org.springframework.context.annotation.Configuration;
   5 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
   6 import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
   7 import org.springframework.security.web.SecurityFilterChain;
   8 
   9 @Configuration
  10 public class SecurityConfiguration {
  11 
  12         @Bean
  13         protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  14                 return http.oauth2ResourceServer(
  15                                 (oauth2ResourceServer) -> {
  16                                         oauth2ResourceServer.jwt((jwt) -> {
  17                                                 jwt.decoder(null);
  18                                         });
  19                                 }).build();
  20         }
  21 
  22         @Bean
  23         public WebSecurityCustomizer webSecurityCustomizer() {
  24                 return (web) -> web.ignoring().requestMatchers("/otherhello**").requestMatchers("/static**");
  25         }
  26 }
src/main/java/com/example/demo/AdminRole.java
   1 package com.example.demo;
   2 
   3 import java.lang.annotation.Retention;
   4 import java.lang.annotation.Target;
   5 import java.lang.annotation.ElementType;
   6 import java.lang.annotation.RetentionPolicy;
   7 
   8 /**
   9  * Annotation to identify code associated with ADMIN role
  10  * 
  11  */
  12 @Retention(RetentionPolicy.RUNTIME)
  13 @Target(ElementType.METHOD)
  14 public @interface AdminRole {
  15 }
src/main/java/com/example/demo/DemoApplication.java
   1 package com.example.demo;
   2 
   3 import java.util.ArrayList;
   4 import java.util.List;
   5 import java.util.Map;
   6 
   7 import org.springframework.boot.SpringApplication;
   8 import org.springframework.boot.autoconfigure.SpringBootApplication;
   9 import org.springframework.web.bind.annotation.GetMapping;
  10 import org.springframework.web.bind.annotation.PathVariable;
  11 import org.springframework.web.bind.annotation.RestController;
  12 import org.springframework.security.core.Authentication;
  13 import org.springframework.security.core.GrantedAuthority;
  14 import org.springframework.security.oauth2.jwt.Jwt;
  15 
  16 @RestController
  17 @SpringBootApplication
  18 public class DemoApplication {
  19 
  20   public static void main(String[] args) {
  21     SpringApplication.run(DemoApplication.class, args);
  22   }
  23 
  24   @GetMapping("/otherhello")
  25   public String otherHello() {
  26     return "other hello";
  27   }
  28 
  29   @GetMapping("/hello")
  30   @UserRole
  31   public String hello(Authentication authentication) {
  32     String authorities = "";
  33     for (int authorityIndex = 0; authorityIndex < authentication.getAuthorities().size(); authorityIndex++) {
  34       GrantedAuthority ga = (GrantedAuthority) authentication.getAuthorities().toArray()[authorityIndex];
  35       authorities += ga.getAuthority() + " ";
  36     }
  37 
  38     Jwt jwt = (Jwt) authentication.getCredentials();
  39 
  40     Object[] keys = jwt.getClaims().keySet().toArray();
  41     String allkeys = "";
  42 
  43     String preferredUsername = jwt.getClaim("preferred_username").toString();
  44     Map<String, Object> realmAccess = jwt.getClaimAsMap("realm_access");
  45     List<String> roles = (ArrayList<String>) realmAccess.get("roles");
  46     System.out.println("Contains USER " + roles.contains("USER"));
  47 
  48     for (int j = 0; j < keys.length; j++) {
  49       allkeys = allkeys + " " + (String) keys[j] + ":" + jwt.getClaims().get(keys[j]).toString() + " ";
  50     }
  51 
  52     return "I am authenticated with user " + authentication.getName() + " Authorities: " + authorities + " Details: "
  53         + authentication.getDetails().toString() + " allKeys: " + allkeys + " ... " + preferredUsername + " ... "
  54         + roles;
  55   }
  56 
  57   @GetMapping("/helloAdmin")
  58   @AdminRole
  59   public String helloAdmin(Authentication authentication) {
  60     return "Hello ADMIN";
  61   }
  62 
  63   @GetMapping("/helloUser/{text}")
  64   @UserRole
  65   public String helloUser(Authentication authentication, @PathVariable String text) {
  66     return "Hello USER " + text;
  67   }
  68 }
