如何使用Webrequest Credentials
属性发送基本身份验证标头?
即使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();
答案 0 :(得分:6)
服务器应发送包含 WWW-Authenticate HTTP标头的HTTP 401 Not Authorized响应代码。
WWW-Authenticate: Basic realm="example"
PreAuthenticate属性仅在身份验证发生后工作。来自MSDN:
如果发送带有请求的HTTP Authorization标头,则为true 认证已经发生;否则,错误。默认是 假的。
有关详细信息,请参阅其他答案。
答案 1 :(得分:4)
我根据Måns Tånneryd的答案做了一些额外的研究。以及他在评论中发布的链接:PreAuthenticate Property of WebRequest - Problem。
首先,如他的链接中所述,HttpWebRequest.PreAuthenticate Property不会发送身份验证标头PRE身份验证,但会在身份验证之后将其发送到以下请求中。来自MSDN:
如果在进行身份验证后发送带有请求的HTTP Authorization标头,则为true;否则,错误。默认值为false。
因此,即使将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中看到以下内容:
响应将得到预期的结果。
答案 2 :(得分:3)
我可以成功运行此代码,访问另外需要SSL和身份验证的服务器。这个服务器与github的不同之处在于github返回一个json结果,说它需要身份验证,而另一个服务器返回一个“经典”401 html页面。嗅探网络你可以看到.net代码试图进行匿名身份验证,即使你将preauth设置为true,我认为这是相当混乱的。然而,在收到常规的401页后,它再次尝试,这次使用身份验证信息,一切正常。在我看来,虽然.net在收到401的json版本时反应不同,而不是第二次尝试。
我想这不是你正在寻找的答案,但希望它能更清楚地了解情况。