The connection to a proxy trough my code always able to connect even when wrong/no credentials are given. When I connect to the same server trough curl 407 error is given when it supposed to.
What am I doing wrong?
Code -
if (proxyProperties != null && proxyProperties.isUseProxy()) {
final String proxyHost = proxyProperties.getHost();
final Integer proxyPort = proxyProperties.getPort();
final HttpHost proxyHttpHost = new HttpHost(proxyHost, proxyPort);
clientBuilder.setProxy(proxyHttpHost);
asyncClientBuilder.setProxy(proxyHttpHost);
logger.info("Proxy connection configured, proxy host: {}", proxyHttpHost);
if (proxyProperties.isUseProxyAuthentication() && !StringUtils.isEmpty(proxyProperties.getUser())) {
final CredentialsProvider credentialsProvider = getProxyAuthenticator(proxyProperties, logger);
clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
asyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}
Related
Hi I got proxy 407 authentication error in my spring boot project.I tried two scenario in these scenarios proxyHost and proxyPort values are working but username and password has no effect?Is any one face this scenario?In my local machine when I give port and host and giving no username password,it works my local user and work,but I give username and password in wrong format to see its effect?I doesnt effect.
Also in server I got 407 authentication proxy exception.How can pass proxy username and password in spring boot?thanks
I add jvm parameters but proxyuser and proxyPassword no effect
-Dhttps.proxyHost=something -Dhttps.proxyPort=5555-Dhttps.proxyUser=xxx -Dhttps.proxyPassword=yyy
I also add someproxy code to myresttemplate builder but it has no effect.
RestTemplate restTemplate=new RestTemplateBuilder()
.build();
int proxyPortNum =5555;
String proxyHost="something";
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxyHost, proxyPortNum), new UsernamePasswordCredentials("myname", "333"));
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost(proxyHost, proxyPortNum));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CloseableHttpClient client = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
restTemplate.setRequestFactory(factory);
you should try something like this:-----
private RestTemplate createRestTemplate() throws Exception {
final String username = "myname";
final String password = "333";
final String proxyUrl = "something";
final int port = 5555;
HttpHost myProxy = new HttpHost(proxyUrl, port);
HttpClientBuilder clientBuilder = HttpClients.custom();
List<Header> headers = new ArrayList<>();
BasicHeader authHeader = new BasicHeader("Authorization",base64authUserPassword());
headers.add(authHeader);
RequestDefaultHeaders reqHeader = new RequestDefaultHeaders(headers);
clientBuilder.addInterceptorLast(reqHeader);
clientBuilder.setProxy(myProxy).disableCookieManagement();
HttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient);
return new RestTemplate(factory);
}
public String base64authUserPassword() {
byte[] baseencode = Base64.getEncoder().encode((username + ":" + password).getBytes());
return "Basic " + new String(baseencode);
}
Hope it will resolve your issue.
Getting error while calling a api in production but works in local.
Used same proxy as in local 10.235.88.30 and port 8080
calling through jersey client:-
com.sun.jersey.api.client.Client client = new Client(
new URLConnectionClientHandler(new HttpURLConnectionFactory() {
#Override
public HttpURLConnection getHttpURLConnection(final URL url) throws IOException {
Proxy proxy;
proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("10.235.88.30", 8080));
return (HttpURLConnection) url.openConnection(proxy);
}
}), new DefaultClientConfig());
Should return response but getting proxy error.
com.sun.jersey.api.client.ClientHandlerException: java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authorization Required"
I am using the OkHttp library to make requests from my application to facebook api, however I need to work on a proxy network, instantiating OkHttpClient() and calling OkHttpClient.newCall(request).execute() I get a timeout message because my proxy stop the request.
After a little research I found the following solution:
int proxyPort = 8080;
String proxyHost = "proxyHost";
final String username = "username";
final String password = "password";
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();
}
};
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.proxyAuthenticator(proxyAuthenticator)
.build();
This works great, however I would not want to leave the proxy information in the code or in the application.
Is there any way to configure the proxy as environment variable or in some external file where OkHttp would be able to complete the requests?
I would use system environment variables for storing this sensitive configuration. If you do not have property file, system variable would be good option.
You can update you authenticate method to this:
Authenticator proxyAuthenticator = new Authenticator() {
#Override public Request authenticate(Route route, Response response) throws
IOException {
String username = System.getenv("PROXY_USERNAME");
String password = System.getenv("PROXY_PASSWORD");
if (username == null || username.isEmpty() || password == null || password.isEmpty() )
throw new IllegalStateException("Proxy information is not defined in system variables");
String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
and remove
final String username = "username";
final String password = "password";
class fields.
Now when you run your application you can define the variables on the computer itself or better to pass them as parameters to you java application. For instance:
java -jar -DPROXY_USERNAME=userName -DPROXY_PASSWORD=password yourJar.jar
How can I use Socks5 proxy in Okhttp to start http request ?
My code:
Proxy proxy = new Proxy(Proxy.Type.SOCKS, InetSocketAddress.createUnresolved(
"socks5host", 80));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy).authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
if (HttpUtils.responseCount(response) >= 3) {
return null;
}
String credential = Credentials.basic("user", "psw");
if (credential.equals(response.request().header("Authorization"))) {
return null; // If we already failed with these credentials, don't retry.
}
return response.request().newBuilder().header("Authorization", credential).build();
}
}).build();
Request request = new Request.Builder().url("http://google.com").get().build();
Response response = client.newCall(request).execute(); <--- **Here, always throw java.net.UnknownHostException: Host is unresolved: google.com**
System.out.println(response.body().string());
How to avoid UnknownHostException?
Any example ?
Thanks!
I found a solution: When create a OkHttpClient.Builder(), set a new socketFactory instead of set proxy, and return a sock5 proxy inside socketFactory createSocket.
I think it's the easiest working soulution. But it seems to me that it can be not 100% safe. I took this code from this code from here and modified it because my proxy's RequestorType is SERVER.
Actually, java has a strange api for proxies, you should to set auth for proxy through system env ( you can see it from the same link)
final int proxyPort = 1080; //your proxy port
final String proxyHost = "your proxy host";
final String username = "proxy username";
final String password = "proxy password";
InetSocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr);
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestingHost().equalsIgnoreCase(proxyHost)) {
if (proxyPort == getRequestingPort()) {
return new PasswordAuthentication(username, password.toCharArray());
}
}
return null;
}
});
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.build();
I configure HttpsUrlConnection like this:
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);
HttpsURLConnection.setDefaultHostnameVerifier(new DummyHostnameVerifier());
DummyHostnameVerifier:
public class DummyHostnameVerifier implements HostnameVerifier {
#Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
Of course, it's only part of configuration. But the problem is that verify method in DummyHostnameVerifier isn't invoked.
When I test my application on local machine, glassfish 3 server, verify invoked and I'm not recieving any exceptions.
But when I test it on remote environment, verify isn't invoked, and I recieve this:
java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate. To disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
On remote env app runs on jboss 5.
Maybe this depends on some jboss config? I can't understand, where default hostname verifier changed after setting my verifier.
I think if you want to by pass the certificateValidation you would need to create Trustmanager which will not go for certificate validation
HttpsURLConnection.setDefaultHostnameVerifier(new DummyHostnameVerifier());
// Create a TrustManager which wont validate certificate chains start
javax.net.ssl.TrustManager[] trustAllCertificates = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCertificates[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCertificates, null);
// Create a TrustManager which wont validate certificate chains end
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);
Could you please try with above code and let me know if you get the resolution ?
The problem was in following: somehow there wasn't action name in message to server.
I configured connection like this:
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);
HttpsURLConnection.setDefaultHostnameVerifier(new DummyHostnameVerifier());
URL url = null;
try {
url = new URL(endpoint + "/wsdl");
} catch (MalformedURLException e) {
LOG.error(e.getMessage());
}
javax.xml.ws.Service s = MyService.create(url, new QName(MyService.NAMESPACE, MyService.SERVICE));
ServiceSoap port = s.getPort(ServiceSoap.class);
Map<String, Object> reqCtx = ((BindingProvider)port).getRequestContext();
reqCtx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
reqCtx.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
reqCtx.put(BindingProvider.SOAPACTION_URI_PROPERTY, actionName);
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnection(ConnectionType.CLOSE);
http.setClient(httpClientPolicy);
TLSClientParameters tls = new TLSClientParameters();
tls.setSSLSocketFactory(sslFactory);
tls.setDisableCNCheck(true);
http.setTlsClientParameters(tls);
So, port configured and everything began to work.