2010-06-02 37 views
9

Tôi đã viết một dịch vụ web REST với Máy chủ Jersey (hoàn toàn là đá!). Tôi hiện đang phát triển phần khách hàng của nó, với khách hàng Jersey là tốt.Xác thực thông báo với Khách hàng Jersey

Về phía server, tôi đã chọn một DIGEST xác thực, bởi vì cá nhân tôi nghĩ rằng BASIC xác thực là một dị giáo đó phải được đánh dấu là "DEPRECATED" trong đầu của chúng tôi.

Thật không may, tôi không thấy bất kỳ hỗ trợ nào của xác thực Digest ở phía máy khách. Đối BASIC xác thực, một điều gì đó như:

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

Nhưng tôi thấy không có "HTTPDigestAuthFilter" đối tác. Tôi có thiếu gì đó không?

Nhờ sự giúp đỡ của bạn,

Raphael

+0

Ok, tôi đã yêu cầu danh sách gửi thư của Jersey và hiện tại nó không tồn tại. Vì vậy, tôi đang triển khai nó. Tôi sẽ đăng nó ở đó ngay khi tôi làm việc. –

+0

Vui lòng thực hiện theo tiến trình trên chuỗi tương ứng của danh sách gửi thư của Jersey, trên Nabble: http://jersey.576304.n2.nabble.com/DIGEST-Authentication-with-Jersey-client-td5132921.html –

+0

Tại sao nên * HTTP xác thực truy cập cơ bản * không được chấp nhận? – user359996

Trả lời

23

Tôi vừa thực hiện nó. tôi đã tạo ra một yêu cầu tính năng trong theo dõi vấn đề Jersey, và được đăng thực hiện của tôi ở đó, như tập tin đính kèm: https://jersey.dev.java.net/issues/show_bug.cgi?id=542

Nó hoạt động tốt để giao tiếp với một xác thực DIGEST của máy chủ Tomcat. Tôi chưa thử nghiệm cho các máy chủ web khác.

+11

+1 Tự mình thực hiện chức năng thiếu và phát hành nó. – user359996

+0

liên kết không hoạt động nữa, đã di chuyển chưa? –

0

Ở đây tôi đã viết một số uri ngẫu nhiên. Vui lòng điền vào URI

URI mong muốn của bạn để thử nghiệm mẫu, bạn có thể nhận trợ giúp về các dịch vụ của google có sẵn trên internet để mở.

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; 

    } 
    } 
Các vấn đề liên quan