设置授权和"访问被拒绝"页面

时间:2017-02-03 17:30:46

标签: c# asp.net asp.net-mvc web-config authorization

我正在开发ASP.Net MVC应用程序。我想拒绝访问AD组中未经身份验证或未经身份验证的所有用户。只有此AD组才能访问。例外情况是"你不会通过!"页。任何人都可以访问它。

在项目根目录中,我在我的web.config中有这个(为了简洁,修剪了文件的其余部分):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <customErrors mode="On">
            <error statusCode="401" redirect="/ui/Other/YouShallNotPass.html" />
        </customErrors>
        <compilation debug="true" targetFramework="4.5.2" />
        <httpRuntime targetFramework="4.5.2" />
        <authentication mode="Windows" />
        <authorization>
            <allow roles="allowedrole"/>
            <deny users="*"/>
        </authorization>
    </system.web>
    <system.webServer>
        <httpErrors>
            <remove statusCode="401" />
            <error statusCode="401" 
                   subStatusCode="2" 
                   responseMode="ExecuteURL" 
                   path="/ui/Other/YouShallNotPass.html" />
        </httpErrors>
    </system.webServer>
</configuration>

我在ui/Other/YouShallNotPass.html旁边有第二个web.config。我希望这允许任何人访问此页面,进行身份验证或其他方式:

<configuration>
    <system.web>
        <authorization>
            <allow users="?"/>
        </authorization>
    </system.web>
</configuration>

我可以通过将AD组设置为不存在的AD组来测试它。我不属于不存在的群组,所以我应该看到YouShallNotPass.html页面。

它没有按预期工作。我在浏览器中收到以下错误:

  

错误消息401.2。:未授权:由于服务器配置,登录失败。验证您是否有权根据您提供的凭据和Web服务器上启用的身份验证方法查看此目录或页面。

如果我直接请求YouShallNotPass.html,我可以在提示用户/通行证后访问它。

我做错了什么?当用户未获得授权时,为什么不能为401页面提供服务呢?

2 个答案:

答案 0 :(得分:1)

通过将以下内容添加到我的global.asax来管理解决此问题:

protected void Application_EndRequest(object sender, EventArgs e)
{
    if (Response.StatusCode != 401)
        return;

    Response.ClearContent();
    Response.WriteFile("~/ui/Other/YouShallNotPass.html");
    Response.ContentType = "text/html";
}

我宁愿使用web.config执行此操作。

答案 1 :(得分:0)

查看此question,因为它解释了为什么您的解决方案无法正常运作。

因此,一旦您使用[授权]移动注释所有安全控制器操作,您可以添加自定义ExceptionFilter

像这样

public class HandleUnauthorizedAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);

        if (filterContext.Exception.GetType() != typeof (SecurityException)) return;

        var controllerName = (string) filterContext.RouteData.Values["controller"];
        var actionName = (string) filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

        filterContext.Result = new ViewResult
        {
            ViewName = "Unauthorized",
            ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
            TempData = filterContext.Controller.TempData
        };
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 403;
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

然后在这里布线

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleUnauthorizedAttribute());
    }
}