Spring Authorization Server程序化生成Access Token(Spring Security 6.0.2)
直接用Spring Authorization Server内置组件就能实现,无需手动构造OAuth2请求,核心是利用OAuth2TokenGenerator及相关上下文对象生成token,具体步骤如下:
注入核心组件
在服务类中注入OAuth2TokenGenerator<OAuth2AccessToken>、RegisteredClientRepository、OAuth2AuthorizationService这三个Bean——它们都是Spring Authorization Server自动配置好的,直接注入即可。获取目标客户端配置
从RegisteredClientRepository中取出内部微服务对应的RegisteredClient实例,这个客户端是你预先在Authorization Server中配置的、供内部服务调用的客户端。构建Token生成上下文
基于已有的Saml2Authentication和Principal,构建OAuth2AuthorizationContext,它会向Authorization Server传递生成token所需的关键信息,比如认证主体、客户端标识、token类型等。生成并提取Access Token
调用OAuth2TokenGenerator的generate方法传入上下文,得到OAuth2AccessToken实例后,直接提取token值即可。
代码示例
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenGenerator; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.context.OAuth2AuthorizationContext; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; import org.springframework.stereotype.Service; @Service public class InternalTokenService { private final OAuth2TokenGenerator<OAuth2AccessToken> tokenGenerator; private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; public InternalTokenService(OAuth2TokenGenerator<OAuth2AccessToken> tokenGenerator, RegisteredClientRepository registeredClientRepository, OAuth2AuthorizationService authorizationService) { this.tokenGenerator = tokenGenerator; this.registeredClientRepository = registeredClientRepository; this.authorizationService = authorizationService; } public String generateInternalAccessToken(Saml2Authentication saml2Authentication) { // 1. 获取内部服务对应的客户端配置,替换为你实际的clientId RegisteredClient registeredClient = registeredClientRepository.findByClientId("internal-service-client"); if (registeredClient == null) { throw new IllegalArgumentException("无效的客户端ID"); } // 2. 构建授权上下文基础信息 OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient) .principalName(saml2Authentication.getName()) .attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, registeredClient.getScopes()) .authentication(saml2Authentication); OAuth2Authorization authorization = authorizationBuilder.build(); // 3. 组装Token生成上下文 OAuth2AuthorizationContext context = OAuth2AuthorizationContext.withAuthorization(authorization) .registeredClient(registeredClient) .principal(saml2Authentication) .build(); // 4. 生成Access Token OAuth2AccessToken accessToken = tokenGenerator.generate(context); if (accessToken == null) { throw new IllegalStateException("生成Access Token失败"); } // 5. 保存授权信息(可选,用于后续token校验、刷新等操作) authorization = authorizationBuilder.token(accessToken, (metadata) -> { metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, accessToken.getClaims()); }).build(); authorizationService.save(authorization); return accessToken.getTokenValue(); } }
关键注意事项
- 确保
RegisteredClient配置正确:需设置合适的scope、token有效期,客户端需提前在Authorization Server中完成配置。 - 权限映射:如果内部服务需要特定权限,要保证
Saml2Authentication中的authorities已正确转换为OAuth2的scope或权限声明。 - 授权信息保存:生成token后将
OAuth2Authorization保存到OAuth2AuthorizationService,这样后续的token校验、刷新操作才能正常执行。
内容的提问来源于stack exchange,提问作者wileecoyote
相关产品推荐
相关产品推荐

