如何在非登录/认证场景下使用Spring Security OAuth2 Client
Spring Security 5.7 非Boot项目处理OAuth2回调及Token存储方案
一、手动跳转授权流程的正确性确认
手动跳转至/oauth2/authorization/blarg是完全正确的——这是Spring Security OAuth2 Client的标准授权请求端点,只要你的第三方客户端registrationId配置为blarg,该端点会触发OAuth2AuthorizationRequestRedirectFilter生成授权请求并自动重定向到第三方服务的授权页面。
二、处理回调授权码并存储AccessToken
要完成授权码到AccessToken的转换,并将结果存入authorizedClientRepository,需要配置以下核心组件:
1. 配置ClientRegistration(指定自定义回调地址)
在Java配置类中定义ClientRegistrationRepository,明确指定你的自定义回调地址,确保与第三方服务配置的回调完全一致:
@Bean public ClientRegistrationRepository clientRegistrationRepository() { // 构建第三方客户端配置 ClientRegistration blargClient = ClientRegistration.withRegistrationId("blarg") .clientId("你的客户端ID") .clientSecret("你的客户端密钥") .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUri("https://example.com:9000/oauth/blarg") // 自定义回调地址 .authorizationUri("第三方服务的授权页面地址") .tokenUri("第三方服务的Token交换地址") .scope("需要申请的权限范围,如read:data") .build(); return new InMemoryClientRegistrationRepository(blargClient); }
2. 配置OAuth2AuthorizedClientRepository
使用基于HttpSession的实现(适合老项目的会话管理场景):
@Bean public OAuth2AuthorizedClientRepository authorizedClientRepository() { return new HttpSessionOAuth2AuthorizedClientRepository(); }
3. 在XML配置中添加回调处理过滤器
修改Spring Security的XML配置,将OAuth2AuthorizationCodeGrantFilter加入过滤器链,位置需在OAuth2AuthorizationRequestRedirectFilter之后:
<http> <!-- 保留你已有的认证配置:如用户名密码登录、SSO过滤器等 --> <!-- 授权请求跳转过滤器(已配置的部分) --> <custom-filter ref="oauth2AuthorizationRequestRedirectFilter" before="AUTHORIZATION_FILTER"/> <!-- 添加授权码回调处理过滤器 --> <custom-filter ref="oauth2AuthorizationCodeGrantFilter" before="AUTHORIZATION_FILTER"/> </http> <!-- 定义回调处理过滤器Bean --> <bean id="oauth2AuthorizationCodeGrantFilter" class="org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter"> <constructor-arg ref="clientRegistrationRepository"/> <constructor-arg ref="authorizedClientRepository"/> </bean> <!-- 授权请求跳转过滤器Bean(如果之前未完整定义) --> <bean id="oauth2AuthorizationRequestRedirectFilter" class="org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter"> <constructor-arg ref="clientRegistrationRepository"/> </bean>
4. 核心逻辑说明
当第三方服务回调到https://example.com:9000/oauth/blarg时,OAuth2AuthorizationCodeGrantFilter会自动执行以下操作:
- 解析回调中的授权码(code参数)
- 调用第三方服务的Token接口,交换得到AccessToken、RefreshToken等
- 将包含Token信息的
OAuth2AuthorizedClient对象存入你配置的authorizedClientRepository(默认是HttpSession)
三、获取Token调用第三方API
在业务代码中,可从authorizedClientRepository获取已授权的Token,代用户调用第三方API:
@Autowired private OAuth2AuthorizedClientRepository authorizedClientRepository; @Autowired private RestTemplate restTemplate; public void invokeThirdPartyApi(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取当前登录用户的认证信息 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // 加载已授权的客户端 OAuth2AuthorizedClient authorizedClient = authorizedClientRepository.loadAuthorizedClient("blarg", auth, request); if (authorizedClient != null) { String accessToken = authorizedClient.getAccessToken().getTokenValue(); // 配置请求头携带Token HttpHeaders headers = new HttpHeaders(); headers.setBearerAuth(accessToken); HttpEntity<String> entity = new HttpEntity<>(headers); // 调用第三方API ResponseEntity<String> apiResponse = restTemplate.exchange( "第三方API地址", HttpMethod.GET, entity, String.class ); // 处理API响应... } else { // 未授权,重定向到授权流程 response.sendRedirect("/oauth2/authorization/blarg"); } }
注意事项
- 确保Spring Security依赖版本为5.7.x,需引入
spring-security-oauth2-client和spring-security-oauth2-core依赖 - 第三方服务配置的回调地址必须与代码中
redirectUri完全一致(包括协议、域名、端口、路径) - 若需自动刷新过期Token,只需在
ClientRegistration中配置refreshTokenUri,Spring Security会自动处理刷新逻辑
内容的提问来源于stack exchange,提问作者DavidA
相关产品推荐
相关产品推荐

