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= .......
This seems to be a cleaner solution:
In a class with @Configuration add this:
@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);
}
});
}
}
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;
}
}
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;
}
}