0

I'm building a standard spring boot mvc + thymeleaf + Oauth2. So far I added the oauth2-client lib for authentication purpose but now I need authorization to protect my app.

Does it mean I also need to configure it as a resource server?

If not, how can I map authorities from the private claim (in the ID token) my authorization-server puts roles into?

ch4mp
  • 6,622
  • 6
  • 29
  • 49
user2566397
  • 89
  • 10

1 Answers1

1

Resource-server configuration is adapted to secure REST resources.

Client configuration is just fine unless you expose your API. If so, add a second security filter-chain. Details in this other answer: Use Keycloak Spring Adapter with Spring Boot 3

Authorities mapping in OAuth2 client

As mentioned in my comment, Spring-security documentation is always better than whatever one on Stackoverflow could write (but Spring-security team members of course, who happen to post answers)

Double check the claim in which your authorization-server puts user roles into and provide an authorities mapper, either:

  • explicitly with http.oauth2Login().userInfoEndpoint().userAuthoritiesMapper(userAuthoritiesMapper());
  • as a @Bean of type GrantedAuthoritiesMapper which should be auto-configured by spring-boot

In both cases, the code for the mapper is the same (double check the name of the claim for user roles with your authorization-server, but it might be groups with Azure AD):

@Bean
GrantedAuthoritiesMapper userAuthoritiesMapper() {
    return (authorities) -> {
        Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

        authorities.forEach(authority -> {
            if (authority instanceof OidcUserAuthority oidcAuth) {
                oidcAuth.getIdToken().getClaimAsStringList("groups").forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));

            } else if (authority instanceof OAuth2UserAuthority oauth2Auth) {
                ((List<String>) oauth2Auth.getAttributes().getOrDefault("groups", List.of())).forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));

            }
        });

        return mappedAuthorities;
    };
}
ch4mp
  • 6,622
  • 6
  • 29
  • 49
  • ok so I should be able to validate the authorization just with my id token right? – user2566397 Feb 13 '23 at 20:41
  • where I can set the claim field name to look for the roles? – user2566397 Feb 13 '23 at 20:50
  • Better to ask god than his disciples: https://docs.spring.io/spring-security/reference/reactive/oauth2/login/advanced.html#webflux-oauth2-login-advanced-map-authorities-grantedauthoritiesmapper – ch4mp Feb 14 '23 at 01:06
  • I edited your question so that, I believe, others with same need have better chance to open the thread. Hope you don't mind. – ch4mp Feb 14 '23 at 02:57
  • Im getting **403** when protecting all requests, any ideia? `http.authorizeHttpRequests((authorize) -> authorize .anyRequest().hasRole("admin"));` – user2566397 Feb 14 '23 at 03:25
  • maybe have you exactly `admin` in your access token => either add `ROLE_` prefix in the mapper or use `hasAuthority("admin")` instead of `hasRole("admin")` (for Spring, a role is nothing more than an authority starting with `ROLE_`) – ch4mp Feb 14 '23 at 04:17
  • it is all set but still doesnt work, I noticed when using the SecurityFilterChain the GrantedAuthoritiesMapper didnt get invoked – user2566397 Feb 14 '23 at 12:46
  • GrantedAuthoritiesMapper with @Bean annotation didnt work, but if I set that into the oauth2Login it works – user2566397 Feb 14 '23 at 13:33