Spring Security 4到6迁移:DefaultTokenServices的替代方案咨询
Spring Security 6 替代 DefaultTokenServices 的方案
在Spring Security 6中,原DefaultTokenServices所属的旧版OAuth2模块已被重构,官方推荐用职责拆分后的组件替代其功能。若要沿用原有授权流程,可通过**OAuth2AuthorizationService和OAuth2TokenGenerator**的组合实现与DefaultTokenServices一致的核心行为。
核心组件说明
OAuth2AuthorizationService:负责OAuth2授权记录(包含令牌、客户端、用户信息等)的存储、查询与更新,对应原DefaultTokenServices中令牌的持久化逻辑。OAuth2TokenGenerator:负责生成访问令牌、刷新令牌等,对应原DefaultTokenServices中的令牌生成逻辑。
替代实现示例
1. 注入核心组件
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; // 注入两个核心组件 private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator; // 构造方法注入(推荐方式) public YourTokenService(OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator) { this.authorizationService = authorizationService; this.tokenGenerator = tokenGenerator; }
2. 实现令牌创建(对应原createAccessToken)
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; import java.time.Instant; public OAuth2AccessToken createAccessToken(OAuth2Authorization authorization) { // 构建令牌生成上下文 OAuth2TokenContext tokenContext = OAuth2TokenContext.builder() .registeredClient(authorization.getRegisteredClient()) .principal(authorization.getPrincipalName()) .authorization(authorization) .tokenType(OAuth2TokenType.ACCESS_TOKEN) .build(); // 生成访问令牌 OAuth2AccessToken accessToken = (OAuth2AccessToken) this.tokenGenerator.generate(tokenContext); // 更新授权记录并保存 authorization = OAuth2Authorization.from(authorization) .token(accessToken, metadata -> metadata.put(OAuth2Authorization.Token.CREATED_AT, Instant.now())) .build(); this.authorizationService.save(authorization); return accessToken; }
3. 实现令牌刷新(对应原refreshAccessToken)
import org.springframework.security.oauth2.core.OAuth2Token; import org.springframework.security.oauth2.server.authorization.InvalidTokenException; public OAuth2AccessToken refreshAccessToken(String refreshTokenValue) { // 根据刷新令牌查询授权记录 OAuth2Authorization authorization = this.authorizationService.findByToken( refreshTokenValue, OAuth2TokenType.REFRESH_TOKEN); if (authorization == null) { throw new InvalidTokenException("无效的刷新令牌"); } // 生成新的访问令牌 OAuth2TokenContext tokenContext = OAuth2TokenContext.builder() .registeredClient(authorization.getRegisteredClient()) .principal(authorization.getPrincipalName()) .authorization(authorization) .tokenType(OAuth2TokenType.ACCESS_TOKEN) .build(); OAuth2AccessToken newAccessToken = (OAuth2AccessToken) this.tokenGenerator.generate(tokenContext); // 更新授权记录,替换旧访问令牌 authorization = OAuth2Authorization.from(authorization) .token(newAccessToken, metadata -> metadata.put(OAuth2Authorization.Token.CREATED_AT, Instant.now())) .build(); this.authorizationService.save(authorization); return newAccessToken; }
4. 实现令牌验证与删除
- 令牌验证:通过
authorizationService.findByToken(tokenValue, OAuth2TokenType.ACCESS_TOKEN)查询令牌是否存在,同时可检查令牌的过期时间、状态等。 - 令牌删除:调用
authorizationService.remove(authorization)删除对应授权记录,即可完成令牌失效处理。
额外注意事项
- 确保项目依赖替换为新版的
spring-security-oauth2-authorization-server(版本需匹配Spring Security 6.0.1),移除旧版的spring-security-oauth2依赖。 - 若需完全复刻
DefaultTokenServices的所有细节(如令牌过期策略、刷新令牌复用规则等),可在自定义的TokenService中添加对应逻辑,基于上述组件封装实现。
内容的提问来源于stack exchange,提问作者sejal mirani
相关产品推荐
相关产品推荐

