您的分析是正确的。
HTTP authentication 方案是:
在 IIS(和大多数 HTTP 服务器)上,默认身份验证过程遵循上述顺序。 IE。如果匿名访问成功(此处不再详述)其他身份验证提供程序即使已启用也会被忽略。
HTTP 401 挑战
如果您想管理多种身份验证方法和提供程序,您必须使用一种机制,当您认为它们无效时拒绝凭据。您可以通过发送401 响应来实现此目的。这称为HTTP 401 Challenge。
这个想法是告诉客户端(浏览器)用于请求资源的凭据被拒绝。
根据场景和客户端配置,客户端可能会处理身份验证。在这种情况下,身份验证过程可能会有所不同:挑战-响应提供者需要一定数量的交换来验证凭据。
无论如何,在您的情况下,启用匿名访问后,第一个 401 响应将被浏览器解释为“此请求需要身份验证”。如果在服务器端启用了支持的身份验证提供程序,则服务器会自动在响应标头中包含它们。
HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+v1b3a89710edce01754fd608...",charset=utf-8,realm="Digest"
WWW-Authenticate: Basic realm="host"
X-Powered-By: ASP.NET
Content-Length: 0
Proxy-Support: Session-Based-Authentication
如果您的浏览器已正确配置为发送 Web 应用程序区域的凭据(您说过),它将自动使用它知道的第一个身份验证提供程序(例如NTLM)并重新处理请求使用它知道的凭据(在您的情况下为 Windows 凭据)。
GET http://host/yourpage.aspx HTTP/1.1
Accept-Encoding: gzip, deflate
Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw==
Connection: Keep-Alive
当身份验证过程失败时,服务器会自动向客户端发送403 Forbidden 响应以避免过多的流量。 403 响应停止挑战。好消息是它需要一些挑战才能发生:超过 4 个。
通常,HTTP 身份验证质询需要接近 3 个 Challenge-Response 最大值才能成功(NTLM 为 3,Negotiate -Kerberos- 为 2)。
由于您允许匿名访问,服务器不会阻止客户端请求,您的页面将使用匿名凭据调用。您仍然可以通过将自己设置为HTTP Response Code 在您的页面中与您的客户进行交互。如前所述,它仅在您启用除 Anonymous 之外的其他身份验证提供程序时才有效。
因此,诀窍是使用服务器端的计数器处理它并说“如果我的身份验证会话/cookie 计数器大于 3,我的客户端无法通过服务器进行身份验证。假设他是匿名的”。
一些代码
我没有完全按照您的需要做,但您可以调整我的代码:
int i = 3;
int j = 0;
HttpContext httpContext = HttpContext.Current;
// Record authentication process
HttpCookie httpCookie2 = httpContext.Request.Cookies["loginAttemptCount"];
if (httpCookie2 == null || httpCookie2.Value == String.Empty)
{
httpCookie2 = new HttpCookie("loginAttemptCount");
}
else
{
j = Int32.Parse(httpCookie2.Value, System.Globalization.CultureInfo.InvariantCulture);
}
j = (j + 1) % i;
string user = Request.ServerVariables["LOGON_USER"];
// Send 401 responses to authenticate the user
if (j != 0 && user == String.Empty)
{
httpCookie2.Value = j.ToString(System.Globalization.CultureInfo.InvariantCulture);
httpContext.Response.Cookies.Add(httpCookie2);
Response.StatusCode = 401;
return;
}
httpCookie2.Value = String.Empty;
httpContext.Response.Cookies.Add(httpCookie2);
如果需要,您可以检查Authorization 标头中的授权提供程序。
Request.Headers["Authorization"]
您可以使用Fiddler 来跟踪您的 HTTP 标头。
希望它足够清楚。