我已经看过了几乎所有关于这个话题的博客和帖子,但我看不到解决方案。我有一个看起来像这样的WebSecurityConfigurerAdapter:
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
String issuerUri = "issuer url";
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers(HttpMethod.GET, "/test").hasRole("Task.Write")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(jwt ->
jwt.decoder(JwtDecoders.fromIssuerLocation(issuerUri))
)
);
}我有一个控制器,看起来像这样:
@GetMapping(value="/test")
public ApplicationResponse test(@AuthenticationPrincipal Jwt jwt) {
// Map<String, Object> x = jwt.getClaims();
return new ApplicationResponse("ok", "ok");
}然而,当我用一个有效的JWT使用Postman访问这个端点时,我得到了一个403错误。我试过用ROLE_和Role_作为角色的前缀,也试过很多其他的方法,但它总是403。
同样奇怪的是,如果我执行permitAll()而不是身份验证,并让JWT通过。我可以在控制器中查看JWT对象。我看到这个角色就在那里。那么,当JWT有效并且角色存在时,为什么这个WebSecurityConfigurerAdapter总是抛出403呢?
我注意到角色位于JWT中的声明中。也许我需要从这里拿到它?我不知道如何在configure方法中从声明中获取角色:

发布于 2021-04-29 02:17:16
默认情况下,Spring Security会转换scope或scp声明中的项,并使用SCOPE_前缀。您可以通过定义自定义JwtAuthenticationConverter bean来更改这两种约定。
要从roles作用域导出授权并使用ROLE_前缀,可以定义以下转换器,以便可以使用hasRole("Task_Write")等方法。
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
return jwtAuthenticationConverter;
}https://stackoverflow.com/questions/67224043
复制相似问题