C# 当用户不在授权角色中时,如何提供未授权页面?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2322366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:24:56  来源:igfitidea点击:

How do I serve up an Unauthorized page when a user is not in the Authorized Roles?

c#asp.net-mvcsecurityroles

提问by Robert Harvey

I am using the Authorizeattribute like this:

我正在使用这样的Authorize属性:

[Authorize (Roles="Admin, User")]
Public ActionResult Index(int id)
{
    // blah
}

When a user is not in the specified roles, I get an error page (resource not found). So I put the HandleErrorattribute in also.

当用户不在指定的角色中时,我会收到一个错误页面(找不到资源)。所以我也把这个HandleError属性放进去了。

[Authorize (Roles="Admin, User"), HandleError]
Public ActionResult Index(int id)
{
    // blah
}

Now it goes to the Loginpage, if the user is not in the specified roles.

如果用户不在指定的角色中,现在它会转到登录页面。

How do I get it to go to an Unauthorizedpage instead of the login page, when a user does not meet one of the required roles? And if a different error occurs, how do I distinguish that error from an Unauthorized error and handle it differently?

当用户不满足所需角色之一时,如何让它转到未经授权的页面而不是登录页面?如果发生不同的错误,我如何将该错误与未经授权的错误区分开来并以不同的方式处理它?

采纳答案by Rune

Add something like this to your web.config:

将这样的内容添加到您的 web.config 中:

<customErrors mode="On" defaultRedirect="~/Login">
     <error statusCode="401" redirect="~/Unauthorized" />
     <error statusCode="404" redirect="~/PageNotFound" />
</customErrors>

You should obviously create the /PageNotFoundand /Unauthorizedroutes, actions and views.

很显然你应该创建/PageNotFound/Unauthorized路线,行动和意见。

EDIT: I'm sorry, I apparently didn't understand the problem thoroughly.

编辑:对不起,我显然没有彻底理解这个问题。

The problem is that when the AuthorizeAttributefilter is executed, it decides that the user does not fit the requirements (he/she may be logged in, but is not in a correct role). It therefore sets the response status code to 401. This is intercepted by the FormsAuthenticationmodule which will then perform the redirect.

问题在于,当AuthorizeAttribute过滤器执行时,它决定用户不符合要求(他/她可能已登录,但没有处于正确的角色)。因此,它将响应状态代码设置为 401。这被FormsAuthentication模块拦截,然后将执行重定向。

I see two alternatives:

我看到两种选择:

  1. Disable the defaultRedirect.

  2. Create your own IAuthorizationFilter. Derive from AuthorizeAttributeand override HandleUnauthorizedRequest. In this method, if the user is authenticated do a redirectto /Unauthorized

  1. 禁用默认重定向。

  2. 创建您自己的IAuthorizationFilter. 派生自AuthorizeAttribute并覆盖 HandleUnauthorizedRequest。在此方法中,如果用户通过身份验证,则重定向到 /Unauthorized

I don't like either: the defaultRedirect functionality is nice and not something you want to implement yourself. The second approach results in the user being served a visually correct "You are not authorized"-page, but the HTTP status codes will not be the desired 401.

我也不喜欢:defaultRedirect 功能很好,而不是你想自己实现的东西。第二种方法会为用户提供一个视觉上正确的“您未被授权”页面,但 HTTP 状态代码将不是所需的 401。

I don't know enough about HttpModules to say whether this can be circumvented with a a tolerable hack.

我对 HttpModules 知之甚少,无法说明是否可以通过可容忍的 hack 来规避此问题。

EDIT 2: How about implementing your own IAuthorizationFilter in the following way: download the MVC2 code from CodePlex and "borrow" the code for AuthorizeAttribute. Change the OnAuthorization method to look like

编辑 2:如何通过以下方式实现您自己的 IAuthorizationFilter:从 CodePlex 下载 MVC2 代码并“借用”AuthorizeAttribute 的代码。将 OnAuthorization 方法更改为

    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (AuthorizeCore(filterContext.HttpContext))
        { 
            HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
            cachePolicy.SetProxyMaxAge(new TimeSpan(0));
            cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
        }
        // Is user logged in?
        else if(filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // Redirect to custom Unauthorized page
            filterContext.Result = new RedirectResult(unauthorizedUrl);
        } 
        else {
            // Handle in the usual way
            HandleUnauthorizedRequest(filterContext);
        }
    }

where unauthorizedUrlis either a property on the filter or read from Web.config.

whereunauthorizedUrl是过滤器上的属性或从 Web.config 读取。

You could also inherit from AuthorizeAttribute and override OnAuthorization, but you would end up writing a couple of private methods which are already in AuthorizeAttribute.

您也可以从 AuthorizeAttribute 继承和 override OnAuthorization,但最终会编写一些已经在 AuthorizeAttribute 中的私有方法。

回答by Mike Chaliy

And HttpUnauthorizedResult(this comes as reuslt of the AuthorizeAtrribute) just sets StatusCode to 401. So probably you can setup 401 page in IIS or custom error pages in web.config. Of course, you also have to ensure that access to your custom error page is not requires authorization.

并且HttpUnauthorizedResult(这是 的重新使用AuthorizeAtrribute)只是将 StatusCode 设置为 401。因此,您可能可以在 IIS 中设置 401 页面或在 web.config 中设置自定义错误页面。当然,您还必须确保访问您的自定义错误页面不需要授权。

回答by Pbirkoff

You could do this in two ways:

您可以通过两种方式执行此操作:

  1. Specify the error the HandleError-attribute, and give a view that should be shown:

    [HandleError(ExceptionType = typeof(UnAuthorizedException), View = "UnauthorizedError")]

  1. 指定 HandleError 属性的错误,并给出应显示的视图:

    [HandleError(ExceptionType = typeof(UnAuthorizedException), View = "UnauthorizedError")]

You can specify several different ExceptionTypes and views

您可以指定几个不同的 ExceptionType 和视图

  1. Create a custom ActionFilter, check there for credentials, and redirect to a controller if the user is unauthorized.: http://web.archive.org/web/20090322055514/http://msdn.microsoft.com/en-us/library/dd381609.aspx
  1. 创建自定义 ActionFilter,检查那里的凭据,如果用户未经授权,则重定向到控制器。:http://web.archive.org/web/20090322055514/http: //msdn.microsoft.com/en-us/图书馆/dd381609.aspx

回答by 628426

Perhaps a 403 status code is more appropriate based on your question (the user is identified, but their account is not privileged enough). 401 is for the case where you do not know what priveleges the user has.

根据您的问题,也许 403 状态代码更合适(已识别用户,但他们的帐户没有足够的特权)。401 适用于您不知道用户拥有什么特权的情况。

回答by Davy

Just override the HandleUnauthorizedRequest method of AuthorizeAttribute. If this method is called, but the user IS authenticated, then you can redirect to your "not authorized" page.

只需覆盖 AuthorizeAttribute 的 HandleUnauthorizedRequest 方法。如果调用此方法,但用户已通过身份验证,则您可以重定向到“未授权”页面。

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Area = "", Controller = "Error", Action = "Unauthorized" }));
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}