【问题标题】:IIS site for both intranet and anonymous users用于 Intranet 和匿名用户的 IIS 站点
【发布时间】:2013-11-27 14:18:42
【问题描述】:

我正在开发一个应用程序,该应用程序应该可供在自己的帐户下运行的 Intranet 用户使用(Windows 身份验证)。这很容易配置和工作。

现在,如果用户没有登录到域(因为他们不在现场或在未登录的设备上),他们应该仍然能够使用该应用程序,但需要一些个性化的功能。

总而言之,这就是我希望发生的事情:

  1. 用户打开应用程序。如果 Windows 凭据可用,浏览器会将它们发送到 IIS。
  2. 如果收到用户凭据,则应用程序会在这些凭据下运行(我已经介绍过了)。
  3. 如果未收到用户凭据,则应用程序将在 IIS 匿名帐户下运行,并且个性化功能将被关闭(我也对此进行了介绍)。

我无法开始工作是选择性地发送凭据。如果我打开 Windows 身份验证,我将登录,这很好。但是,如果我尝试在不发送凭据的情况下访问该站点,我会得到一个 401,这是有道理的。所以我打开了匿名身份验证,现在永远不会发送凭据。

这实际上是有道理的,因为 IIS 从不向浏览器请求身份验证。问题是,我如何让这个场景发挥作用?

【问题讨论】:

  • MSDN上有一篇关于混合Windows和Forms身份验证的文章。它包含可能对您的方案有所帮助的信息:msdn.microsoft.com/en-us/library/ms972958.aspx
  • 我看过这篇文章。它可能会成为解决方案的灵感,尽管我认为使用自定义 401 错误有点小题大做。我必须先咨询团队中的其他人。
  • 当你写“所以我打开匿名身份验证,现在永远不会发送凭据”。您的意思是即使启用匿名身份验证和 Windows 身份验证,也不会发送凭据?如果是这样,它看起来像浏览器(IE?)配置行为。
  • @JoeBilly 这就是我的意思。我已将我正在测试的站点配置为受信任站点,并默认启用发送当前 Windows 凭据。我对 HTTP 身份验证机制的理解是,它只会根据服务器的身份验证请求来执行此操作。

标签: asp.net authentication iis


【解决方案1】:

您的分析是正确的。 HTTP authentication 方案是:

  • 匿名访问
  • 质询-响应身份验证
    • 协商(Kerberos)
    • NTLM
    • 摘要
  • 基本身份验证

在 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 标头。

希望它足够清楚。

【讨论】:

  • 在实施任何事情之前我要清楚。基本思想是在 IIS 中允许匿名并在稍后阶段处理身份验证。然后前 3 次返回 401 并允许第 4 次访问?
  • 是的,您知道了,请注意,您至少需要在服务器端启用两种身份验证方法:Anonymous Authentication 另一种类似Windows Authentication 的方法可以使用@987654340 @。在我的回答中指出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多