当用户不属于授权角色时,如何提供未经授权的页面?

发布于 2024-08-23 02:27:02 字数 479 浏览 8 评论 0原文

我使用 Authorize 属性,如下所示:

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

当用户不属于指定角色时,我会收到错误页面(未找到资源)。所以我也添加了 HandleError 属性。

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

现在,如果用户不属于指定角色,它将进入登录页面。

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

I am using the Authorize attribute like this:

[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 HandleError attribute in also.

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

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

How do I get it to go to an Unauthorized page 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

缺⑴份安定 2024-08-30 02:27:02

将类似的内容添加到您的 web.config 中:

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

您显然应该创建 /PageNotFound/Unauthorized 路由、操作和视图。

编辑:抱歉,我显然没有彻底理解这个问题。

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

我看到两种选择:

  1. 禁用defaultRedirect。

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

我也不喜欢:defaultRedirect 功能很好,而不是您想要自己实现的功能。第二种方法会导致用户看到一个视觉上正确的“您未经授权”页面,但 HTTP 状态代码不会是所需的 401。

我对 HttpModules 的了解不够,无法判断是否可以使用 aa 来规避此问题可以容忍的黑客攻击。

编辑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);
        }
    }

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

您还可以继承 AuthorizeAttribute 并重写 OnAuthorization,但您最终会编写几个已经在 AuthorizeAttribute 中的私有方法。

Add something like this to your web.config:

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

You should obviously create the /PageNotFound and /Unauthorized routes, actions and views.

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

The problem is that when the AuthorizeAttribute filter 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 FormsAuthentication module which will then perform the redirect.

I see two alternatives:

  1. Disable the defaultRedirect.

  2. Create your own IAuthorizationFilter. Derive from AuthorizeAttribute and override HandleUnauthorizedRequest. In this method, if the user is authenticated do a redirect to /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.

I don't know enough about HttpModules to say whether this can be circumvented with a a tolerable 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

    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 unauthorizedUrl is either a property on the filter or read from 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.

旧梦荧光笔 2024-08-30 02:27:02

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

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

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

您可以指定几种不同的 ExceptionTypes 和视图

  1. 创建自定义 ActionFilter,检查凭据,如果用户未经授权则重定向到控制器。: http://web.archive.org/web/20090322055514/http:// /msdn.microsoft.com/en-us/library/dd381609.aspx

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")]

You can specify several different ExceptionTypes and views

  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
守护在此方 2024-08-30 02:27:02

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

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.

无敌元气妹 2024-08-30 02:27:02

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

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.

深海夜未眠 2024-08-30 02:27:02

只需重写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);
        }
    }
}

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.

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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文