简体   繁体   English

设置授权和“拒绝访问”页面

[英]Setting up authorization and a “Access-denied” page

I'm working on an ASP.Net MVC application. 我正在研究ASP.Net MVC应用程序。 I want to deny access to all users who are unauthenticated or not in an AD group. 我想拒绝对未经身份验证或不在AD组中的所有用户的访问。 Only this AD group should have access. 只有该广告组才能访问。 The exception to this is the "You Shall Not Pass!" 唯一的例外是“您不得通过!” page. 页。 Anyone can access that. 任何人都可以访问。

In the project root, I have this in my web.config (the rest of the file is trimmed for brevity): 在项目根目录中,我在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>

I have a second web.config sitting next to ui/Other/YouShallNotPass.html . 我在ui/Other/YouShallNotPass.html旁边有第二个web.config。 I expect this to allow anyone to access this page, authenticated or otherwise: 我希望这允许任何人通过身份验证或其他方式访问此页面:

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

I'm able to test this by setting the AD group to one that doesn't exist. 我可以通过将AD组设置为不存在的组来进行测试。 I'm not part of the non-existent group, so I should expect to see the YouShallNotPass.html page. 我不属于不存在的组,所以我应该期望看到YouShallNotPass.html页面。

It's not working as expected. 它没有按预期工作。 I'm getting the following error in my browser: 我的浏览器出现以下错误:

Error message 401.2.: Unauthorized: Logon failed due to server configuration. 错误消息401.2 ::未经授权:由于服务器配置,登录失败。 Verify that you have permission to view this directory or page based on the credentials you supplied and the authentication methods enabled on the Web server. 根据您提供的凭据和Web服务器上启用的身份验证方法,验证您是否有权查看此目录或页面。

If I request YouShallNotPass.html directly, I can access it after being prompted for a user/pass. 如果我直接请求YouShallNotPass.html ,则在提示输入用户名/通行证后可以访问它。

What am I doing incorrectly? 我做错了什么? Why won't it serve the 401 page when the user isn't authorized? 当用户未获得授权时,为什么它不提供401页?

Managed to work around this by adding the following to my global.asax: 通过将以下内容添加到我的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";
}

I would have preferred using the web.config to do this, though. 不过,我宁愿使用web.config来执行此操作。

Check out this question because it explains why your solution won't work. 请查看此问题,因为它说明了您的解决方案无法正常工作的原因。

So once you move to annotate all your secure controller actions with [Authorize] you can add a custom ExceptionFilter 因此,一旦您要使用[Authorize]为所有安全控制器操作添加注释,就可以添加自定义ExceptionFilter

like this 像这样

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;
    }
}

Then wiring it up here 然后在这里接线

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM