2010-06-02 7 views
9

Ich habe eine REST Web-Service mit Jersey Server geschrieben (das total rockt!). Ich entwickle jetzt den Client Teil davon, mit Jersey Client auch.Digest Authentifizierung mit Jersey Client

Auf der Serverseite habe ich eine DIGEST Authentifizierung gewählt, weil ich persönlich denke, dass BASIC Authentifizierung eine Häresie ist, die als „deprecated“ in unseren Köpfen markiert werden sollen.

Leider sehe ich keine Unterstützung der Digest-Authentifizierung auf der Client-Seite. Für BASIC Authentifizierung, macht man so etwas wie:

client.addFilter(
    new HTTPBasicAuthFilter(
     user, 
     password)); 

Aber ich sehe keinen "HTTPDigestAuthFilter" Pendant. Fehle ich etwas?

Danke für Ihre Hilfe,

Raphael

+0

Ok, ich habe auf der Jersey Mailingliste gefragt und es existiert derzeit nicht. Also ich implementiere es. Ich poste es dort, sobald ich es funktioniere. –

+0

Bitte folgen Sie den Fortschritt auf dem entsprechenden Thread von Jersey Mailingliste, auf Nabble: http://jersey.576304.n2.nabble.com/DIGEST-Authentication-with-Jersey-client-td5132921.html –

+0

Warum sollte * HTTP Basic Access Authentication * veraltet sein? – user359996

Antwort

23

Ich habe es gerade umgesetzt. Ich habe eine Feature-Anfrage in der Jersey issue tracker erstellt, und habe meine Implementierung dort als Anhang: https://jersey.dev.java.net/issues/show_bug.cgi?id=542

Es funktioniert gut für eine DIGEST Authentifizierung eines Tomcat-Server zu kommunizieren. Ich habe noch nicht für andere Webserver getestet.

+11

+1 Implementieren Sie fehlende Funktionalität selbst und veröffentlichen Sie sie. – user359996

+0

Link funktioniert nicht mehr, wurde verschoben? –

0

Hier schrieb ich einige zufällige uri. Bitte füllen Sie Ihre gewünschte URI

Für Beispieltests können Sie Hilfe von Google-Diensten nehmen, die im Internet für geöffnet verfügbar sind.

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; 

    } 
    } 
Verwandte Themen