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)