允许多个角色访问控制器动作

现在我像这样装饰一个方法,以允许“成员”访问我的控制器动作

[Authorize(Roles="members")]

如何允许多个角色?例如,以下不工作,但它显示了我正在尝试做什么(允许“成员”和“admin”访问):

[Authorize(Roles="members", "admin")]
229190 次浏览

另一种选择是使用一个单独的授权过滤器,但删除内部报价。

[Authorize(Roles="members,admin")]

如果你想使用自定义角色,你可以这样做:

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

在我的控制行动中,我做到了:

[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

    [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

我把答案混在一起,提出了这个方法。

首先,我们为角色访问创建一个枚举。

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)]


在这种方法中,我们使用可选字符串值的数字。 (1= Admin, 2=User,…)

它有助于减小令牌大小和比较性能。