使用jQuery可以进行摘要式身份验证吗?
收藏

我正在尝试发送需要HTTP Digest身份验证的请求。

可以在jQuery中进行摘要吗?

如果是这样,这是否接近正确的方法?目前无法使用。

<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>

最佳答案

否,摘要式访问身份验证方案要复杂一些,因为它实现了质询-响应身份验证机制,该机制需要以下步骤:

  1. 客户端发送对受访问保护的资源的请求,但未发送可接受的Authorization标头字段
  2. 服务器以“ 401未经授权”状态代码和WWW-Authenticate标头字段作为响应(摘要挑战)
  3. 客户端发送另一个对相同资源的请求,但其中包含一个Authorization标头字段以响应质询(摘要响应)
  4. 如果授权不成功,请执行步骤2;否则,服务器将继续正常运行。

这意味着至少有两个请求/响应对。

每个WWW-Authenticate响应标头字段均具有以下语法:

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

因此,您需要解析摘要挑战以获取能够使用以下语法为“授权请求”标头字段生成摘要响应的参数:

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

该部分还描述了摘要响应参数的计算方式。特别是,您可能需要MD5实现,因为这是此身份验证方案最常用的算法。

您可以从以下简单的令牌化开始:

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);

这将使WWW-Authenticate标头字段变为:

WWW-Authenticate: Digest
        realm="testrealm@host.com",
        qop="auth,auth-int",
        nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
        opaque="5ccc069c403ebaf9f0171e9517f40e41"

变成:

['Digest', 'realm="testrealm@host.com"', '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, " ");
}

有了这个,您应该能够自己实现。

    公众号
    关注公众号订阅更多技术干货!