提问者:小点点

@RolesAllowed注释始终引发Keyclock 403错误


我是Spring boot的新手,可能有一个愚蠢的问题。我有一个简单的Spring boot rest api应用程序,具有Spring Security和oaut2。Outh2代理是Keycloak所以我的安全过滤器看起来像这样

@Configuration
@EnableWebSecurity
public class WebSecurityAdditionalConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .authorizeRequests()
                .antMatchers("/api/**")
                .authenticated()
                .and()
                .oauth2ResourceServer().jwt();
        http.csrf().disable().sessionManagement().sessionCreationPolicy(
                SessionCreationPolicy.STATELESS);
    }

}

我还启用了全局方法安全性


@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = true, prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}

但当我尝试将@RolesAllowed('admin')添加到我的控制器方法时,我总是会得到403禁止错误。如果没有注释,一切都正常,如果没有令牌,我会得到401,如果令牌过期403。这是我的jwt示例

{
  
  "realm_access": {
    "roles": [
      "admin"
    ]
  },
  "resource_access": {
    "edge_client": {
      "roles": [
        "cli_admin"
      ]
    }
  },
  "scope": "profile web-origins email",
  "email_verified": false,
  "name": "John Spartan",
  "groups": [
    "admin"
  ],
  "preferred_username": "test_admin",
  "given_name": "John",
  "family_name": "Spartan"
}

共1个答案

匿名用户

我认为这个类负责获取权限。默认情况下,它正在jwt中查找范围scp声明。在您的情况下,您有"范围":"profile web-Oriins email"。之后,它会在每个权限前加上DEFAULT_AUTHORITY_PREFIX等于SCOPE_。我想当您从SecurityContextHolder. getContext().getAuthentication()getAuth()返回的权限将等于SCOPE_profileSCOPE_web-起源SCOPE_email。您应该将代码更改为:

.oauth2ResourceServer()
.jwt(customizer -> {
    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    //write your own Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter 
    //and override Collection<GrantedAuthority> convert(Jwt jwt) to get roles from
    //realm_access.roles
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
    customizer.jwtAuthenticationConverter(jwtAuthenticationConverter)
})

或使用 Keycloak Adapter for Spring 而不是 oauth2ResourceServer()