如何从Spring Cloud Gateway获取已认证用户的Access Token
获取Spring Cloud Gateway中已认证用户的Access Token
在Spring Cloud Gateway的OAuth2认证场景下,已认证用户的Access Token存储在OAuth2AuthorizedClient对象中,可通过以下两种方式获取:
方式一:在GlobalFilter中通过请求上下文获取
修改你已实现的GlobalFilter,注入ServerOAuth2AuthorizedClientRepository,结合OAuth2AuthenticationToken提取Token:
import org.springframework.security.oauth2.client.ServerOAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; public class AccessTokenExtractionFilter implements GlobalFilter { private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository; public AccessTokenExtractionFilter(ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { this.authorizedClientRepository = authorizedClientRepository; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return exchange.getPrincipal() .filter(principal -> principal instanceof OAuth2AuthenticationToken) .cast(OAuth2AuthenticationToken.class) .flatMap(authToken -> authorizedClientRepository.loadAuthorizedClient( authToken.getAuthorizedClientRegistrationId(), authToken, exchange ) ) .map(OAuth2AuthorizedClient::getAccessToken) .map(accessToken -> { // 提取Access Token的值 String tokenValue = accessToken.getTokenValue(); // 可选:将Token添加到请求头转发给下游服务 ServerHttpRequest modifiedRequest = exchange.getRequest().mutate() .header("X-User-Access-Token", tokenValue) .build(); return exchange.mutate().request(modifiedRequest).build(); }) .defaultIfEmpty(exchange) .flatMap(chain::filter); } }
方式二:通过ReactiveOAuth2AuthorizedClientService查询
如果需要在非请求上下文的服务类中获取Token,可注入ReactiveOAuth2AuthorizedClientService和ReactiveClientRegistrationRepository:
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import reactor.core.publisher.Mono; @Service public class TokenService { private final ReactiveOAuth2AuthorizedClientService authorizedClientService; private final ReactiveClientRegistrationRepository clientRegistrationRepository; public TokenService(ReactiveOAuth2AuthorizedClientService authorizedClientService, ReactiveClientRegistrationRepository clientRegistrationRepository) { this.authorizedClientService = authorizedClientService; this.clientRegistrationRepository = clientRegistrationRepository; } public Mono<String> getUserAccessToken(String username) { // 替换为你的客户端注册ID(对应application.yaml中的spring.security.oauth2.client.registration下的ID) String clientRegistrationId = "your-oauth2-client-id"; return clientRegistrationRepository.findByRegistrationId(clientRegistrationId) .flatMap(clientRegistration -> authorizedClientService.loadAuthorizedClient( clientRegistrationId, username ) ) .map(OAuth2AuthorizedClient::getAccessToken) .map(accessToken -> accessToken.getTokenValue()); } }
关键说明
- 确保
clientRegistrationId与application.yaml中配置的OAuth2客户端注册ID一致 - 使用
oauth2Login认证后,Spring Security会自动存储用户的授权客户端信息,无需手动维护 - 转发Token到下游服务时,建议使用自定义请求头(如示例中的
X-User-Access-Token),避免与标准HTTP头冲突
内容的提问来源于stack exchange,提问作者Puneet Mehta
相关产品推荐
相关产品推荐

