Asp.net MVC授权属性,重定向到自定义"无权限"页面

mam*_*amu 32 asp.net-mvc asp.net-mvc-2

response 302当经过身份验证的用户没有权限时,Asp.net MVC2会重定向到登录页面.

我想分成两个动作

  1. 如果用户未经过身份验证,则执行其操作,重定向到登录页面.
  2. 如果用户已通过身份验证但没有必需的权限,则返回相应的http状态代码并显示没有权限的dude页面.

有什么办法吗?或者我在授权和表单身份验证方面做错了什么?我能想到的唯一方法是编写自定义授权属性,我想避免使用它.

小智 19

您可以像这样编写自定义过滤器属性:

public class CustomAuthorizeAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?returnUrl=" +
                filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
            }

            //Check user right here
            if (userNotRight)
            {
                filterContext.HttpContext.Response.StatusCode = 302;
                filterContext.Result = new HttpUnauthorizedResult();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

并在控制器中使用它:

[CustomAuthorize]
public class HomeController : Controller
{

}
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用AuthorizeAttribute而不是ActionFilterAttribute来进行授权. (18认同)

Dar*_*rov 9

你可以写一个自定义的授权属性,在AuthorizeCore方法,如果用户没有通过验证回报HttpUnauthorizedResult,如果他被验证,但不执行的角色,你想一些其他的动作.请注意,如果返回401状态代码,FormsAuthentication框架最终将使用302重定向到登录页面.

  • 但是......你只能从AuthorizeCore返回一个bool.您必须重写OnAuthorization才能返回ActionResult (4认同)

Bri*_*ers 7

正如在ASP.NET MVC自定义授权中所建议的那样,您可以将AuthorizeAttribute子类化为拦截经过身份验证但未经授权的方案,并使用重定向替换结果.


And*_*eas 7

实现自定义AuthorizeAttribute并添加以下覆盖.基础是检查用户是否经过身份验证但未经授权,然后重定向到您自己的"拒绝访问"页面.希望这可以帮助!

public override void OnAuthorization(AuthorizationContext filterContext) 
{
    base.OnAuthorization(filterContext);

    // Check if user is authenticated and if this action requires authorization
    if (filterContext.HttpContext.User.Identity.IsAuthenticated
        && filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), true)
        || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), true))
    {
        List<object> attributes = new List<object>(filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
        attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));

        // Check all authorzation attributes
        foreach (var attribute in attributes)
        {
            var authAttribute = attribute as AuthorizeAttribute;
            if (authAttribute != null)
            {
                if (!filterContext.HttpContext.User.IsInRole(authAttribute.Roles))
                {
                    // User is not authorized so redirect to our access denied error page
                    filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary 
                            {
                                { "area", "" },
                                { "controller", "Error" },
                                { "action", "AccessDenied" }
                            });
                    break;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)