我正在为我的动作方法MyAuthorizeAttribute写我自己的自定义属性,我仍在忙着编写代码,这是我的部分代码:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public new Role Roles;
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (Roles != 0) // Did it this way to see what the value of Roles was
return;
// Here I am going to get a list of user roles
// I'm doing my own database calls
filterContext.Result = new HttpUnauthorizedResult();
}
}
这是我的角色枚举:
public enum Role
{
Administrator = 1,
SuperAdministrator = 2
}
我的行动方法:
[MyAuthorize(Roles = Role.Administrator|Role.SuperAdministrator)]
public ActionResult Create()
{
return View();
}
我没有使用Roles =“Administrator,SuperAdministrator”的原因是角色是硬编码的。如果角色名称发生变化,我不希望有100个地方可以更改。
根据我的方法,当它到达if(Roles!= 0)然后Roles总值为3时,我如何检查这两个角色是否在特定用户的用户角色列表中?
我在这里做得对吗?如果不是,我将如何实现这一点?它不一定是我做的方式。
答案 0 :(得分:6)
如果MyAuthorizeAttribute接受了IList(或类似的),那会不会更好 这样它既是类型安全的,但你不必使用位标志。 如果你想保存reult,那么位标志很棒,但这是另一种方式。
编辑(现在有例子):
Attribute:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public Role[] RoleList { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
}
//Only role access is implemented here
/*if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}*/
if ((RoleList.Length > 0) && !RoleList.Select(p=>p.ToString()).Any<string>(new Func<string, bool>(user.IsInRole)))
{
return false;
}
return true;
}
}
控制器:
[MyAuthorize(RoleList = new []{Role.Administrator , Role.SuperAdministrator} )]
public ActionResult Create()
{
return View();
}
答案 1 :(得分:3)
如果我理解正确,那么您的问题不在于继承AuthorizeAttribute
,而在于比较枚举值。您可能想要一个可以用作位标志的枚举类型 - 如果是这样,请查看the section about Enumeration Types in the C# Programming guide,尤其是第二部分,“枚举类型为位标志”。
澄清一下:
您现在可以执行以下操作,而不仅仅是检查Roles!=0
:
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// Here you get an enum indicating the roles this user is in. The method
// converts the db information to a Role enum before it is returned.
// If the user is not authenticated, the flag should not be set, i.e. equal 0.
Role userRole = GetUserRolesFromDatabase();
// Bitwise comparison of the two role collections.
if (Roles & userRole > 0)
{
// The user is in at least one of the roles in Roles. Return normally.
return;
}
// If we haven't returned yet, the user doesn't have the required privileges.
new HttpUnauthorizedResult();
}
为了使比较更容易,您可以在枚举上使用以下扩展方法:
public static class RolesExtensions
{
public static bool HasAnyOf(this Roles r1, Roles roles)
{
return (r1 & roles) > 0;
}
}