gpt4 book ai didi

java - Spring Security JWT 刷新 token 未过期

转载 作者:搜寻专家 更新时间:2023-11-01 03:31:58 26 4
gpt4 key购买 nike

我是 spring 的新手,我正在使用 spring security 开发 spring boot REST,目前我实现了 JWT token 。我有一些问题,但似乎找不到答案。我尝试添加刷新 token 。
起初我以为我会把它和用户一起存储在数据库中,但是 spring security 会自动完成所有事情,我似乎无法找到如何将它存储在表用户的给定字段中。
因此,继续前进我决定我将尝试坚持使用 spring 安全自动化并将刷新 token 过期时间设置为 10 秒以测试它是否过期,但遗憾的是它没有按预期工作 - 我可以根据需要使用刷新 token 并用它生成新的 token 。
所以在这里我有几个问题:
1. 如何让刷新 token 在给定时间后过期?这是我的安全配置

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

@Value("${security.signing-key}")
private String signingKey;

@Value("${security.encoding-strength}")
private Integer encodingStrength;

@Value("${security.security-realm}")
private String securityRealm;

@Autowired
private UserDetailsService userDetailsService;

@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}

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

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

@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().httpBasic()
.realmName(securityRealm).and().csrf().disable();

}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
}

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

@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setRefreshTokenValiditySeconds(10);
return defaultTokenServices;
}

  1. 是否可以将刷新 token 传递给数据库并手动检查 token 是否有效,因为这是我的第一个想法。

最佳答案

我确实找到了答案,只是忘了更新我的工单。所以在这里,默认情况下 JwtTokenStore 不支持刷新 token 。 Here's JwtTokenStore source code .所以这意味着,在设置中启用 token 实际上不会使其工作。我所做的是创建我自己的 JWT token 存储,它扩展了 JwtTokenStore 并编写了我自己的刷新 token 逻辑。

public class MyJwtTokenStore extends JwtTokenStore {

@Autowired
UserRepository userRepository;

public MyJwtTokenStore(JwtAccessTokenConverter jwtTokenEnhancer) {
super(jwtTokenEnhancer);
}

@Override
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
user.setToken(refreshToken.getValue());
userRepository.save(user);
}

@Override
public OAuth2RefreshToken readRefreshToken(String token) {
OAuth2Authentication authentication = super.readAuthentication(token);
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
if (!token.equals(user.getToken())) {
return null;
}
OAuth2RefreshToken refreshToken = new DefaultOAuth2RefreshToken(token);
return refreshToken;
}

@Override
public void removeRefreshToken(OAuth2RefreshToken token) {
OAuth2Authentication authentication = super.readAuthentication(token.getValue());
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
user.setToken(null);
userRepository.save(user);
}

在此之后,我刚刚更新了我的 TokenStore Bean

@Bean
public TokenStore tokenStore() {
MyJwtTokenStore jwtTokenStore = new MyJwtTokenStore(accessTokenConverter());
return jwtTokenStore;
// return new JwtTokenStore(accessTokenConverter());
}

最后,我将剩余的设置添加到我的 AuthorizationServerConfigurerAdapter 类中以支持刷新 token 并为其提供有效时间。

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Value("${security.jwt.client-id}")
private String clientId;

@Value("${security.jwt.client-secret}")
private String clientSecret;

@Value("${security.jwt.grant-type}")
private String grantType;

@Value("${security.jwt.grant-type-other}")
private String grantTypeRefresh;

@Value("${security.jwt.scope-read}")
private String scopeRead;

@Value("${security.jwt.scope-write}")
private String scopeWrite = "write";

@Value("${security.jwt.resource-ids}")
private String resourceIds;

@Autowired
private TokenStore tokenStore;

@Autowired
private JwtAccessTokenConverter accessTokenConverter;

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private AppUserDetailsService userDetailsService;

@Autowired
private PasswordEncoder passwordEncoder;


@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.authorizedGrantTypes(grantType, grantTypeRefresh).scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds).autoApprove(false).accessTokenValiditySeconds(1800) // 30min
.refreshTokenValiditySeconds(86400); //24 hours
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints.tokenStore(tokenStore).accessTokenConverter(accessTokenConverter).tokenEnhancer(enhancerChain)
.reuseRefreshTokens(false).authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}

@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); // http://localhost:4200
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}

关于java - Spring Security JWT 刷新 token 未过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48974646/

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