Forum Discussion

asherhancong's avatar
asherhancong
New Contributor
8 years ago

Retrieve HTTP Digest Data from WWW-Authenticate header in 401 Response from Server

Hi Everyone,

 

I'm trying to build a test case to test HTTP digest authentication. The basic idea is to send an HTTP GET request without Authorization header first and calculate the digest response from the digest data in WWW-Authenticate header in 401 Response from Server then send the request with Authorization Header to server again.

 

When I send the request, the server replies with 401 with all digest data in WWW-Authenticate header. I followed blogs about HTTP digest in SmartBear Community to build Groovy script to calculate digest response but it failed.

 

It would be very appreciated if you could share your experience or instructions to retrieve the digest data from the WWW-Authenticate header. My project and Wireshark trace are both attached.

 

Thx a lot.

 

BRs//Asher

  • PaulMS's avatar
    PaulMS
    Super Contributor

    Based on some stackoverflow answers a possible solution is splitting the WWW-Authenticate header by comma, then put each key value pair in a map collection.

     

    https://stackoverflow.com/questions/45361721/groovy-digest-authentication

    https://stackoverflow.com/questions/1757065/java-splitting-a-comma-separated-string-but-ignoring-commas-in-quotes

     

    See if this groovy script sets the property values that you want. 

     

    import org.apache.commons.codec.digest.DigestUtils
    
    def user = "sip:381117508016@ims.telekomsrbija.com";
    def pass = "bzlops16";
    def request = testRunner.testCase.testSteps["HTTP_Get_FirstHit"].testRequest;
    def headerauth = request.response.responseHeaders["WWW-Authenticate"][0];
    
    def values = headerauth.split(',(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)', 0);
    def map = [:];
    values.eachWithIndex {it, index ->
    	def pair = values[index].tokenize('=')
    	map.put(pair[0].trim(), pair[1].trim().replace('"',''))
    }
    
    def realm = map["Digest realm"];
    def qop = map["qop"];
    def nonce = map["nonce"];
    def opaque = map["opaque"];
    
    def method = request.getMethod()
    def uri = request.getEndpoint();
    def response = md5(user, realm, pass, method, uri, nonce);
    log.info response
    
    def md5(user, realm, pass, method, String uri, nonce) {
    def A1 = DigestUtils.md5Hex ("$user:$realm:$pass")
    def A2 = DigestUtils.md5Hex ("$method:$uri")
    DigestUtils.md5Hex ("$A1:$nonce:$A2")
    }
    
    def init = testRunner.testCase.getTestStepByName( "Properties" );
     init.setPropertyValue( "realm", realm);
     init.setPropertyValue( "nonce", nonce);
     init.setPropertyValue( "opaque", opaque);
     init.setPropertyValue( "response", response);
     init.setPropertyValue( "uri", uri);

     

      • PaulMS's avatar
        PaulMS
        Super Contributor

        A couple of things to add.

         

        One property value was missing in the groovy script

        init.setPropertyValue( "qop", qop);

         

        Close bracket was missing after ${Properties#opaque" in the request Authorization header

        The request Raw tab is an easy way to check the header to see if anything is missing