Why preemptive authentication required ?
System.setProperty("httpclient.authentication.preemptive", "true");
I had written web services access client program in java. Where we were setting username and password in call object and that was working perfectly.
Recently, our service provider made some changes at their side and after that they were not receiving username & password in web service call and as they were not receiving username & passwod so we were not able to connect to their (provider) service.
Then i did googling and found about preemptive authentication.
While calling web services we set "httpclient.authentication.preemptive" as "true" - System.setProperty("httpclient.authentication.preemptive", "true"); , then we are able to receive responses from our service provider.
When we remove System.setProperty("httpclient.authentication.preemptive", "true"); line then we are not able to connect to their services.
When we changed transport pivot="java:org.apache.axis.transport.http.HTTPSender" to transport pivot="java:org.apache.axis.transport.http.CommonsHTTPSender" in client-config.wsdd file. This issue got resolved whithout setting System.setProperty("httpclient.authentication.preemptive", "true"); .
client-config.wsdd -
<?xml version="1.0" encoding="UTF-8"?>
<deployment
name="commonsHTTPConfig"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<!-- use CommonsHTTPSender instead of the default HTTPSender -->
<transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender" />
<transport name="local" pivot = "java:org.apache.axis.transport.local.LocalSender" />
<transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />
</deployment>
Here's how regular authentication works (aka pre-emptive authentication - e.g. how Curl does it):
- User instructs client to make a request to http://user:pass@example.com
- Client makes a request with a header like:
Authorization: Basic dXNlcjpwYXNz
- Server authenticates the user and response with 200
Here's how non-pre-emptive authentication works (e.g. how Apache's HttpClient does it):
- User instructs client to make a request to http://user:pass@example.com
- Client makes a request without authentication
- Server responds with 401 and a header like:
WWW-Authenticate: Basic realm="Default Realm"
- Client makes a second request with a header like:
Authorization: Basic dXNlcjpwYXNz
- Server authenticates the user and response with 200
Why should we use the second method? It ensures that only servers that need authentication get your password. But it does mean that the server has to respond in a correct way (the WWW-Authenticate
header). Perhaps this is what broke in your case, and why you had to override your HTTP Client to force pre-emptive authentication.
(I suggest using Wireshark if you want to get a better idea of what is actually going on between your client and server. And you can read the documentation here for Apache's HTTP Client on this topic: http://hc.apache.org/httpclient-3.x/authentication.html )