Spring Boot微服务:OAuth2仅保护对外API,放行对内请求的配置问题
解决方案:Spring Boot 3.x 中 OAuth2 客户端服务自身API放行配置
问题根源
添加spring-boot-starter-oauth2-client依赖后,Spring Security自动配置会默认启用OAuth2客户端相关安全规则,同时默认保护所有HTTP端点,这就是S2自身API被要求登录的原因。之前自定义SecurityFilterChain出现Forbidden,大概率是因为配置未适配WebFlux环境,或是遗漏了OAuth2客户端必要配置项。
正确配置步骤
1. 适配WebFlux的SecurityFilterChain配置
创建或修改安全配置类,明确放行S2自身API,同时保留OAuth2客户端配置以支持调用S1:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; @Configuration @EnableWebFluxSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http // 非浏览器调用的API可关闭CSRF防护 .csrf(ServerHttpSecurity.CsrfSpec::disable) // 放行所有自身API请求,也可指定具体路径如pathMatchers("/s2-api/**").permitAll() .authorizeExchange(exchanges -> exchanges.anyExchange().permitAll() ) // 保留OAuth2客户端配置,确保WebClient能自动获取调用S1的凭证 .oauth2Client(oauth2 -> oauth2); return http.build(); } }
2. 验证OAuth2客户端配置
确保application.properties中的客户端配置仅用于S1调用,不干扰自身API:
# S1的OAuth2客户端凭证配置 spring.security.oauth2.client.registration.s1-client.client-id=你的客户端ID spring.security.oauth2.client.registration.s1-client.client-secret=你的客户端密钥 spring.security.oauth2.client.registration.s1-client.authorization-grant-type=client_credentials spring.security.oauth2.client.provider.s1-client.token-uri=http://S1的地址:端口/oauth2/token
3. 确认WebClient配置正确性
保证WebClient使用OAuth2客户端上下文,调用S1时自动携带凭证:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class WebClientConfig { @Bean public WebClient webClient(ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Filter) { return WebClient.builder() .filter(oauth2Filter) .build(); } @Bean public ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Filter( ServerOAuth2AuthorizedClientManager authorizedClientManager) { ServerOAuth2AuthorizedClientExchangeFilterFunction filter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); // 指定使用的客户端注册ID,对应application.properties中的s1-client filter.setDefaultClientRegistrationId("s1-client"); return filter; } }
关键注意点
- 因为使用WebFlux,必须用
@EnableWebFluxSecurity和ServerHttpSecurity配置,而非Servlet环境的@EnableWebSecurity和HttpSecurity,这是很多配置失败的核心原因。 - 必须保留
.oauth2Client()配置段,否则Spring会禁用OAuth2客户端自动配置,导致WebClient无法获取S1的调用凭证。
内容的提问来源于stack exchange,提问作者Jithin M V
相关产品推荐
相关产品推荐

