简体   繁体   English

使用Jersey Client进行摘要式身份验证

[英]Digest authentication with Jersey Client

I have written a REST web service with Jersey Server (that totally rocks !). 我已经用Jersey Server编写了一个REST Web服务(完全是摇滚!)。 I am now developing the client part of it, with Jersey Client as well. 我现在正在使用Jersey客户端开发它的客户端部分。

On the server side, I have chosen a DIGEST authentication, because I personally think that BASIC authentication is an heresy that should be marked as "DEPRECATED" in our heads. 在服务器端,我选择了DIGEST身份验证,因为我个人认为BASIC身份验证是一种异端,应该在我们的头脑中标记为“已弃用”。

Unfortunately, I do not see any support of the Digest authentication on the client side. 不幸的是,我在客户端看不到任何Digest身份验证的支持。 For BASIC authentication, one does something like : 对于BASIC身份验证,可以执行以下操作:

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

But I see no " HTTPDigestAuthFilter " counterpart. 但我看不到“ HTTPDigestAuthFilter ”对应物。 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 我在Jersey问题跟踪器中创建了一个功能请求,并在那里发布了我的实现,作为附件: https//jersey.dev.java.net/issues/show_bug.cgi?id = 542

It works fine for communicating with a DIGEST authentication of a Tomcat server. 它适用于与Tomcat服务器的DIGEST身份验证进行通信。 I have not tested for other web servers yet. 我还没有测试过其他网络服务器。

Here I wrote some random uri. 在这里,我写了一些随机的uri。 Please fill your desired URI 请填写您想要的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;

    }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM