im using FusionAuth for my Oauth server and I have a problem. Spring security will decode the JWT successfully but there are no roles!
This is my complete Authentication Object in JSON:
https://jsoneditoronline.org/#left=cloud.911cb58e717544ab9168632ed221aae1
and as you can see I have the roles and the role object in my principal. but when I try to use it in @PreAuthroize or even log it. it's empty.
WebSecurityConfigurerAdapter:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers(HttpMethod.GET, "v1/balance/**").permitAll()
.antMatchers(HttpMethod.POST, "v1/balance/**").permitAll()
.antMatchers(HttpMethod.GET, "/actuator/**").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(jwt ->
jwt.decoder(JwtDecoders.fromIssuerLocation(issuerUri)).jwkSetUri(jwksUrl)
)
);
}
this is how i try to log the roles:
@GetMapping("/currency/{currency}")
// @PreAuthorize("hasAnyRole('admin')")
public CurrencyBalance getWalletByCurrency(@PathVariable String currency, Principal principal){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Set<String> roles = authentication.getAuthorities().stream()
.map(r -> r.getAuthority()).collect(Collectors.toSet());
System.out.println(roles);
System.out.println(new Gson().toJson(authentication));
System.out.println(authentication.getAuthorities());
System.out.println(authentication.getCredentials().toString());
System.out.println(authentication.getDetails());
System.out.println(authentication.getPrincipal());
System.out.println(authentication.getName());
return null;
// return balanceService.getWalletByCurrency(principal.getName(),currency);
}
First of all, you need to understand How JWT Authentication Works
(source: spring.io)
JwtAuthenticationConverter converts JWT to authorities of Authentication, By default it only decode the SCOPE of JWT to authorities.(look at JwtGrantedAuthoritiesConverter).
You have to create a subclass of JwtAuthenticationConverter and override the extractAuthorities method if you want to decode custom attribute of JWT. Finally, declare you custom subclass as a Bean, spring security will automatically use it