HTTPClient 在成功之前获得两个 401(发送错误的令牌) [英] HTTPClient getting two 401s before success (sending wrong token)

查看:36
本文介绍了HTTPClient 在成功之前获得两个 401(发送错误的令牌)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 HttpClient 与自托管的 WebAPI 客户端进行通信.使用以下代码创建客户端:

I'm trying to communicate with a self-hosted WebAPI client using HttpClient. The client is created with the following code:

HttpClientHandler clientHandler = new HttpClientHandler()
{
    UseDefaultCredentials = true,
    PreAuthenticate = true
};
var client = new HttpClient(clientHandler);

在服务器端我们设置:

HttpListener listener = (HttpListener)app.Properties[typeof(HttpListener).FullName];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;

启动文件中.

问题是我在处理请求之前收到两个(或预身份验证后的一个)401 错误.

The problem is that I get two (or one after preauthentication) 401 errors before the request is processed.

在 fiddler 中,序列如下所示:

In fiddler the sequence looks like this:

First request:
Authorization: Negotiate TlRMTVNTUAABAAAAl7II4gcABwAxAAAACQAJACgAAAAGAbEdAAAAD1dTMTEzLTEyMFNXVC0xMTM=
Answer:
WWW-Authenticate: Negotiate TlRMTVNTUAACAAAADgAOADgAAAAVwonisrQOBMTKHhKwCkgCAAAAAJoAmgBGAAAABgGxHQAAAA9TAFcAVAAtADEAMQAzAAIADgBTAFcAVAAtADEAMQAzAAEAEgBXAFMAMQAxADMALQAxADIAMAAEABYAcwB3AHQALQAxADEAMwAuAGwAbwBjAAMAKgBXAFMAMQAxADMALQAxADIAMAAuAHMAdwB0AC0AMQAxADMALgBsAG8AYwAFABYAQQBMAEQASQA5ADkAOQAuAGwAbwBjAAcACACkGh0XVY3QAQAAAAA=

Second request (succeeds):
Authorization: Negotiate TlRMTVNTUAADAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAFcKI4gYBsR0AAAAPfJafWSuLL0sAXYtWCynOqg==

那么为什么我的客户第一次不发送正确的授权令牌,但总是需要这种两次方法?

So why isn't my client sending the correct authorization token the first time around but always needs this two-time approach?

推荐答案

您遇到的情况很正常,这就是 NTLM 身份验证方案的工作原理.

What you are experiencing is normal, this is how the NTLM authentication scheme works.

1: C  --> S   GET ...

2: C <--  S   401 Unauthorized
              WWW-Authenticate: NTLM

3: C  --> S   GET ...
              Authorization: NTLM <base64-encoded type-1-message>

4: C <--  S   401 Unauthorized
              WWW-Authenticate: NTLM <base64-encoded type-2-message>

5: C  --> S   GET ...
              Authorization: NTLM <base64-encoded type-3-message>

6: C <--  S   200 Ok

  1. 客户端向服务器发送 GET 请求.
  2. 由于您需要通过身份验证才能访问所请求的资源,因此服务器会发回 401 Unathorized 响应并在 WWW-Authenticate 标头中通知客户端它支持NTLM 身份验证.所以这是您获得第一个 401 响应代码的地方.
  3. 客户端在Authorization 标头中将域名和用户名发送到服务器.请注意,仅根据这些信息还无法对客户端进行身份验证.
  4. 服务器向客户端发送质询.这是一个随机生成的数字,称为 nonce.这是您获得第二个 401 响应代码的地方.
  5. 客户端发送回对服务器质询的响应,使用其密码的哈希值来加密随机数.
  6. 服务器将客户端的用户名、发送给客户端的质询以及从客户端收到的响应发送到域控制器.域控制器使用用户名检索用户密码的哈希值并用它加密挑战.如果结果与客户端发送的响应匹配,则客户端通过身份验证,服务器向客户端发送回 200 响应代码和请求的资源.
  1. The client sends a GET request to the server.
  2. Since you need to be authenticated to access the requested resource, the server sends back a 401 Unathorized response and notifies the client in the WWW-Authenticate header that it supports NTLM authentication. So this is where you get your first 401 response code.
  3. The client sends the domain name and the username to the server in the Authorization header. Note that based solely on these information the client cannot be authenticated yet.
  4. The server sends a challenge to the client. It's a randomly generated number called a nonce. This is where you get your second 401 response code.
  5. The client sends back a response to the server's challenge, using its password's hash to encrypt the random number.
  6. The server sends the client's username, the challenge sent to the client and the response received from the client to the domain controller. Using the username the domain controller retrieves the hash of the user's password and encrypts the challenge with it. If the result matches the response sent by the client, the client is authenticated and the server sends back a 200 response code and the requested resource to the client.

这篇关于HTTPClient 在成功之前获得两个 401(发送错误的令牌)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