现在我像这样装饰一个方法,以允许“成员”访问我的控制器动作
[Authorize(Roles="members")]
如何允许多个角色?例如,以下不工作,但它显示了我正在尝试做什么(允许“成员”和“admin”访问):
[Authorize(Roles="members", "admin")]
另一种选择是使用一个单独的授权过滤器,但删除内部报价。
[Authorize(Roles="members,admin")]
如果你想使用自定义角色,你可以这样做:
CustomRoles类:
CustomRoles
public static class CustomRoles { public const string Administrator = "Administrador"; public const string User = "Usuario"; }
使用
[Authorize(Roles = CustomRoles.Administrator +","+ CustomRoles.User)]
如果你的角色很少,也许你可以把它们结合起来(为了清晰起见):
public static class CustomRoles { public const string Administrator = "Administrador"; public const string User = "Usuario"; public const string AdministratorOrUser = Administrator + "," + User; }
[Authorize(Roles = CustomRoles.AdministratorOrUser)]
对于MVC4,使用Enum (UserRoles)与我的角色,我使用自定义AuthorizeAttribute。
Enum
UserRoles
AuthorizeAttribute
在我的控制行动中,我做到了:
[CustomAuthorize(UserRoles.Admin, UserRoles.User)] public ActionResult ChangePassword() { return View(); }
我使用自定义AuthorizeAttribute,如下所示:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class CustomAuthorize : AuthorizeAttribute { private string[] UserProfilesRequired { get; set; } public CustomAuthorize(params object[] userProfilesRequired) { if (userProfilesRequired.Any(p => p.GetType().BaseType != typeof(Enum))) throw new ArgumentException("userProfilesRequired"); this.UserProfilesRequired = userProfilesRequired.Select(p => Enum.GetName(p.GetType(), p)).ToArray(); } public override void OnAuthorization(AuthorizationContext context) { bool authorized = false; foreach (var role in this.UserProfilesRequired) if (HttpContext.Current.User.IsInRole(role)) { authorized = true; break; } if (!authorized) { var url = new UrlHelper(context.RequestContext); var logonUrl = url.Action("Http", "Error", new { Id = 401, Area = "" }); context.Result = new RedirectResult(logonUrl); return; } } }
这是由fabicio Martínez Tamayo https://github.com/fabriciomrtnz/FNHMVC/修改的FNHMVC的一部分
一个可能的简化是子类AuthorizeAttribute:
public class RolesAttribute : AuthorizeAttribute { public RolesAttribute(params string[] roles) { Roles = String.Join(",", roles); } }
用法:
[Roles("members", "admin")]
从语义上看,它和Jim Schmehil的答案是一样的。
更好的代码添加一个子类AuthorizeRole.cs
AuthorizeRole.cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] class AuthorizeRoleAttribute : AuthorizeAttribute { public AuthorizeRoleAttribute(params Rolenames[] roles) { this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r))); } protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAuthenticated) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "Unauthorized" }, { "controller", "Home" }, { "area", "" } } ); //base.HandleUnauthorizedRequest(filterContext); } else { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "Login" }, { "controller", "Account" }, { "area", "" }, { "returnUrl", HttpContext.Current.Request.Url } } ); } } }
如何使用这个
[AuthorizeRole(Rolenames.Admin,Rolenames.Member)] public ActionResult Index() { return View(); }
另一个清晰的解决方案是使用常量来保持约定,并添加多个[Authorize]属性。看看这个:
public static class RolesConvention { public const string Administrator = "Administrator"; public const string Guest = "Guest"; }
然后在控制器中:
[Authorize(Roles = RolesConvention.Administrator )] [Authorize(Roles = RolesConvention.Guest)] [Produces("application/json")] [Route("api/[controller]")] public class MyController : Controller
如果您发现自己经常应用这两个角色,您可以将它们包装在自己的Authorize中。这实际上是公认答案的延伸。
using System.Web.Mvc; public class AuthorizeAdminOrMember : AuthorizeAttribute { public AuthorizeAdminOrMember() { Roles = "members, admin"; } }
然后将新的授权应用到Action。我觉得这样看起来更干净,也更容易读。
public class MyController : Controller { [AuthorizeAdminOrMember] public ActionResult MyAction() { return null; } }
使用AspNetCore 2。X,你必须走不同的路:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class AuthorizeRoleAttribute : AuthorizeAttribute { public AuthorizeRoleAttribute(params YourEnum[] roles) { Policy = string.Join(",", roles.Select(r => r.GetDescription())); } }
就像这样使用它:
[Authorize(YourEnum.Role1, YourEnum.Role2)]
Intent promptInstall = new Intent(android.content.Intent.ACTION_VIEW); promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); promptInstall.setDataAndType(Uri.parse("http://10.0.2.2:8081/MyAPPStore/apk/Teflouki.apk"), "application/vnd.android.package-archive" ); startActivity(promptInstall);
可以使用授权策略 在Startup.cs < / p >
services.AddAuthorization(options => { options.AddPolicy("admin", policy => policy.RequireRole("SuperAdmin","Admin")); options.AddPolicy("teacher", policy => policy.RequireRole("SuperAdmin", "Admin", "Teacher")); });
在控制器文件中:
[Authorize(Policy = "teacher")] [HttpGet("stats/{id}")] public async Task<IActionResult> getStudentStats(int id) { ... }
“teacher"策略接受3个角色。
[Authorize(Roles="admin")] [Authorize(Roles="members")]
将在需要AND时工作(由问题询问),而这答案显示OR版本。 参见https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-6.0#adding-role-checks
AND
OR
我把答案混在一起,提出了这个方法。
首先,我们为角色访问创建一个枚举。
public enum ERoleAccess { [Description("Admin User")] Admin = 1, [Description("General User")] User = 2, [Description("Editor User")] Editor = 3, }
其次,我们需要一个用于客户MVC授权的属性过滤器。
public class RolesAttribute:AuthorizeAttribute { public RolesAttribute(params ERoleAccess[] roles) { Roles = string.Join(",", roles); } }
最后,我们可以使用“;角色属性”;在控制器或动作上。
[Roles(ERoleAccess.Admin, ERoleAccess.Editor, ERoleAccess.User)]
它有助于减小令牌大小和比较性能。