C# 设置授权和a";“拒绝访问”;页

C# 设置授权和a";“拒绝访问”;页,c#,asp.net,asp.net-mvc,web-config,authorization,C#,Asp.net,Asp.net Mvc,Web Config,Authorization,我正在开发一个ASP.NETMVC应用程序。我想拒绝所有未经验证或不在广告组中的用户访问。只有此广告组应具有访问权限。例外情况是“你不能通过!”页面。任何人都可以访问它 在项目根目录中,我的web.config中有这个文件(为了简洁起见,文件的其余部分被修剪): 我可以通过将广告组设置为一个不存在的组来测试这一点。我不是不存在的组的一部分,所以我希望看到YouShallNotPass.html页面 它没有按预期工作。我的浏览器中出现以下错误: 错误消息401.2.:未经授权:由于服务器配置,登录

我正在开发一个ASP.NETMVC应用程序。我想拒绝所有未经验证或不在广告组中的用户访问。只有此广告组应具有访问权限。例外情况是“你不能通过!”页面。任何人都可以访问它

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

我可以通过将广告组设置为一个不存在的组来测试这一点。我不是不存在的组的一部分,所以我希望看到
YouShallNotPass.html
页面

它没有按预期工作。我的浏览器中出现以下错误:

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

如果我直接请求
YouShallNotPass.html
,我可以在提示输入用户/密码后访问它

我做错了什么?当用户未经授权时,为什么它不提供401页服务?

请查看此内容,因为它解释了您的解决方案不起作用的原因

因此,一旦您使用[Authorize]对所有安全控制器操作进行注释,您就可以添加自定义例外过滤器

像这样

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;
    }
}
看看这个,因为它解释了为什么你的解决方案不起作用

因此,一旦您使用[Authorize]对所有安全控制器操作进行注释,您就可以添加自定义例外过滤器

像这样

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

通过将以下内容添加到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";
}

不过,我更愿意使用web.config来实现这一点。

通过在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";
}


不过,我更愿意使用web.config来执行此操作。

尝试在
的web.config中插入
,然后查看发生了什么。由于浏览器仍在提示用户/通行证,这意味着该页面仍需要windows身份验证(因为您将其放在主web.config中,并且没有覆盖它)。当我直接请求
YouShallNotPass.html
时,它不再要求用户/通行证。但是任何其他页面,我仍然会得到原始错误。是否有可能您的访问池用户无权访问您正在进行身份验证的数据库?身份验证工作正常,而我没有针对数据库进行身份验证。请尝试在您的
YouShallNotPass.html的web.config中插入
,然后看看会发生什么。由于浏览器仍在提示用户/通行证,这意味着该页面仍需要windows身份验证(因为您将其放在主web.config中,并且没有覆盖它)。当我直接请求
YouShallNotPass.html
时,它不再要求用户/通行证。但是任何其他页面和我仍然会得到原始错误。是否有可能您的访问池用户无权访问您正在进行身份验证的数据库?身份验证工作正常,而我没有针对数据库进行身份验证。这是否适用于我的情况
YouShallNotPass.html
是一个静态html文件。它不是由控制器提供服务的。关键是你不能在web.config中配置安全性,在那里你锁定了整个网站,然后像使用asp.net webforms那样打开漏洞。所以1。在控制器操作2上使用“授权”属性。在执行1之后,您可能可以使用customerrors,因为您没有锁定所有内容。另一个问题是,您在此处将身份验证(您是谁)与授权(您可以做什么)混合使用。身份验证错误可能是401。授权错误是403。我还将更改为视图,如我的解决方案,因为您可以在错误页面上看到其他信息,如他们试图访问的内容。我对将其更改为视图不感兴趣。1) 我已经在使用
[Authorize]
,2)我的自定义错误部分不起作用,3)我正在锁定所有内容,包括静态文件,这是使用
Authorize
无法完成的。这适用于我的情况吗
YouShallNotPass.html
是一个静态html文件。它不是由控制器提供服务的。关键是你不能在web.config中配置安全性,在那里你锁定了整个网站,然后像使用asp.net webforms那样打开漏洞。所以1。在控制器操作2上使用“授权”属性。在执行1之后,您可能可以使用customerrors,因为您没有锁定所有内容。另一个问题是,您在此处将身份验证(您是谁)与授权(您可以做什么)混合使用。身份验证错误可能是401。授权错误是403。我还将更改为视图,如我的解决方案,因为您可以在错误页面上看到其他信息,如他们试图访问的内容。我对将其更改为视图不感兴趣。1) 我已经在使用
[Authorize]
,2)我的自定义错误部分不起作用,3)我正在锁定所有内容,包括静态文件,这是使用
Authorize
无法完成的。您是否尝试在主web.config中使用
元素而不是使用第二个web.config?这可能是一个比拦截回应更干净的选择。是的,我做了。但是我不记得为什么它现在不起作用了。您是否尝试在主web.config中使用
元素而不是使用第二个web.config?这可能是一个比拦截回应更干净的选择。是的,我做了。不过,我不记得为什么它现在不起作用了。
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";
}