4

如何使用 WebrequestCredentials属性发送基本身份验证标头?为什么即使PreAuthenticate设置为 true,Authorization 标头也不随请求一起发送?

WebRequest request = (HttpWebRequest)WebRequest.Create("https://api.github.com/user");
request.Credentials = new NetworkCredential("githubUsername", "githubPassword");
request.PreAuthenticate = true;
var response = request.GetResponse();
4

3 回答 3

5

服务器应发送包含WWW-Authenticate HTTP 标头的 HTTP 401 Not Authorized 响应代码。

WWW-Authenticate: Basic realm="example"

PreAuthenticate 属性仅在进行身份验证后才起作用。来自 MSDN:

true 在身份验证发生后发送带有请求的 HTTP Authorization 标头;否则为假。默认值为假。

有关更深入的解释,请参阅其他答案。

于 2013-11-04T21:20:20.550 回答
4

我根据Måns Tånneryd的回答做了一些额外的研究。以及他在评论中发布的链接:PreAuthenticate Property of WebRequest - Problem

首先,如他的链接中所述,HttpWebRequest.PreAuthenticate 属性不发送 Authentication 标头 PRE 身份验证,而是在身份验证之后在后续请求中预发送它。来自 MSDN:

true 在身份验证发生后发送带有请求的 HTTP Authorization 标头;否则为假。默认值为假。

因此,即使将PreAuthenticate属性设置为 true,在任何事情发生之前,我们仍然需要一个带有 401 Unauthorized 的 WWW-Authenticate 质询。现在,如果我们尝试使用以下代码对 github 进行身份验证:

WebRequest request = (HttpWebRequest)WebRequest.Create("https://api.github.com/user");
request.Credentials = new NetworkCredential("githubUsername", "githubPassword");

var response = request.GetResponse();

将抛出一个WebException,因为我们没有收到 WWW-Authenticate 挑战。如果我们在 Fiddler 中捕获它,我们将得到以下信息:

在此处输入图像描述

但是,如果我们尝试使用完全相同的代码,针对确实返回 WWW-Authenticate 质询的网站,我们将在 Fiddler 中看到以下内容:

在此处输入图像描述 在此处输入图像描述

并且响应将具有预期的结果。

于 2014-08-12T07:36:47.657 回答
3

我可以成功运行此代码来访问另一个也需要 SSL 和身份验证的服务器。该服务器与 github 的不同之处在于 github 返回一个 json 结果,说明它需要身份验证,而另一个服务器返回一个“经典”401 html 页面。嗅探网络,您可以看到.net 代码尝试进行匿名身份验证,即使您确实将 preauth 设置为 true,我认为这相当令人困惑。但是,在收到常规的 401 页后,它会再次尝试,这次使用身份验证信息,一切正常。在我看来,好像.net 在收到 401 的 json 版本时反应不同,而不是第二次尝试。

我想这不是您正在寻找的答案,但希望它可以进一步阐明这种情况。

于 2013-11-04T10:00:12.447 回答