引入spring-boot-starter-oauth2-client后公开接口返回登录页如何解决
问题根因
引入spring-boot-starter-oauth2-client依赖后,Spring Security自动装配逻辑会默认对所有接口开启认证保护,因此未配置免认证规则的/test接口会被拦截,触发默认登录流程。
解决方案
按以下三步修改即可实现需求:
步骤1:自定义Spring Security规则,放行免认证接口
创建安全配置类,明确指定/test无需认证即可访问:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 配置无需认证的接口,本地测试可把/test2也加入放行列表 .requestMatchers("/test").permitAll() // 其余接口的认证规则可根据业务需求调整 .anyRequest().authenticated() ) // 不需要默认的OAuth2登录页可关闭 .oauth2Login(oauth2 -> oauth2.disable()); return http.build(); } }
步骤2:配置支持OAuth2客户端认证的RestTemplate
普通RestTemplate不会自动携带OAuth2令牌,需要添加OAuth2拦截器实现自动获取、携带、刷新令牌的能力:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.client.http.OAuth2ClientHttpRequestInterceptor; import org.springframework.web.client.RestTemplate; @Configuration public class OAuth2RestConfig { @Bean public OAuth2AuthorizedClientManager clientCredentialsAuthorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) { // 配置仅支持客户端凭证模式的授权管理器 OAuth2AuthorizedClientProvider provider = OAuth2AuthorizedClientProviderBuilder .builder() .clientCredentials() .build(); DefaultOAuth2AuthorizedClientManager manager = new DefaultOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientRepository); manager.setAuthorizedClientProvider(provider); return manager; } @Bean public RestTemplate oauth2RestTemplate(OAuth2AuthorizedClientManager authorizedClientManager) { RestTemplate restTemplate = new RestTemplate(); // 添加OAuth2拦截器,自动处理令牌相关逻辑 restTemplate.getInterceptors().add(new OAuth2ClientHttpRequestInterceptor(authorizedClientManager)); return restTemplate; } }
步骤3:修改Controller使用配置好的RestTemplate
@RestController public class OAuthController { // 注入配置好的带OAuth2能力的RestTemplate private final RestTemplate oauth2RestTemplate; // 构造方法注入 public OAuthController(RestTemplate oauth2RestTemplate) { this.oauth2RestTemplate = oauth2RestTemplate; } @GetMapping(value="/test") public String testing() { System.out.println("running controller"); // 调用第三方OAuth2接口时,拦截器会自动在请求头携带access token return oauth2RestTemplate.getForObject("替换为第三方接口x的实际地址", String.class); } @GetMapping(value="/test2") public String testing2() { return "Hello from test2"; } }
内容的提问来源于stack exchange,提问作者Sarthak
相关产品推荐
相关产品推荐

