在ASP.NET MVC中重写授权属性


83

我有一个MVC控制器基类,在该基类上应用了Authorize属性,因为我希望几乎所有的控制器(以及它们的动作)都得到授权。

但是我需要一个控制器和另一个控制器的操作未经授权。我希望能够使用[Authorize(false)]或来装饰它们,但这不可用。

有任何想法吗?

Answers:


100

编辑:自ASP.NET MVC 4以来,最好的方法就是简单地使用内置的AllowAnonymous属性。

下面的答案是指早期版本的ASP.NET MVC

您可以创建一个继承自标准AuthorizeAttribute的自定义授权属性,并使用一个可选的bool参数来指定是否需要授权。

public class OptionalAuthorizeAttribute : AuthorizeAttribute
{
    private readonly bool _authorize;

    public OptionalAuthorizeAttribute()
    {
        _authorize = true;
    }

    public OptionalAuthorizeAttribute(bool authorize)
    {
        _authorize = authorize;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if(!_authorize)
            return true;

                    return base.AuthorizeCore(httpContext);
    }
}

然后,您可以使用该属性装饰基本控制器:

[OptionalAuthorize]
public class ControllerBase : Controller
{
}

对于不需要控制器的任何控制器,只需使用带有'false'的替代-例如

[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}

我已经想到了这一点,但我希望有一个更简单的解决方案。但是,如果“他们”没有提供解决方案,那么您的解决方案就是最好的解决方案。
2009年

2
最好使用[AllowAnonymous]属性。
Jaider

等待...所以控制器仅接受特定类型的顶级类的属性?
Triynko

您知道为什么使用AllowAnonymous实际上更好吗?因为您拥有更好的控制权。就我而言,我只想在某些环境中禁用授权端点,例如,对于本地主机,则不需要它。与我在startup.cs中要做的相比,这提供了更优雅的解决方案。11年后,我们在这里谈论。
sksallaj


15

我个人对此的看法是拆分控制器。只需创建另一个控制器,对于这些操作,您不需要身份验证。

或者您可能有:

  • BaseController
    不需要身份验证-在这里,您拥有所有“基本资料” :)。

  • BaseAuthController : BaseController
    这里的所有操作都需要认证。

这样,您可以在需要时进行身份验证,只需从特定的类派生即可。


6

如果您只想在其他经过授权的控制器上未经授权执行某项操作,则可以执行以下操作:

public class RequiresAuthorizationAttribute : ActionFilterAttribute
{
    private readonly bool _authorize;

    public RequiresAuthorizationAttribute()
    {
        _authorize = true;
    }

    public RequiresAuthorizationAttribute(bool authorize)
    {
        _authorize = authorize;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var overridingAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequiresAuthorizationAttribute), false);

        if (overridingAttributes.Length > 0 && overridingAttributes[0] as RequiresAuthorizationAttribute != null && !((RequiresAuthorizationAttribute)overridingAttributes[0])._authorize)
            return;

        if (_authorize)
        {
            //redirect if not authenticated
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                //use the current url for the redirect
                var redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;

                //send them off to the login page
                //var redirectUrl = string.Format("?RedirectUrl={0}", redirectOnSuccess);
                var loginUrl = LinkBuilder.BuildUrlFromExpression<HomeController>(filterContext.RequestContext, RouteTable.Routes,
                                                                                  x => x.Login(redirectOnSuccess));
                filterContext.HttpContext.Response.Redirect(loginUrl, true);
            }
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.