2010-06-02 15 views
9

J'ai écrit un service web REST avec Jersey Server (ça bombe!). Je suis en train de développer la partie client avec le client de Jersey.Authentification Digest avec Jersey Client

Du côté du serveur, j'ai choisi une authentification DIGEST , parce que je pense personnellement que authentification de base est une hérésie qui devrait être marqué comme « DECONSEILLE » dans nos têtes.

Malheureusement, je ne vois aucun support de l'authentification Digest côté client. Pour authentification de base, on fait quelque chose comme:

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

Mais je vois pas d'équivalent "HTTPDigestAuthFilter". Ai-je raté quelque chose?

Merci pour votre aide,

Raphael

+0

Ok, j'ai demandé sur la liste de diffusion Jersey et il n'existe pas actuellement. Donc je l'implémente. Je l'afficherai dès que je l'aurai fonctionné. –

+0

Veuillez suivre la progression sur le fil correspondant de la liste de diffusion de Jersey, sur Nabble: http://jersey.576304.n2.nabble.com/DIGEST-Authentication-with-Jersey-client-td5132921.html –

+0

Pourquoi * HTTP authentification d'accès de base * être obsolète? – user359996

Répondre

23

Je viennent de réaliser ce. J'ai créé une demande de fonctionnalité dans le suivi de l'émission Jersey, et affiché là ma mise en œuvre, en pièce jointe: https://jersey.dev.java.net/issues/show_bug.cgi?id=542

Il fonctionne très bien pour communiquer avec une authentification DIGEST d'un serveur Tomcat. Je n'ai pas encore testé d'autres serveurs web.

+11

+1 Implémenter vous-même des fonctionnalités manquantes et les libérer. – user359996

+0

Le lien ne fonctionne plus, a-t-il été déplacé? –

0

Ici, j'ai écrit un uri aléatoire. S'il vous plaît remplir votre URI souhaitée

Pour des exemples de test, vous pouvez prendre l'aide de google services qui sont disponibles sur Internet pour ouvrir.

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; 

    } 
    }