We are using spring-security-saml for our SAML authentication. The app is working fine and when we try to run the app on demo machine, the connection to SAML metadata url is timing out.
we have given the metadata url in our application.yml as
security:
saml2:
metadata-url: https://dev-715244.oktapreview.com/app/<app_id>/sso/saml/metadata
Tried setting the proxy to the jvm while running the jar but same issue is there. But this URL is reachable through CURL.
Any idea as to how to set proxy details to the HTTP Client used by spring SAML?
Yes, you need to create a bean as follows to your WebSecurityConfig:
#Bean
public HttpClient httpClient() {
HttpClient client = new HttpClient(this.multiThreadedHttpConnectionManager);
HostConfiguration hostConfiguration = new HostConfiguration();
hostConfiguration.setProxy("PROXYHOST", PROXYPORT);
client.setHostConfiguration(hostConfiguration);
return client;
}
Related
All the connections from my spring boot application which connect to an external service must be routed through a proxy.
I am using Squidmen for mocking a local proxy with provided services for 127.0.0.1 on port 3333.
To test if the proxy is working, I can make the following request and see the request in the Squidmen access logs.
curl -x http://127.0.0.1:3333 -L http://google.ch
I found this similar issue to configure my spring boot application. So I'm setting my environment variables as follows:
http.proxyHost=127.0.0.1
http.proxyPort=3333
http.proxySet=true
https.proxyHost=127.0.0.1
https.proxyPort=3333
https.proxySet=true
server.use-forwarded-headers=true
Analog to my curl request, this is my java request:
URL url = new URL("https://google.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
System.out.println(con.getResponseCode());
System.out.println(con.getHeaderField("Content-Type"));
However, with the specified configuration the request is not forward to the proxy. How can I make sure that these kind of request to external serivces are routed through the proxy.
We built a Java client application connecting to an API behind a proxy that demands NTLM authentication. The application uses a Jetty HttpClient.
Unfortunately the authentication fails with a 407
Response headers HttpResponse[HTTP/1.1 407 Proxy Authorization Required]#3577846e
Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
We tried to authenticate using the SPNEGOAuthentication-class
AuthenticationStore authStore = httpClient.getAuthenticationStore();
SPNEGOAuthentication auth = new SPNEGOAuthentication(proxyUrl);
auth.setUserName(user);
auth.setUserPassword(password);
authStore.addAuthentication(auth);
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy(proxyUrl.getHost(), proxyUrl.getPort());
proxyConfig.getProxies().add(proxy);
But without success (407). We also tried overwriting the DefaultAuthenticator.
Any hints what we probably did wrong or other suggestions?
Regards and thanks in advance,
Thomas
I wrote Java code to login to Salesforce and ran this code on a firewalled server. For this, I have to specify the proxy url and proxy port before connecting to Salesforce due to the firewall. However, I'm getting an unknownhostexception error for the proxy url. If I try to login via curl with the proxy settings, I am able to connect. How come there is a problem connecting using Java then? Any help is appreciated.
Apparently the issue was caused by JVM configs. We have to configure JVM to use the proxy settings as follows:
System.setProperty("http.proxyHost", crmProxyURL);
System.setProperty("http.proxyPort", crmProxyPort);
Depending on your HTTP library the System settings might not be enough or not needed. In the Salesforce context it is quite possible that one would try using the Jetty HTTP Client. In this case the System properties are ignored and proxy needs to be handled by the Jetty client:
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy("proxyHost", proxyPort);
proxyConfig.getProxies().add(proxy);
The Apache HTTP Client, another popular choice, also uses its own little mechanism:
HttpHost proxy = new HttpHost("proxyHost", proxyPort, "https");
RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
HttpGet request = new HttpGet(someURL);
request.setConfig(config);
Interesting here: one can specify to use http or https as the proxy protocol.
In general I found using one of the http client much easier that the JDK low level functions.
I was using Jersey 2.25 client with Jackson, I configured everything correctly in Jersey, it worked normally on my development machine when I ran it in a test class, but Jersey client could never connect to a certain host that we have when deployed on our STG environment and always throws a read timeout exception.
I also know that the problem is not in our environment because I can connect using curl
But when switched to HTTPClient it worked normally.
This is how we created our Jersey Client:
Client client = ClientBuilder.newBuilder()
.register(JacksonFeature.class)
.property(ClientProperties.CONNECT_TIMEOUT,5000)
.property(ClientProperties.READ_TIMEOUT,15000)
.build();
The only difference here is the flow of the app, and also the major change that happens in the flow that could affect the connection is that somewhere before calling the Jersey client another class sets a proxy in the system config:
System.setProperty("http.proxyHost",strProxyHost);
System.setProperty("http.proxyPort",strProxyPort);
System.setProperty("https.proxyHost",strProxyHost);
System.setProperty("https.proxyPort",strProxyPort);
However we can establish a connection normally using HTTPClient:
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setConnectionTimeout(5000);
params.setSoTimeout(10000);
HttpConnectionManager manager = new SimpleHttpConnectionManager();
manager.setParams(params);
HttpClient httpClient = new HttpClient(manager);
We are using HTTPClient 3 because part of this app is legacy and we cannot update the version, but it works normally.
What could be causing this connection problem with Jersey? is there something global that Jersey reads when it's trying to connect?
Jersey by default uses HttpURLConnection and HttpURLConnection uses following global settings for proxy configuration -
System.setProperty("http.proxyHost",strProxyHost);
System.setProperty("http.proxyPort",strProxyPort);
System.setProperty("https.proxyHost",strProxyHost);
System.setProperty("https.proxyPort",strProxyPort);
It means if these system variables are set, Jersey will send all the requests through this configured proxy. Check Details here
However, Apache HttpClient does not follow these settings. For using proxy in Apache HttpClient, you have to use HostConfiguration class. Check details here
So, now to your problem, It looks that your STG environment is not able to connect to specified proxy but able to connect with the service directly.
So, while using Jersey, client is not able to connect to proxy and hence ReadTimeoutException is occurring. Since, you haven't configured HttpClient for using any proxy, it is able to connect with the service directly.
Our environment just allows HTTPS connections so they provide us an HTTPS proxy which is the only way of connecting to the outside world. We have to route all traffics through this proxy as well as our Java application (a which uses OkHttp as its HTTP client.
We've setup the proxy like this:
Authenticator proxyAuthenticator = new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
return builder
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.proxyAuthenticator(proxyAuthenticator)
.build();
And we tested it using squid (as HTTP proxy). But we found out that this doesn't work in the real environment. as the proxy is HTTPS (SSL or TLS tunnelling?) not HTTP.
We could force all other Linux applications like wget to use the https proxy by setting the following environment variable:
export https_proxy='http://domain\user:password#prox-server:port'
But the Java application doesn't work and can't route traffics using this proxy.
BTW we couldn't config JVM to route all traffics through proxy by setting system properties http.proxyHost, http.proxyPort, https.proxyHost, https.proxyPort etc.
Is there any simple and straightforward way to set HTTPS proxy for a Java application?
For HTTPS you need to use https.proxyHost and https.proxyPort
https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html