I am developing a SSL/TLS enabled server using the Java SimpleFramework. I am wondering how to validate client authentications on the server.
On the server side, I am extending org.simpleframework.http.core.ContainerServer and overriding the process() method as follows:
#Override
public void process(Socket socket) throws IOException {
// Ensures client authentication is required
socket.getEngine().setNeedClientAuth(true);
super.process(socket);
}
This is to make sure that clients authenticate. Note that if I remove the call to setNeedClientAuth(), my program works perfectly.
On the client side, the following code is used:
HttpClient client = new HttpClient();
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(AuthScope.ANY, defaultcreds);
GetMethod get = new GetMethod("https://url.to.server");
get.setDoAuthentication(true);
client.executeMethod(get);
When enabling authentication requirement, I get the following exception:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
I am guessing this relates to the fact that the passed credentials is never validated.
To summarize my question, how should I proceed to validate clients on the server?
Related
I've created a SOAP web-service client on Netbeans. The web-service is exposed on Navision with NTML authentication. During class generation, a login pop-up picks the required credentials and uses them for authentication.
The issue is once the classes are generated and I try to invoke any method;
ServicePort webservice_port = new WService().getServicePort();
webservice_port.retrieveData();
I get an exception.
java.io.IOException: Server returned HTTP response code: 401 for URL: ...
Exception in thread "main" com.sun.xml.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:275)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:246)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:209)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:178)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:363)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:321)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:230)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:211)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:207)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:114)
at javax.xml.ws.Service.<init>(Service.java:57)
at com.ntml.remote.MSACCO.<init>(MSACCO.java:42)
Is this an issue with NTLM authentication or is there another way to pass the credentials?
Found a working solution. Injecting an authentication mechanism to the client using the web service port.
Port webservice_port = new Wservice().getServicePort();
Client client = ClientProxy.getClient(webservice_port);
HTTPConduit conduit = (HTTPConduit) client.getConduit();
AuthorizationPolicy authorization = conduit.getAuthorization();
authorization.setUserName(username);
authorization.setPassword(password);
conduit.getClient().setAllowChunking(false);
conduit.getClient().setAutoRedirect(true);
webservice_port.callWebMethod();
I have a stand-alone Java client trying to do RMI through a NTLM proxy.
It's multithreaded.
I'm using Apache httpclient 4.5.6.
I've got the proxy on a 5 minute timeout cycle.
The basic case works, reauthenticating every 5 minutes when challenged by the proxy, as long as 2 threads don't make a request at the same time at exactly the time the proxy times out. Then it fails. Once it fails, all subsequent attempts fail.
I've attached a wireshark screenshot to clarify (screenshot is from 4.5.2 but I upgraded to 4.5.6 and saw the same behavior).
A good cycle looks like
Client tries CONNECT (no NTML flags)
Proxy replies with 407 (no NTML flags)
Client tries CONNECT again with ntlm messagetype NTLMSSP_NEGOTIATE
Proxy replies with 407 NTLMSSP_CHALLENGE
Client does CONNECT with NTLMSSP_AUTH and my credentials.
Proxy replies with 200, and we are good to go for another 5 minutes.
A bad cycle looks like
Client tries CONNECT (no NTML flags)
Proxy replies with 407 (no NTML flags)
Client tries CONNECT again with ntlm messagetype NTLMSSP_NEGOTIATE
Client tries CONNECT (no NTML flags)
Proxy replies with 407 (no NTML flags)
Proxy replies with 407 NTLMSSP_CHALLENGE
A whole bunch more CONNECTs and 407s without NTML flags within a few seconds.
to me this looks like a multithread race condition in non-threadsafe code.
With Apache httpclient 4.5.2 it just propogated the 407 and I detected it in CloseableHttpResponse.getStatusLine().getStatusCode().
With Apache httpclient 4.5.6 I see this
java.lang.IllegalStateException: Auth scheme is null
at org.apache.http.util.Asserts.notNull(Asserts.java:52)
at org.apache.http.impl.auth.HttpAuthenticator.ensureAuthScheme(HttpAuthenticator.java:229)
at org.apache.http.impl.auth.HttpAuthenticator.generateAuthResponse(HttpAuthenticator.java:184)
at org.apache.http.impl.execchain.MainClientExec.createTunnelToTarget(MainClientExec.java:484)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:411)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
Any ideas how to protect against this or work around it or recover from it?
(beside sync on the calls, which would slow down an already slow app a lot)
some code snippets from the app:
// this is done only once
HttpClientBuilder builder = HttpClients.custom();
SocketConfig.Builder socketConfig = SocketConfig.custom();
RequestConfig.Builder requestConfig = RequestConfig.custom();
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
builder.setProxy(proxy);
requestConfig.setProxy(proxy);
builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
String localHost = getLocalHostname();
credentialsProvider.setCredentials(
new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM, "ntlm"),
new NTCredentials(user, password, localHost, domain));
builder.setDefaultCredentialsProvider(credentialsProvider);
builder.setDefaultSocketConfig(socketConfig.build());
builder.setDefaultRequestConfig(requestConfig.build());
CloseableHttpClient client = builder.build();
...
// cached, we use the same one every time in accordance with section 4.7 of
// https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/authentication.html
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsProvider);
...
// new HttpPost every time
HttpPost postMethod = new HttpPost(uri);
postMethod.setEntity(new ByteArrayEntity(bytesOut.toByteArray()));
response = client.execute(postMethod, context);
HttpContext instances are perfectly thread-safe. However some attributes stored in the context such as authentication handshake state are obviously not. Make sure that HttpContext instances do not get updated concurrently and the problem should go away.
Thank you Oleg, this is what I did and it seems to be working so far (too long to post as a comment on your answer, but I wanted to share my code)
// I use the base version when not going through a proxy
public class HttpClientContextFactory {
public HttpClientContext create() {
return HttpClientContext.create();
}
}
// I use this when I go through a NTLM proxy
private HttpClientContextFactory getNtlmContextFactory(
final CredentialsProvider credentialsProvider) {
return new HttpClientContextFactory() {
ThreadLocal<HttpClientContext> tlContext = ThreadLocal
.<HttpClientContext> withInitial(() -> {
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsProvider);
return context;
});
#Override
public HttpClientContext create() {
return tlContext.get();
}
};
}
// then do this when I connect to the server
response = client.execute(postMethod, contextFactory.create());
How do I enable secure connections with CometD?
I have an app that is working when I use an "http" protocol for the BayeuxServer. If I switch to "https", I get failed handshakes.
What is the correct way to use a secure connection in CometD?
This is via the Java Client.
Here is the error:
{failure={exception=java.lang.NullPointerException, message={ext={ack=true}, supportedConnectionTypes=[long-polling], channel=/meta/handshake, id=4, version=1.0}, connectionType=long-polling}, channel=/meta/handshake, id=4, subscription=null, successful=false}
I do not see any exceptions on the server (ie, the null pointer is not in our code), and if I use HTTP, it works fine.
I've pieced together the following for the Java client side:
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true); // only interacting with our backend, so accept self-signed certs
WebSocketClient webSocketClient = new WebSocketClient(sslContextFactory);
webSocketClient.start();
ClientTransport wsTransport = new JettyWebSocketTransport(null, null, webSocketClient);
HttpClient httpClient = new HttpClient(sslContextFactory);
httpClient.start();
ClientTransport httpTransport = new LongPollingTransport(null, httpClient);
I believe that will do it.
I still need to figure out how to configure the server side cometd to accept the secure connections. I am using the Spring setup.
The answer to the server side is: Its a pain in the ass.
Here is how you can get it working with the jetty maven plugin:
http://juplo.de/configure-https-for-jetty-maven-plugin-9-0-x/#comment-53352
I am trying to send a SOAP request over SSL with my own little Java client and it fails with "java.net.ConnectException: Connection refused". The same request sent with SOAPUI does not fail, I get a valid response from the server.
This is the code I am trying to run:
public static void main(String[] args) throws MalformedURLException {
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
SSLUtilities.trustAllHttpsCertificates();
URL wsdlURL = new URL(MY_WSDL_LOCATION);
QName serviceName = new QName(MY_QNAME, NAME_OF_SERVICE);
Service service = Service.create(wsdlURL, serviceName);
Order myOrder = service.getPort(Order.class);
BindingProvider portBP = (BindingProvider) myOrder;
String urlUsed = (String) portBP.getRequestContext().
get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
System.out.println("Using URL: " + urlUsed);
((BindingProvider)myOrder).getRequestContext().put(
BindingProvider.USERNAME_PROPERTY, CORRECT_USERNAME);
((BindingProvider)myOrder).getRequestContext().put(
BindingProvider.PASSWORD_PROPERTY, CORRECT_PASSWORD);
AliveRequest aliveRequest = new AliveRequest();
MerchantInfo merchInfo = new MerchantInfo();
merchInfo.setMerchantId(CORRECT_MERCHANT_ID);
aliveRequest.setMerchantInfo(merchInfo);
AliveResponse aliveResponse = myOrder.alive(aliveRequest);
}
It fails with "java.net.ConnectException: Connection refused" exception. When I build a request from the same WSDL using SOAPUI, populate the same fields with same values and enter the same basic authentication credentials, a valid response is returned.
The problem was the fact that my Java client didn't send the request through the proxy, so my own company's firewall was blocking it. Unlike my own Java client, SOAPUI actually detects the proxy settings of the system (probably reads system environment variables) when SOAPUI's proxy settings are set "auto" (default). The solution was to set the following system properties:
-Dhttps.proxySet=true
-Dhttps.proxyHost=MY_PROXY_HOST
-Dhttps.proxyPort=MY_PROXY_PORT
I am currently working at a web requests project and I am using Apache Http Client library. I try to connect to a server (E.g. http://www.google.com) with an working Socks v4/5 tested with mozilla firefox but the problem is that I never get a response. Only different errors...
Here is a code snippet:
//HttpClient
DefaultHttpClient http = new DefaultHttpClient();
//A class defined by me
Proxy proxy = bla bla;
HttpHost host = new HttpHost(proxy.getIP(), proxy.getPort());
if (proxy.getUsername() != null) {
http.getCredentialsProvider().setCredentials(
new AuthScope(proxy.getIP(), proxy.getPort()),
new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()));
}
http.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, host);
Can anyone tell a proper way to initiate comunnication through SOCKS proxies? Thanks!
Note: The code above works perfect with HTTP proxies.
Http proxy and socks proxy has very different protocols ( http://en.wikipedia.org/wiki/SOCKS#Comparison ).
For your question:
You can do thTis by native java socket ( How can I configure HTTPClient to authenticate against a SOCKS proxy? ) or create your own implementation over DefaultClientConnectionOperator, here is good guide ( http://4devops.blogspot.com/2011/10/httphttps-over-socks-proxy-with-java.html )