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.
In general, preemptive authentication means that the server expects that the authorization credentials will be sent without providing the Unauthorized response. This reduces the load on network and the server itself. You can configure your requests to use or omit the preemptive authentication.
Preemptive Authentication. As we've seen on a previous post on Spring Security authentication, a server might use a challenge-response mechanism to indicate explicitly when the consumer needs authenticate to access the resource. By default, REST Assured waits for the server to challenge before sending the credentials.
Basic Authentication is a method for an HTTP user agent (e.g., a web browser) to provide a username and password when making a request. When employing Basic Authentication, users include an encoded string in the Authorization header of each request they make.
Digest authentication is another authentication type specified in HTTP 1.1. Unlike basic authentication, digest authentication does not require the password to be transmitted. Rather, the client takes the username and password and uses the MD5 hashing algorithm to create a hash, which is then sent to the SQL Server.
Here's how regular authentication works (aka pre-emptive authentication - e.g. how Curl does it):
Authorization: Basic dXNlcjpwYXNz
Here's how non-pre-emptive authentication works (e.g. how Apache's HttpClient does it):
WWW-Authenticate: Basic realm="Default Realm"
Authorization: Basic dXNlcjpwYXNz
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 )
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With