How to set proxy on spring oauth2 OAuth2AccessToke

2019-01-26 01:15发布

I have tried to set network proxy in the following ways, but none of the method is working

1: set jvm variables like -Dhttp.proxyHost= -Dhttp.proxyPort= .......
2: Created the 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);
}

But this configuration is overridden by OAuth2AccessTokenSupport.restTemplate.

So the below method always returns the newly created rest template object.

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;
}

Kindly help me to override or set proxy on the rest template from OAuth Client application.

2条回答
淡お忘
2楼-- · 2019-01-26 01:26

Another way to do this is by setting a custom AccessTokenProvider to your OAuth2RestTemplate. In the code sample below the SSL validation is bypassed :

@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;
    }
}
查看更多
乱世女痞
3楼-- · 2019-01-26 01:42

This might not be a simple solution. But finally managed to set the proxy on oauth request by the below code.

Register the filter

@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);
}

Auth filter

@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;
}

Request helper code

@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;
  }
}
查看更多
登录 后发表回答