我是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"
}
我认为这个类负责获取权限。默认情况下,它正在jwt
中查找范围
或scp
声明。在您的情况下,您有"范围":"profile web-Oriins email"
。之后,它会在每个权限前加上DEFAULT_AUTHORITY_PREFIX
等于SCOPE_
。我想当您从SecurityContextHolder. getContext().getAuthentication()
其getAuth()
返回的权限将等于SCOPE_profile
、SCOPE_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()