如何在spring oauth2上设置代理OAuth2AccessToken请求或如何覆盖OAuth2AccessTokenSupport restTemplate变量?

问题描述 投票:4回答:3

我试图通过以下方式设置网络代理,但没有一种方法可行

1:设置jvm变量,如-Dhttp.proxyHost = -Dhttp.proxyPort = ....... 2:创建了Bean。

@Bean
public RestTemplate restTemplate() {
    final String proxyHost = "######"; // host
    final int proxyPort = ####;  // port
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setProxy(new Proxy(Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)));
    return new RestTemplate(factory);
}

但OAuth2AccessTokenSupport.restTemplate会覆盖此配置。

因此,下面的方法总是返回新创建的rest模板对象。

org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport

protected RestOperations getRestTemplate() {
    if (restTemplate == null) {
        synchronized (this) {
            if (restTemplate == null) {
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.setErrorHandler(getResponseErrorHandler());
                restTemplate.setRequestFactory(requestFactory);
                restTemplate.setInterceptors(interceptors);
                this.restTemplate = restTemplate;
            }
        }
    }
    if (messageConverters == null) {
        setMessageConverters(new RestTemplate().getMessageConverters());
    }
    return restTemplate;
}

请帮助我在OAuth客户端应用程序中覆盖或设置其余模板的代理。

spring spring-security proxy spring-boot spring-security-oauth2
3个回答
3
投票

另一种方法是将自定义AccessTokenProvider设置为OAuth2RestTemplate。在下面的代码示例中,绕过了SSL验证:

@Configuration
public class ConfigLocal {

    @Value("${https.proxyHost}")
    private String proxyHost;

    @Value("${https.proxyPort}")
    private Integer proxyPort;

    @Value("${https.proxyUser}")
    private String proxyUser;

    @Value("${https.proxyPassword}")
    private String proxyPassword;

    @Bean
    public OAuth2RestTemplate oauth2RestTemplate(ClientCredentialsResourceDetails clientCredentialsResourceDetails)
            throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException {
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(clientCredentialsResourceDetails);

        // Instanciate a new http client with proxy configuration, and bypass SSL Certificate verification
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUser, proxyPassword));

        HttpClientBuilder httpClientBuilder =
                HttpClients.custom()
                        .setProxy(new HttpHost(proxyHost, proxyPort))
                        .setDefaultCredentialsProvider(credentialsProvider)
                        .setSSLHostnameVerifier(new NoopHostnameVerifier())
                            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true)
                                    .build());

        // requestFactory
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
        ClientCredentialsAccessTokenProvider clientCredentialsAccessTokenProvider = new ClientCredentialsAccessTokenProvider();
        clientCredentialsAccessTokenProvider.setRequestFactory(requestFactory);

        // accessTokenProvider
        AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(
                new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
                new ResourceOwnerPasswordAccessTokenProvider(), clientCredentialsAccessTokenProvider));

        restTemplate.setAccessTokenProvider(accessTokenProvider);

        return restTemplate;
    }
}

1
投票

这可能不是一个简单的解决方案。但最终设法通过以下代码在oauth请求上设置代理。

注册过滤器

@Override
protected void configure(HttpSecurity http) throws Exception {
    // @formatter:off
    http.antMatcher("/**")
    .authorizeRequests().antMatchers("/webjars/**", "/scripts/**", "/styles/**", "/instances/**", "/#/invalid").permitAll()
    .anyRequest().authenticated()
    .and().csrf().csrfTokenRepository(csrfTokenRepository())
    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
    .addFilterBefore(oauthFilter(), BasicAuthenticationFilter.class);
    // @formatter:on
    super.configure(http);
}

验证过滤器

@Autowired
OAuth2ClientContext oauth2ClientContext;

@Autowired
OAuth2ProtectedResourceDetails resource;

@Autowired
ResourceServerProperties resourceServer;

@Autowired
RequestHelper requestHelper;

