Another way to control access is Role based, which enables "grouping" the privilege that makes management easier.
For example, the real life scenario is like:
Again, 3-party play:
Define user and roles in Auth Server
Resource Server: Securing endpoints to a specific role
@EnableWebSecurity public class WebSecurity extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRoleConverter()); http .authorizeRequests() .antMatchers(HttpMethod.GET, "/users/status/check") .hasRole("developer") .anyRequest().authenticated() .and() .oauth2ResourceServer() .jwt() .jwtAuthenticationConverter(jwtAuthenticationConverter); } }
Resource Server: Mapping the JWT role, into Autority class reckognised by Spring.
In the code, we will need to convert the role into spring-authorities
Here is a trick on how to inspect the role from the token (https://jwt.io/)
public class KeycloakRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> { @Override public Collection<GrantedAuthority> convert(Jwt jwt) { Map<String, Object> realmAccess = (Map<String, Object>) jwt.getClaims().get("realm_access"); if (realmAccess == null || realmAccess.isEmpty()) { return new ArrayList<>(); } Collection<GrantedAuthority> returnValue = ((List<String>) realmAccess.get("roles")) .stream().map(roleName -> "ROLE_" + roleName) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); return returnValue; } }
Spring framework has 2 methods to check:
-
hasAuthority("ROLE_developer");
//you have to add the prefix ROLE_ by yourself. -
hasRole("developer");
// it is working the same as above, but without needing to add prefix ROLE_
Top comments (0)