asp.net - 将 IIS Windows 身份验证配置为返回 HTTP 403 而不是 HTTP 401,以拒绝经过身份验证的用户的权限

标签 asp.net iis

今天,一位同事问我如何配置 IIS 7.5,以对一个简单的 Intranet 网站使用集成 Windows 身份验证和模拟,该网站仅包含仅限 Active Directory 中特定组(例如“管理员”)的静态内容。

事实证明,当经过身份验证的用户没有请求资源的权限时,IIS 会发送 HTTP 401 响应。权限被拒绝可能是 NTFS 文件 ACL 或 IIS 配置中定义的 system.webServer/security/authorization ACL 造成的。

所有主流浏览器似乎都会将此 401 解释为最终用户提供了无效的 Windows 用户名/密码凭据,从而提示用户输入用户名/密码。 IE 似乎在显示 401 响应正文/内容之前提示最多 3 次。 Chrome 和 Safari 似乎会反复提示用户。

这可能会让最终用户感到困惑,他们不断重复输入有效的 Windows 用户名/密码,结果却再次收到提示。

更好的方法是让 IIS 返回 HTTP 403 而不是 HTTP 401:

403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated.

Source: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4

如何配置 IIS 集成 Windows 身份验证以发送 HTTP 401(表示登录失败)和 HTTP 403(表示权限被拒绝)?

最佳答案

什么不起作用

我尝试了几乎所有 IIS 配置排列,但没有成功。我摆弄了 Windows 身份验证提供程序设置,例如 NTLM、Negotiate 和 Negotiate:Kerberos。他们似乎都没有成功。这并不奇怪,因为浏览器决定再次尝试身份验证,尽管它们可能不应该这么做。

401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refuse for those credentials.

Source: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2

什么有效

我决定利用一些低劣和肮脏的 ASP.NET 来解决这个问题。下面借助服务器上的几个文本文件和 ASP.NET 动态编译来实现响应重写。 (我以前从未使用过动态编译,但是,对于静态站点来说,编译似乎有点大材小用。)

下面的 Global.asax 文件会 Hook EndRequest 事件,如果用户成功验证为 Windows 用户,则将 HTTP 401 响应重写为 HTTP 403,但是,由于某些其他原因,请求被拒绝(我假设原因必须是是授权失败)。

web.config 文件包含用于通过 ASP.NET 管道路由所有请求的条目,并拒绝任何非“销售”Windows 组成员的经过身份验证的用户的访问。

此解决方案假设您有一个在 IIS 集成管道模式(即非经典模式)下运行的应用,您启用了 Windows 身份验证,并禁用了所有其他身份验证方案。

/Global.asax:

<Script language="C#" runat="server">
     void Application_EndRequest() {
          // rewrite HTTP 401s to HTTP 403s if the user is authenticated using 
            // integrated Windows auth with impersonation, but, 
            // the user lacks permissions to the requested URL
            if (Context.User != null && 
                    Context.User.Identity != null &&
                        Context.User.Identity.IsAuthenticated &&
                            Context.User is System.Security.Principal.WindowsPrincipal && 
                                Context.Response.StatusCode == 401) 
            {
                Context.Response.Clear();
                Context.Response.StatusCode = 403;
            }
        }
</script>

/web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <security>
            <authorization>
                <remove users="*" roles="" verbs="" />
                <add accessType="Allow" roles="Sales" />
            </authorization>
        </security>
      <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>
</configuration>

为了将来的引用,我创建了一个要点@ https://gist.github.com/steve-jansen/6234700

关于asp.net - 将 IIS Windows 身份验证配置为返回 HTTP 403 而不是 HTTP 401,以拒绝经过身份验证的用户的权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18241640/

相关文章:

asp.net - 在 IIS 上托管 Asp.Net Core 2

ios - HTTP 不支持的媒体类型问题

c# - 一些静态内容加载非常缓慢

c# - 来自主窗口文本框的用户控件文本框内的 wpf 绑定(bind)文本

c# - 带有 Blazor : Cannot figure out cookie authentification 的 ASP.NET Core

c# - 在 .NET 中创建 XMLSerializer 会引发异常

asp.net - 无法在 IIS 中启动网站 - W3SVC 正在运行

javascript - 如何在 JavaScript 中使用内联 ASP.NET 标记?

c# - Win 2003 服务器忽略 css 样式

asp.net - 增加应用程序池 session 超时不起作用