eff*_*kay 4 security asp.net-mvc
如果我只想让管理员访问名为"ManagerUser"的操作,我知道我可以这样做:
[Authorize( Roles = Constants.ROLES_ADMINISTRATOR )]
public ActionResult ManageUser( string id )
{
}
Run Code Online (Sandbox Code Playgroud)
如果我想让除了管理员以外的所有人访问该怎么办?我不想在函数上编写所有角色:|.
有什么建议/出路吗?
man*_*u08 11
您可以创建自己的自定义Authorize属性,例如"AuthorizeAllExceptAdmin".在该类中,您只需要检查当前用户是否是管理员,如果他们拒绝它,否则接受它.
这是一个很好的教程,但你可能会得到类似的东西:
public class AuthorizeAllExceptAdmin : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !httpContext.User.IsInRole(Constants.ROLES_ADMINISTRATOR);
}
}
Run Code Online (Sandbox Code Playgroud)
然后您的控制器方法变为:
[AuthorizeAllExceptAdmin]
public ActionResult SomethingOnlyNonAdminsCanDo()
{
}
Run Code Online (Sandbox Code Playgroud)
这是一个自定义属性的示例,它接受了拒绝的角色.
public class DoNotAuthorize : AuthorizeAttribute
{
private IEnumerable<string> _rolesToReject;
public DoNotAuthorize(IEnumerable<string> rolesToReject)
{
_rolesToReject = rolesToReject;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
foreach (var role in _rolesToReject)
{
if (httpContext.User.IsInRole(role))
return false;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后您的控制器方法变为:
[DoNotAuthorize(new [] {Constants.ROLES_ADMINISTRATOR})]
public ActionResult SomethingOnlyNonAdminsCanDo()
{
}
Run Code Online (Sandbox Code Playgroud)
在选择上述选项之一之前,我会考虑一下.如果您认为您将拥有多个具有类似授权要求的方法(或整个控制器)(即管理员无法执行的多个操作),那么我会坚持使用非参数化的自定义属性.这样,您可以稍后将它们一起进化(仅通过更改自定义属性).例如,稍后您可能希望管理员能够进入可以执行这些操作的特殊模式.
或者,如果自动化在动作之间变化更大,那么使用参数化列表是有意义的,因为它们将相对独立地发展.
除了创建manu建议的自定义AuthorizeAttribute之外,您还可以使用带有Deny-SecurityAction的PrincipalPermission:
[PrincipalPermission(SecurityAction.Deny, Role="Administrator")]
Run Code Online (Sandbox Code Playgroud)