我正在创建一个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在构造函数中,因为我不知道如何传递它们。
答案 0 :(得分:1)
据我了解,您需要创建自己的AuthorizeAttribute
派生的授权属性,以便您可以实现所需的这些参数,然后您可以覆盖OnAuthorization
方法来实现您的特定逻辑:
或者,您可以实施IAuthorizationFilter
:http://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