您是否可以为控制器启用[授权]但是为单个操作禁用它?

时间:2008-11-30 22:22:57

标签: c# asp.net-mvc authorization

除了[Authorize]操作之外,我想对我的管理控制器中的每个操作使用Login

[Authorize (Roles = "Administrator")]
public class AdminController : Controller
{
    // what can I place here to disable authorize?
    public ActionResult Login()
    {
        return View();
    }
}

4 个答案:

答案 0 :(得分:25)

您可以使用[授权]修饰您的控制器,然后您可以使用[AllowAnonymous]

装饰您想要免除的方法

答案 1 :(得分:14)

我认为您不能使用标准的Authorize属性执行此操作,但您可以从AuthorizeAttribute派生自己的属性,该属性采用允许的操作列表并允许仅访问这些操作。您可以在www.codeplex.com查看AuthorizeAttribute的源代码,了解有关如何执行此操作的建议。如果你这样做,它可能看起来像:

[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ]
public class AdminController : Controller
{
    public ActionResult Login()
    {
        return View();
    }

    public ActionResult Login()
    {
        return View();
    }

    ... other, restricted actions ...
}

编辑:仅供参考,我最终遇到了需要自己做类似事情的事情,我走的是另一个方向。我创建了默认授权过滤器提供程序并应用了全局授权过滤器。授权过滤器提供程序使用反射来检查操作或控制器是否应用了特定的授权属性,如果是,则按照它进行操作。否则,它应用默认授权过滤器。这与从AuthorizeAttribute派生的PublicAttribute相结合,允许公共访问。现在,我获得默认的安全访问权限,但可以通过应用于操作或控制器的[Public]授予公共访问权限。如有必要,还可以应用更具体的授权。请访问我的博客http://farm-fresh-code.blogspot.com/2011/04/default-authorization-filter-provider.html

答案 2 :(得分:4)

您可以覆盖控制器的OnAuthorization方法

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Login")
        {
            filterContext.Cancel = true;
            filterContext.Result = Login();
        }
    }

这有效,但它是一个黑客。

用于测试的完整类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcApplication2.Controllers
{
[HandleError]
[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Title"] = "Home Page";
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }


    public ActionResult About()
    {
        ViewData["Title"] = "About Page";

        return View();
    }


    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Index")
        {
            filterContext.Cancel = true;
            filterContext.Result = Index();
        }
    }
}
}

答案 3 :(得分:1)

可能不是真的,但我写了自定义属性:

public class SelectableAuthorizeAttribute : AuthorizeAttribute
{
    public SelectableAuthorizeAttribute(params Type[] typesToExclude)
    {
        _typesToExlude = typesToExclude;
    }

    private readonly Type[] _typesToExlude;

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        bool skipAuthorization = _typesToExlude.Any(type => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == type);

        if (!skipAuthorization)
        {
            base.OnAuthorization(filterContext);
        }
    }
}

然后在我的全球档案中注册:

filters.Add(new SelectableAuthorizeAttribute(typeof(MyController)));

希望它对某人有用