一位同事今天问我如何配置IIS 7.5以使用集成的Windows身份验证模拟简单的Intranet网站,其中只有静态内容仅限于Active Directory中的特定组(例如"管理员").
事实证明,当经过身份验证的用户没有对请求资源的权限时,IIS会发送HTTP 401响应.拒绝权限可能是NTFS文件ACL或system.webServer/security/authorizationIIS配置中定义的ACL 的结果.
所有主流浏览器似乎都将此401解释为最终用户提供了无效的Windows用户名/密码凭据,从而提示用户输入其用户名/密码.在显示401响应主体/内容之前,IE似乎提示最多3次.Chrome和Safari似乎反复提示用户.
这可能会让最终用户感到困惑,他们不断重复输入有效的Windows用户名/密码,只是再次提示.
更好的方法是IIS返回HTTP 403而不是HTTP 401:
403禁止
服务器理解请求,但拒绝履行请求.授权不会帮助和请求不应重复.
资料来源: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未经授权
该请求需要用户身份验证.响应必须包含WWW-Authenticate头字段(第14.47节),其中包含适用于所请求资源的质询.客户端可以使用合适的Authorization头字段重复请求(第14.8节).如果请求已包含授权凭据,则401响应表示授权已拒绝这些凭据.
资料来源:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
做了什么工作
我决定利用一些down和dirty ASP.NET来解决这个问题.下面借助服务器上的几个文本文件和ASP.NET动态编译实现响应重写.(我之前从未使用过动态编译,但是,对于静态站点来说,编译似乎有点过分.)
下面的Global.asax文件挂钩EndRequest事件,如果用户成功通过身份验证为Windows用户,则将HTTP 401响应重写为HTTP 403,但由于某些其他原因,请求被拒绝(我认为原因必须是授权失败).
web.config文件包含通过ASP.NET管道路由所有请求的条目,并拒绝访问任何不是"Sales"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>
Run Code Online (Sandbox Code Playgroud)
/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>
Run Code Online (Sandbox Code Playgroud)
为了将来的参考,我创建了一个Gist @ https://gist.github.com/steve-jansen/6234700
| 归档时间: |
|
| 查看次数: |
3279 次 |
| 最近记录: |