You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring OAuth2配置带凭证代理访问OAuth2.0服务器问题求助

Spring Boot OAuth2客户端配置带凭证代理的解决方案

核心逻辑

Spring Security OAuth2客户端的所有请求(比如授权码交换Token、刷新Token等)都是通过ClientHttpRequestFactory执行的,只要自定义这个工厂并配置代理及凭证,再替换默认的工厂,就能让OAuth请求走带认证的代理。

具体实现步骤

1. 添加HTTP客户端依赖

Spring Boot默认的SimpleClientHttpRequestFactory对代理认证支持有限,推荐使用Apache HttpClient5来处理带凭证的代理,先在pom.xml中添加依赖:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
</dependency>

2. 自定义带代理的ClientHttpRequestFactory

创建配置类,定义带代理凭证的请求工厂Bean:

import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpHost;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

@Configuration
public class ProxyConfig {

    @Bean
    public HttpComponentsClientHttpRequestFactory proxyHttpRequestFactory() {
        // 替换为你的代理服务器地址和端口
        HttpHost proxy = new HttpHost("proxy.yourcompany.com", 8080);
        
        // 替换为代理的用户名和密码
        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                new AuthScope(proxy.getHostName(), proxy.getPort()),
                new UsernamePasswordCredentials("proxy-user", "proxy-pass".toCharArray())
        );

        CloseableHttpClient httpClient = HttpClients.custom()
                .setProxy(proxy)
                .setDefaultCredentialsProvider(credentialsProvider)
                .setConnectionManager(new PoolingHttpClientConnectionManager())
                .build();

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(5000);
        return factory;
    }
}

3. 配置OAuth2客户端使用自定义请求工厂

修改你的Security FilterChain配置,让OAuth2的授权码交换请求使用这个代理工厂:

import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
// 其他必要的导入

// 在你的Security配置类中
@Autowired
private HttpComponentsClientHttpRequestFactory proxyHttpRequestFactory;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers(PAGE_AUTH_SSO_LOGIN, PAGE_AUTH_ERROR, LOGIN_OAUTH2_CALLBACK_URL,
                            AuthenticationUtils.FAILURE_OAUTH_LOGIN_CALLBACK,
                            SpringConstants.ACTUATOR_HEALTH_URL).permitAll()
                    .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                    .loginPage(PAGE_AUTH_SSO_LOGIN)
                    .successHandler((request, response, authentication) ->
                            response.sendRedirect(SUCCESSFUL_OAUTH_LOGIN_CALLBACK))
                    .failureHandler((request, response, authentication) ->
                            response.sendRedirect(AuthenticationUtils.FAILURE_OAUTH_LOGIN_CALLBACK))
                    // 配置授权码流程使用代理请求工厂
                    .authorizationCodeGrant(codeGrant -> codeGrant
                            .tokenEndpoint(tokenEndpoint -> tokenEndpoint
                                    .accessTokenResponseClient(accessTokenResponseClient())
                            )
                    )
            )
            .logout(logout -> logout
                    .logoutUrl(LOGOUT_URL)
                    .logoutSuccessUrl("/oauth2/authorization/logout?redirect_uri=http://localhost:8090/page/auth/ssoLogin.xhtml")
                    .clearAuthentication(true)
                    .invalidateHttpSession(true)
                    .deleteCookies(JSESSIONID)
            )
            .csrf().disable();
    return http.build();
}

// 定义使用代理工厂的Token响应客户端
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() {
    DefaultAuthorizationCodeTokenResponseClient tokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
    tokenResponseClient.setRequestFactory(proxyHttpRequestFactory);
    return tokenResponseClient;
}

4. 额外:WebClient请求也走代理(如果需要)

如果你的应用中用WebClient调用OAuth2服务器的其他接口,也可以配置WebClient使用代理:

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.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.client.HttpComponentsClientHttpConnector;

// 在配置类中添加
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Autowired
private OAuth2AuthorizedClientRepository authorizedClientRepository;
@Autowired
private HttpComponentsClientHttpRequestFactory proxyHttpRequestFactory;

@Bean
public WebClient oauth2WebClient() {
    OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
            .authorizationCode()
            .refreshToken()
            .build();

    OAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
            clientRegistrationRepository, authorizedClientRepository);
    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Filter =
            new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);

    return WebClient.builder()
            .clientConnector(new HttpComponentsClientHttpConnector(proxyHttpRequestFactory.getHttpClient()))
            .apply(oauth2Filter.oauth2Configuration())
            .build();
}

注意事项

  • 确保代理服务器地址、端口、用户名密码正确,可先通过curl测试代理连通性
  • 如果代理使用NTLM认证,需要调整HttpClient的认证配置(替换BasicCredentialsProvider为对应的NTLM认证提供者)
  • 以上代码适配Spring Boot 3.0.1、Spring Security 3.0.1版本

内容的提问来源于stack exchange,提问作者glethien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:56:36