可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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. 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; } }
回答2:
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. asList( new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(), clientCredentialsAccessTokenProvider)); restTemplate.setAccessTokenProvider(accessTokenProvider); return restTemplate; } }