gpt4 book ai didi

java - Spring Security 5 根据 JWT 声明填充权限

转载 作者:行者123 更新时间:2023-11-30 01:42:44 25 4
gpt4 key购买 nike

据我所知,Spring Security OAuth2.x 项目已移至 Spring Security 5.2.x。我尝试以新的方式实现授权和资源服务器。除了一件事 - @PreAuthorize 注释之外,一切都正常工作。当我尝试将其与标准 @PreAuthorize("hasRole('ROLE_USER')") 一起使用时,我总是被禁止。我看到的是 Principal 类型为 org.springframework.security.oauth2.jwt.Jwt 的对象无法解析权限,我不知道为什么。

org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken@44915f5f: Principal: org.springframework.security.oauth2.jwt.Jwt@2cfdbd3; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffffa64e: RemoteIpAddress: 172.19.0.1; SessionId: null; Granted Authorities: SCOPE_read, SCOPE_write

将其转换为Jwt后声明

{user_name=user, scope=["read","write"], exp=2019-12-18T13:19:29Z, iat=2019-12-18T13:19:28Z, authorities=["ROLE_USER","READ_ONLY"], client_id=sampleClientId}

安全服务器配置

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Autowired
private DataSource dataSource;

@Autowired
private AuthenticationManager authenticationManager;

@Bean
public KeyPair keyPair() {
ClassPathResource ksFile = new ClassPathResource("mytest.jks");
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(ksFile, "mypass".toCharArray());
return keyStoreKeyFactory.getKeyPair("mytest");
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(keyPair());
return converter;
}

@Bean
public JWKSet jwkSet() {
RSAKey key = new Builder((RSAPublicKey) keyPair().getPublic()).build();
return new JWKSet(key);
}

@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

private UserDetailsService userDetailsService;

public SecurityConfiguration(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/.well-known/jwks.json")
.permitAll()
.anyRequest()
.authenticated();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}

资源服务器配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResuorceServerConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}
}

也许有人有类似的问题?

最佳答案

默认情况下,资源服务器根据“scope”声明填充权限。
如果 Jwt 包含名称为 "scope""scp" 的声明,那么 Spring Security 将使用该声明中的值来构造当局通过在每个值前加上“SCOPE_”作为前缀。

在您的示例中,其中一项声明是 scope=["read","write"]
这意味着权限列表将由 "SCOPE_read""SCOPE_write" 组成。

您可以通过在安全配置中提供自定义身份验证转换器来修改默认权限映射行为。

http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(getJwtAuthenticationConverter());

然后在 getJwtAuthenticationConverter 的实现中,您可以配置 Jwt 如何映射到权限列表。

Converter<Jwt, AbstractAuthenticationToken> getJwtAuthenticationConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt -> {
// custom logic
});
return converter;
}

关于java - Spring Security 5 根据 JWT 声明填充权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59379645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com