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>
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.
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.
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.
No, the Digest Access Authentication Scheme is a little more complex as it implements a challenge-response authentication mechanism that requires the following steps:
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.
It is possible with vanilla javascript. Try digestAuthRequest.js:
https://github.com/inorganik/digest-auth-request
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With