DEV Community

JL
JL

Posted on

OAuth 2.0 - Role-based Access Control

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:

Image description

Again, 3-party play:

Define user and roles in Auth Server

Image description

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);
    }

}
Enter fullscreen mode Exit fullscreen mode

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/)

Image description

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;
    }

}
Enter fullscreen mode Exit fullscreen mode

Spring framework has 2 methods to check:

  1. hasAuthority("ROLE_developer"); //you have to add the prefix ROLE_ by yourself.
  2. hasRole("developer"); // it is working the same as above, but without needing to add prefix ROLE_

Top comments (0)