ASP.NET MVC4覆盖OnAuthorization以允许角色的白名单

时间:2012-10-09 15:11:31

标签: authentication asp.net-mvc-4 authorization

我有一个ASP.NET MVC4站点,有两种类型的角色:管理员和合作伙伴。

基本上,对站点的所有访问都需要用户进行身份验证并具有管理员角色。 因此,我在FilterConfig.cs(从Global.asax调用)中执行此操作:

public class FilterConfig {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new AuthorizeAttribute { Roles = "Administrator" }); // default deny
    }
}

对于一个控制器,我希望授予具有Partner角色但不具有Adminstrator角色的用户的权限。我知道我可以通过不使用全局过滤器来代替在每个Controller或Action上设置Authorize属性,但是我想要一个白名单方法,而默认情况下所有访问都需要“管理员”角色,然后使用某种形式的白名单

我尝试过使用一个控制器来覆盖OnAuthorization,如下所示:

public class MyController : Controller {
    protected override void OnAuthorization(AuthorizationContext filterContext) {
        if (User.Identity.IsAuthenticated) {
            var attributes = new List<AllowRolesAttribute>();
            attributes.AddRange(filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AllowRolesAttribute>());
            attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(true).OfType<AllowRolesAttribute>());
            foreach (var authorizationAttribute in attributes) {
                foreach (var role in authorizationAttribute.Roles.Split(',')) {
                    if (User.IsInRole(role))
                        return; // Skip authorization because user has one of the allowed roles.
                }
            }
        }
        base.OnAuthorization(filterContext);
    }
}
然后我按照这样定义控制器:

[AllowRoles(Roles = "Partner")]
public class HomeController : MyController
{
    ...

但这不起作用。当我使用角色为“Partner”的用户访问此控制器时,我可以将代码跟踪到内部return语句中,但仍然会将用户重定向到登录页面而不是授权。我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

不确定您是否使用了表单身份验证。可能需要这样的东西?

[AllowRoles(Roles = "Partner")]
public class HomeController : MyController
{     
    FormsAuthentication.RedirectFromLoginPage( "User", false );
    .
    .
    .
}