简体   繁体   中英

Setting up authorization and a “Access-denied” page

I'm working on an ASP.Net MVC application. I want to deny access to all users who are unauthenticated or not in an AD group. 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):

<?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 . 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. I'm not part of the non-existent group, so I should expect to see the YouShallNotPass.html page.

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. 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.

If I request YouShallNotPass.html directly, I can access it after being prompted for a user/pass.

What am I doing incorrectly? Why won't it serve the 401 page when the user isn't authorized?

Managed to work around this by adding the following to my 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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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