Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Digest authentication possible with jQuery?

I'm trying to send a request that requires HTTP Digest authentication.

Is Digest possible in jQuery?

If so, is this close to the correct way to do it? It's not currently working.

<script type="text/javascript">     $.ajax({         url: url,         type: 'GET',         dataType: 'json',         success: function() { alert('hello!'); },         error: function() { alert('error')},         beforeSend: setHeader      });      function setHeader(xhr){         xhr.setRequestHeader("Authorization", "Digest username:password");         xhr.setRequestHeader("Accept", "application/json");     } </script> 
like image 893
Mitciv Avatar asked Mar 13 '11 07:03

Mitciv


People also ask

Should I use Digest authentication?

Something you should NEVER EVER use. Doesn't protect the password in transit and requires the server to store passwords in plain. Digest does provide better in-transit security than Basic authentication for unencrypted traffic, but it's weak.

How secure is Digest authentication?

Digest authentication is secure due to the way it passes authentication information over the network. Usernames and passwords are never sent. Instead, IIS uses a message digest (or hash) to verify the user's credentials.

How does HTTP digest authentication work?

Specifically, digest access authentication uses the HTTP protocol, applying MD5 cryptographic hashing and a nonce value to prevent replay attacks. Hash values are affixed to the person's username and password before they are sent over the network, enabling the provider's server to authenticate the person.


2 Answers

No, the Digest Access Authentication Scheme is a little more complex as it implements a challenge-response authentication mechanism that requires the following steps:

  1. client sends a request for an access-protected resource, but an acceptable Authorization header field is not sent
  2. server responds with a "401 Unauthorized" status code and a WWW-Authenticate header field (the digest-challenge)
  3. client sends another request for the same resource but containing a Authorization header field in response to the challenge (the digest-response)
  4. if the authorization is not successful, go to step 2; otherwise the server proceeds as normal.

This means there are at least two request/response pairs.

Each WWW-Authenticate response header field has the syntax:

challenge        =  "Digest" digest-challenge digest-challenge  = 1#( realm | [ domain ] | nonce |                     [ opaque ] |[ stale ] | [ algorithm ] |                     [ qop-options ] | [auth-param] ) 

So you need to parse the digest-challenge to get the parameters to be able to generate a digest-reponse for the Authorization request header field with the following syntax:

credentials      = "Digest" digest-response digest-response  = 1#( username | realm | nonce | digest-uri                 | response | [ algorithm ] | [cnonce] |                 [opaque] | [message-qop] |                     [nonce-count]  | [auth-param] ) 

That section does also describe how the digest-response parameters are calculated. In particular, you will probably need an MD5 implementation as that’s the most commonly used algorithm for this authentication scheme.

Here is a simple tokenization that you can start with:

var ws = '(?:(?:\\r\\n)?[ \\t])+',     token = '(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2E\\x30-\\x39\\x3F\\x41-\\x5A\\x5E-\\x7A\\x7C\\x7E]+)',     quotedString = '"(?:[\\x00-\\x0B\\x0D-\\x21\\x23-\\x5B\\\\x5D-\\x7F]|'+ws+'|\\\\[\\x00-\\x7F])*"',     tokenizer = RegExp(token+'(?:=(?:'+quotedString+'|'+token+'))?', 'g'); var tokens = xhr.getResponseHeader("WWW-Authentication").match(tokenizer); 

This will turn a WWW-Authenticate header field like:

WWW-Authenticate: Digest         realm="[email protected]",         qop="auth,auth-int",         nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",         opaque="5ccc069c403ebaf9f0171e9517f40e41" 

into:

['Digest', 'realm="[email protected]"', 'qop="auth,auth-int"', 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"', 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'] 

Then you need to parse the parameters (check existence and validity) and extract the values. Note that quoted-string values can be folded, so you need to unfold them (see also the use of the unquote function unq in the RFC):

function unq(quotedString) {     return quotedString.substr(1, quotedString.length-2).replace(/(?:(?:\r\n)?[ \t])+/g, " "); } 

With this you should be able to implement that on your own.

like image 108
Gumbo Avatar answered Sep 26 '22 12:09

Gumbo


It is possible with vanilla javascript. Try digestAuthRequest.js:

https://github.com/inorganik/digest-auth-request

like image 42
inorganik Avatar answered Sep 22 '22 12:09

inorganik