I have written a REST web service with Jersey Server (that totally rocks !). I am now developing the client part of it, with Jersey Client as well.
On the server side, I have chosen a DIGEST authentication, because I personally think that BASIC authentication is an heresy that should be ma开发者_如何转开发rked as "DEPRECATED" in our heads.
Unfortunately, I do not see any support of the Digest authentication on the client side. For BASIC authentication, one does something like :
client.addFilter(
new HTTPBasicAuthFilter(
user,
password));
But I see no "HTTPDigestAuthFilter" counterpart. Am I missing something ?
Thanks for your help,
Raphael
I have just implemented it. I have created a feature request in the Jersey issue tracker, and posted my implementation there, as attachment : https://jersey.dev.java.net/issues/show_bug.cgi?id=542
It works fine for communicating with a DIGEST authentication of a Tomcat server. I have not tested for other web servers yet.
Here I wrote some random uri. Please fill your desired URI
For sample testing you can take help of google services which are available in the internet for open.
import javax.ws.rs.core.*;
import org.apache.commons.codec.digest.*;
import org.codehaus.jettison.json.*;
import com.sun.jersey.api.*;
public class DigestClient {
//Dividing into two parts because we need to send the last part of uri in our second request to service.
static String baseUri = "https://www.something.com";
static String subUri = "/later-part";
public static void main(String[] args) throws JSONException{
ClientConfig cc = new DefaultClientConfig();
Client client = Client.create(cc);
WebResource webResource = client.resource(baseUri+subUri);
ClientResponse response = webResource.get(ClientResponse.class);
// Basically in Digest-Authentication mechanism, we hit the rest service two times.
// First time with No Authentication, which returns some values (qop, nonce, realm) which are used as inputs in second call to rest service.
/*--------------- First call-----------------*/
// We get 401, Unauthorized
System.out.println(response.getStatus()+" "+response.getStatusInfo());
// Here is the complete header information
System.out.println(response.getHeaders());
// We need "WWW-Authenticate" part information for our second call to rest
System.out.println("WWW-Authenticate: \t" + response.getHeaders().get("www-Authenticate"));
String noAuthResp = response.getHeaders().get("www-Authenticate").toString();
noAuthResp = noAuthResp.replace("Digest ", "");
noAuthResp = noAuthResp.replace('[', '{');
noAuthResp = noAuthResp.replace(']', '}');
// Creating a JSONObject for easy information retrieval
JSONObject resp = new JSONObject(noAuthResp);
/*--------------- Second call-----------------*/
// Here client has to set the fields which was returned from the first call
String user = "postman"; // username
String password = "password"; // password
String realm = resp.getString("realm"); // realm value from the first rest-call response
String qop = resp.getString("qop"); //qop value from the first rest-call response
String nonce = resp.getString("nonce"); // nonce value from the first rest-call response
String opaque = resp.getString("opaque"); // Some times if we don't get this value, set it with ""
String algorithm = "MD5"; // The algorithm set by the client
int nonceCount = 678; // Some numerical input from the client
String clientNonce = "afdjas0"; // Some random text from the client for encryption
String method = "GET"; // HTTP method
String ha1 = new DigestClient().formHA1(user, realm, password);
String ha2 = new DigestClient().formHA2(method, subUri);
String responseCode = new DigestClient().generateResponse(ha1, nonce, nonceCount, clientNonce, qop, ha2);
// Header to be sent to the service
String value = "Digest username=\""+user+"\", realm=\""+realm+"\", nonce=\""+nonce+"\", uri=\""+subUri+"\", qop="+qop+", nc="+nonceCount+", cnonce=\""+clientNonce+"\", response=\""+responseCode+"\", opaque=\""+opaque+"\"";
// Hitting the service
response = webResource.header("authorization", value).type(MediaType.TEXT_PLAIN).accept("*").get(ClientResponse.class);
System.out.println("\nComplete Response:\n"+response+"\n");
String output = response.getEntity(String.class);
System.out.println("Response Text: "+output);
}
// For generating HA1 value
public String formHA1(String userName,String realm,String password){
String ha1 = DigestUtils.md5Hex(userName + ":" + realm + ":" + password);
return ha1;
}
// For generating HA2 value
public String formHA2(String method,String uri){
String ha2=DigestUtils.md5Hex(method + ":" + uri);
return ha2;
}
// For generating response at client side
public String generateResponse(String ha1,String nonce,int nonceCount,String clientNonce,String qop,String ha2){
String response=DigestUtils.md5Hex(ha1 + ":" + nonce + ":" + nonceCount + ":" +clientNonce +":" + qop + ":" +ha2);
return response;
}
}
精彩评论