针对 Web API 的 HttpClient 基本身份验证失败,而浏览器按预期工作

HttpClient basic authentication against Web API fails, while browser works as expected

我正在测试我自己的 Web API 服务,并且在添加

[Authorize(Roles = "MyRole")]

到控制器,HttpClient 发出的所有请求都失败并显示 "Unauthorized" (401)。服务托管在启用了 Windows 身份验证的 IIS Express 中,如建议 here.

客户端发送适当的请求header:

var authHeaderParameter = Convert.ToBase64String(Encoding.ASCII.GetBytes("MyUser:MyPassword"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authHeaderParameter);

从浏览器发出的相同请求(至少,相同的 URI 和凭据)按预期工作并且 returns 数据。 Fiddler 显示,浏览器发送 "Proxy-Authorization" 请求 header,但不发送任何 "Authorization".

我做错了什么? 如何使用 HttpClient?

修复请求

UPD.

这也没有帮助:

var handler = new HttpClientHandler
{
    UseProxy = false
};

var client = new HttpClient(handler, true)
{
    BaseAddress = new Uri(baseAddress)
};

我会 post 发表评论,但我的声誉太低了,过去我遇到过这个问题,当服务器发回 http 重定向并且 http 库自动发回我的请求时没有自定义header 数据。我认为如果发生这种情况,请求或响应 object 将有一个 uri 字段,您也可以禁用自动重定向处理。我最终使用 wire shark 解决了所有这些问题,我强烈建议你接下来这样做。

嗯,问题出在 IIS Express 设置中。
我将post这个答案并将"VS 2015"标签添加到问题中,因为它可能会有帮助。

感谢@swiley,WireShark and npcap(最后需要通过 WireShark 捕获环回接口流量)。

检查发送到网络浏览器的响应 headers,我发现 401 响应包含 Autorization: NTLM headers。由于浏览器会自动处理这种情况,因此它会在进一步的请求中发送当前的 NTLM 凭据并获取请求的数据。我的 HttpClient 代码没有,而且实际上不能处理 NTLM.

先决条件。

首先,这是 VS 2015,我的 Web API 项目使用 IIS Express 进行托管,这是默认设置。 Non-default 这里是我已经将端口更改为常量值:

其次,IIS express in VS 2015 将其配置存储在%SolutionDir%\.vs\config\applicationhost.config 文件中。请注意,这与以前的版本不同。

第三个。 按 F4 键可用的项目属性非常有限,实际上,您只是修改上面的相同 applicationhost.config

第四个,thispost没有帮助:

To enable Basic authentication using IIS, set the authentication mode to "Windows" in the Web.config of your ASP.NET project:

虽然这适用于 "mature" IIS,但 Visual Studio + IIS express 忽略这些设置。

解决方法。

  1. 在文本编辑器中打开 %SolutionDir%\.vs\config\applicationhost.config
  2. 找到第一个 <authentication> 标签。
  3. 在其下找到<basicAuthentication enabled="false" />,将enabled改为true
  4. 保存文件。
  5. 重新启动 Web 应用程序。

请注意,您可以通过按 F4 查看的属性存储在 <location path="YourProjectName"> 标签下。

默认情况下,它有 sub-tag authentication,但没有 basicAuthentication:

<authentication>
    <windowsAuthentication enabled="false" />
    <anonymousAuthentication enabled="false" />
</authentication>

如果解决方案有多个具有自定义身份验证设置的 IIS Express-hosted 项目,应将 basicAuthentication 添加到 project-related 部分而不是第一个 <authentication> 标记,即每个解决方案的全局配置。