private Filter oauthFilter() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    OAuth2ClientAuthenticationProcessingFilter oauthFilter = new OAuth2ClientAuthenticationProcessingFilter("/login");
    OAuth2RestTemplate oauthTemplate = new OAuth2RestTemplate(resource, oauth2ClientContext);
    OAuth2AccessTokenSupport authAccessProvider = new AuthorizationCodeAccessTokenProvider();
    // Set request factory for '/oauth/token'
    authAccessProvider.setRequestFactory(requestHelper.getRequestFactory());
    AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(
            (AuthorizationCodeAccessTokenProvider)authAccessProvider));
    oauthTemplate.setAccessTokenProvider(accessTokenProvider);
    // Set request factory for '/userinfo'
    oauthTemplate.setRequestFactory(requestHelper.getRequestFactory());
    oauthFilter.setRestTemplate(oauthTemplate);
    UserInfoTokenServices userInfoTokenService = new UserInfoTokenServices(resourceServer.getUserInfoUri(), resource.getClientId());
    userInfoTokenService.setRestTemplate(oauthTemplate);
    oauthFilter.setTokenServices(userInfoTokenService);
    return oauthFilter;
}

请求帮助程序代码

@Configuration
public class RequestHelper {

  @Value("${proxy.hostname}")
  private String proxyHost;

  @Value("${proxy.port}")
  private int proxyPort;

  @Value("${proxy.username}")
  private String proxyUser;

  @Value("${proxy.password}")
  private String proxyPassword;

  @Value("${useProxy}")
  private boolean useProxyFlag;

  @Value("${skipSslValidation}")
  private Boolean skipSslValidationFlag;

  public HttpComponentsClientHttpRequestFactory getRequestFactory() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {

      HttpClientBuilder httpClientBuilder = HttpClients.custom();

      // Skip SSL validation based on condition
      if (skipSslValidationFlag) {
          TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

          SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                  .loadTrustMaterial(null, acceptingTrustStrategy)
                  .build();
          SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

          httpClientBuilder = httpClientBuilder.setSSLSocketFactory(csf);
      }

      // Set proxy based on condition
      if (useProxyFlag) {
          CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
          credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUser, proxyPassword));
          httpClientBuilder = httpClientBuilder.setProxy(new HttpHost(proxyHost, proxyPort));
          httpClientBuilder = httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
      }

      CloseableHttpClient httpClient = httpClientBuilder.build();
      HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
      requestFactory.setHttpClient(httpClient);
      return requestFactory;
  }
}

0
投票

这似乎是一个更清洁的解决方案:

在使用@Configuration的类中添加:

@Bean
public CustomUserInfoRestTemplateCustomizer customUserInfoRestTemplateCustomizer() {
    return new CustomUserInfoRestTemplateCustomizer();
}

/**
 * Customize the UserInfoRestTemplateCustomizer used by OAuthRestTemplate
 * 
 */
private static class CustomUserInfoRestTemplateCustomizer implements UserInfoRestTemplateCustomizer {
    @Value("${http.custom.connect-timeout:500}")
    private int connectTimeout;

    @Value("${http.custom.read-timeout:30000}")
    private int readTimeout;

    @Value("${http.custom.proxy-host:}")
    private String proxyHost;

    @Value("${http.custom.proxy-port:-1}")
    private int proxyPort;

    @Override
    public void customize(OAuth2RestTemplate template) {
        template.setRequestFactory(new ClientHttpRequestFactory() {
            @Override
            public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
                SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
                clientHttpRequestFactory.setConnectTimeout(connectTimeout);
                clientHttpRequestFactory.setReadTimeout(readTimeout);
                if (StringUtils.isNoneEmpty(proxyHost)) {
                    Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
                    clientHttpRequestFactory.setProxy(proxy);
                }
                return clientHttpRequestFactory.createRequest(uri, httpMethod);
            }
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.