覆盖 ASP.NET MVC 中的授权属性

发布于 2024-07-16 17:32:12 字数 182 浏览 3 评论 0原文

我有一个 MVC 控制器基类,我在其中应用了 Authorize 属性,因为我希望几乎所有控制器(及其操作)都获得授权。

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

有任何想法吗?

I have an MVC controller base class on which I applied the Authorize attribute since I want almost all of the controllers (and their actions along) to be authorized.

However I need to have a controller and an action of another controller unauthorized. I wanted to be able to decorate them with the [Authorize(false)] or something but this is not available.

Any ideas?

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

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

发布评论

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

评论(4

忘你却要生生世世 2024-07-23 17:32:12

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

Edit: Since ASP.NET MVC 4 the best approach is simply to use the built-in AllowAnonymous attribute.

The answer below refers to earlier versions of ASP.NET MVC

You could create a custom authorisation attribute inheriting from the standard AuthorizeAttribute with an optional bool parameter to specify whether authorisation is required or not.

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

Then you can decorate your base controller with that attribute:

[OptionalAuthorize]
public class ControllerBase : Controller
{
}

and for any controllers you don't want authorisation simply use the override with a 'false' - e.g.

[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}
递刀给你 2024-07-23 17:32:12

似乎 ASP.NET MVC 4 通过添加 AllowAnonymous 属性。

David Hayden 写了相关内容 :

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

    // ...
}

It seems ASP.NET MVC 4 'fixed' this by adding an AllowAnonymous attribute.

David Hayden wrote about this :

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

    // ...
}
生寂 2024-07-23 17:32:12

我个人对此的看法是拆分控制器。 只需创建另一个控制器即可执行不需要身份验证的操作。

或者你可以有:

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

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

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

My personal take on this would be to split the controller. Just create another controller For the actions you don't need authentication.

Or you could have :

  • BaseController
    doesn't require authentication - here you have all your "base stuff" :).

  • BaseAuthController : BaseController
    all actions here require authentication.

That way you can have authentication when you want , just by deriving from a specific class.

Spring初心 2024-07-23 17:32:12

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

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

If you just want one action to be unauthorized on an otherwise authorized controller you can do something like this:

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