Spring 安全无法从 JWT 中提取角色

Spring security can't extract roles from JWT

我正在为我的 Oauth 服务器使用 FusionAuth,但我遇到了问题。 Spring security 将成功解码 JWT 但没有角色!

这是我在 JSON 中的完整身份验证对象:

https://jsoneditoronline.org/#left=cloud.911cb58e717544ab9168632ed221aae1

如您所见,我的主体中有角色和角色对象。但是当我尝试在@PreAuthroize 中使用它甚至记录它时。它是空的。

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

    }

这是我尝试记录角色的方式:

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

首先,您需要了解 JWT 身份验证的工作原理 JwtAuthenticationConverter converts JWT to authorities of Authentication, By default it only decode the SCOPE of JWT to authorities.(look at JwtGrantedAuthoritiesConverter).

如果要解码 JWT 的自定义属性,则必须创建 JwtAuthenticationConverter 的子类并覆盖 extractAuthorities 方法。 最后,将您的自定义子类声明为 Bean,spring 安全性将自动使用它