在授权上实施额外业务逻辑的位置?

时间:2014-10-29 11:44:36

标签: .net asp.net-mvc asp.net-roles authorize-attribute

我正在创建一个ASP.NET MVC应用程序,这是我的问题:

当访问控制器中的操作时,除了检查登录的用户是否具有授权属性的允许角色之外,如果用户我想编辑(它的id作为动作参数),我需要包含逻辑概念比登录用户更低的角色(我不想让普通用户编辑管理员等。)

我应该在哪里实现这个逻辑?我想覆盖AuthorizeAttribute中的方法,只需在那里添加这个逻辑,但在这种情况下,我必须发送我想要在属性的参数中编辑的用户,但这是不允许的。

另一种选择是在控制器中创建私有方法,但如果我想在其他控制器中使用此逻辑,我将不得不一次又一次地重复此代码。

什么是正确的解决方案?

[AttributeUsageAttribute( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true )]
public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    private string _roles { get; set; }            
    private UserEntity _user { get; set; }
    private UserEntity _loggedUser { get; set; }

    public AuthorizeRolesAttribute(string Roles, string User, int Id)
    { 
        _user = new UserEntity();
        _loggedUser = new UserEntity();
        _roles = Roles;
    }

    //Called when access is denied
    protected override void HandleUnauthorizedRequest( AuthorizationContext filterContext )
    {                        
        filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary( new { controller = "Account", action = "LogOn" } )
        );                 
    }

    //Core authentication, called before each action
    protected override bool AuthorizeCore( HttpContextBase httpContext )
    {            
        bool b = false;
        string[] roles = _roles.Split(',');
        //Is user logged in?
        if ( httpContext.User.Identity.IsAuthenticated )
        { 
            //If user is logged in and we need a custom check:
            if ( roles.Any(r => httpContext.User.IsInRole(r)) && HasPermission(_user, _loggedUser))
                b = true;
        }
        //Returns true or false, meaning allow or deny. False will call HandleUnauthorizedRequest above
        return b;
    }

    private bool HasPermission(UserEntity user, UserEntity loggedUser)
    {
        if (user.IsAdmin) return false;
        if (loggedUser.IsAdmin || loggedUser.IsApplicationAdmin) return true;                                   

        if (loggedUser.IsAmbassador)
        { 
            if (user.IsApplicationAdmin)
            { return false; }
            else
            { return true; }
        }
        return false;
    }
}

正如您所看到的,目前我只是创建空虚假物品      _user和      _loggedUser在构造函数中,因为我不知道如何传递它们。

1 个答案:

答案 0 :(得分:1)

据我了解,您需要创建自己的AuthorizeAttribute派生的授权属性,以便您可以实现所需的这些参数,然后您可以覆盖OnAuthorization方法来实现您的特定逻辑:

这是您必须覆盖的方法:http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.onauthorization(v=vs.118).aspx

或者,您可以实施IAuthorizationFilterhttp://msdn.microsoft.com/en-us/library/system.web.mvc.iauthorizationfilter(v=vs.118).aspx

最后,您可以在全球范围内注册AuthorizeAttributes和IAuthorizationFilters,因此您不必将它们置于每个操作或控制器之上:http://weblogs.asp.net/gunnarpeipman/asp-net-mvc-3-global-action-filters