Дайджест-аутентификация с помощью Jersey Client - PullRequest
9 голосов
/ 02 июня 2010

Я написал веб-сервис REST с Jersey Server (это просто потрясающе!). Сейчас я разрабатываю клиентскую часть, в том числе и с Jersey Client.

На стороне сервера я выбрал DIGEST аутентификацию, потому что лично я считаю, что BASIC аутентификация - это ересь, которую в наших головах следует пометить как "УСТАРЕВШИЙ". 1009 *

К сожалению, я не вижу поддержки дайджест-аутентификации на стороне клиента. Для BASIC аутентификации можно сделать что-то вроде:

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

Но я не вижу " HTTPDigestAuthFilter " аналога. Я что-то упустил?

Спасибо за помощь,

Raphael

Ответы [ 2 ]

23 голосов
/ 25 июня 2010

Я только что реализовал это. Я создал запрос функции в системе отслеживания проблем Джерси и разместил там свою реализацию в виде приложения: https://jersey.dev.java.net/issues/show_bug.cgi?id=542

Отлично работает для связи с DIGEST-аутентификацией сервера Tomcat. Я еще не тестировал другие веб-серверы.

0 голосов
/ 05 января 2017

Здесь я написал несколько случайных URI. Пожалуйста, заполните желаемый URI

В качестве примера тестирования вы можете воспользоваться услугами Google, которые доступны в Интернете для открытого доступа.

    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;

    }
    }
...