簡體   English   中英

覆蓋ASP.NET MVC中的授權屬性

[英]Override Authorize Attribute in ASP.NET MVC

我有一個MVC控制器基類,我在其上應用了Authorize屬性,因為我希望幾乎所有控制器(及其操作)都被授權。

但是我需要一個控制器和另一個控制器的動作未經授權。 我希望能夠使用[Authorize(false)]或其他東西來裝飾它們,但這不可用。

有任何想法嗎?

編輯:自ASP.NET MVC 4以來,最好的方法就是使用內置的AllowAnonymous屬性。

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

您可以使用可選的bool參數創建從標准AuthorizeAttribute繼承的自定義授權屬性,以指定是否需要授權。

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

似乎ASP.NET MVC 4通過添加AllowAnonymous屬性來“修復”此問題。

大衛海登寫到這個

[Authorize]
public class AccountController : Controller
{
    [AllowAnonymous]
    public ActionResult Login()
    {
        // ...
    }

    // ...
}

我個人對此的看法是拆分控制器。 只需創建另一個控制器對於您不需要身份驗證的操作。

或者你可以:

  • BaseController
    不需要身份驗證 - 在這里你有你所有的“基礎東西”:)。

  • BaseAuthController : BaseController
    此處的所有操作都需要驗證

這樣,您可以在需要時進行身份驗證,只需從特定類派生即可。

如果您只想在其他授權的控制器上對一個操作進行未授權,您可以執行以下操作:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM