asp.net mvc decorate с несколькими enumsми

У меня есть controller, и я хочу, чтобы две роли имели к нему доступ. 1-админ ИЛИ 2-замедлитель

Я знаю, что вы можете сделать [Authorize (Roles = “admin, moderators”)], но у меня есть свои роли в перечислении. С перечислением я могу разрешать только одну роль. Я не могу понять, как разрешить два.

Я пробовал что-то вроде [Authorize (Roles = MyEnum.Admin, MyEnum.Moderator)], но это не скомпилируется.

Кто-то однажды предложил это:

[Authorize(Roles=MyEnum.Admin)] [Authorize(MyEnum.Moderator)] public ActionResult myAction() { } 

но он не работает как OR. Я думаю, что в этом случае пользователь должен быть частью роли BOTH. Могу ли я игнорировать некоторый синтаксис? Или это случай, когда мне приходится отказываться от собственного пользовательского разрешения?

Попробуйте использовать оператор bit OR следующим образом:

 [Authorize(Roles= MyEnum.Admin | MyEnum.Moderator)] public ActionResult myAction() { } 

Если это не сработает, вы можете просто свернуть свое. Я только что сделал это в своем проекте. Вот что я сделал:

 public class AuthWhereRole : AuthorizeAttribute { ///  /// Add the allowed roles to this property. ///  public UserRole Is; ///  /// Checks to see if the user is authenticated and has the /// correct role to access a particular view. ///  ///  ///  protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) throw new ArgumentNullException("httpContext"); // Make sure the user is authenticated. if (!httpContext.User.Identity.IsAuthenticated) return false; UserRole role = someUser.Role; // Load the user's role here // Perform a bitwise operation to see if the user's role // is in the passed in role values. if (Is != 0 && ((Is & role) != role)) return false; return true; } } // Example Use [AuthWhereRole(Is=MyEnum.Admin|MyEnum.Newbie)] public ActionResult Test() {} 

Кроме того, обязательно добавьте атрибут flags в свой список и убедитесь, что все они оценены с 1 и выше. Как это:

 [Flags] public enum Roles { Admin = 1, Moderator = 1 << 1, Newbie = 1 << 2 etc... } 

Левое смещение битов дает значения 1, 2, 4, 8, 16 и так далее.

Надеюсь, это немного поможет.

Вот простое и элегантное решение, которое позволяет просто использовать следующий синтаксис:

 [AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)] 

Создавая свой собственный атрибут, используйте ключевое слово params в своем конструкторе:

 public class AuthorizeRoles : AuthorizeAttribute { public AuthorizeRoles(params MyEnum[] roles) { ... } protected override bool AuthorizeCore(HttpContextBase httpContext) { ... } } 

Это позволит вам использовать атрибут следующим образом:

 [AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)] public ActionResult myAction() { } 

Я объединил несколько решений здесь, чтобы создать свой личный фаворит. Мой пользовательский атрибут просто изменяет данные в форме, которую ожидает SimpleMembership, и позволяет обрабатывать все остальное.

Мои роли перечислены:

 public enum MyRoles { Admin, User, } 

Чтобы создать роли:

 public static void CreateDefaultRoles() { foreach (var role in Enum.GetNames(typeof(MyRoles))) { if (!Roles.RoleExists(role)) { Roles.CreateRole(role); } } } 

Пользовательский атрибут:

 public class AuthorizeRolesAttribute : AuthorizeAttribute { public AuthorizeRolesAttribute(params MyRoles[] allowedRoles) { var allowedRolesAsStrings = allowedRoles.Select(x => Enum.GetName(typeof(MyRoles), x)); Roles = string.Join(",", allowedRolesAsStrings); } } 

Используется так:

 [AuthorizeRoles(MyRoles.Admin, MyRoles.User)] public ActionResult MyAction() { return View(); } 

Пытаться

 public class CustomAuthorize : AuthorizeAttribute { public enum Role { DomainName_My_Group_Name, DomainName_My_Other_Group_Name } public CustomAuthorize(params Role[] DomainRoles) { foreach (var domainRole in DomainRoles) { var domain = domainRole.ToString().Split('_')[0] + "_"; var role = domainRole.ToString().Replace(domain, "").Replace("_", " "); domain=domain.Replace("_", "\\"); Roles += ", " + domain + role; } Roles = Roles.Substring(2); } } public class HomeController : Controller { [CustomAuthorize(Role.DomainName_My_Group_Name, Role.DomainName_My_Other_Group_Name)] public ActionResult Index() { return View(); } } 

Вот моя версия, основанная на ответах @CalebHC и @Lee Harold.

Я придерживался стиля использования именованных параметров в атрибуте и переопределял свойство Roles базовых classов.

@ Ответ CalebHC использует новое свойство Is которое, как мне кажется, не нужно, потому что AuthorizeCore() переопределяется (который в базовом classе использует роли), поэтому имеет смысл использовать наши собственные Roles . Используя наши собственные Roles мы получаем, чтобы написать Roles = Roles.Admin на controllerе, который следует за стилем других атрибутов .Net.

Я использовал два конструктора для CustomAuthorizeAttribute чтобы отображать имена реальных активных групп каталогов. В производстве я использую параметризованный конструктор, чтобы избежать магических строк в classе: имена групп вытягиваются из web.config во время Application_Start() и передаются в создание с использованием инструмента DI.

Вам понадобится NotAuthorized.cshtml или подобное в вашей папке Views\Shared или неавторизованные пользователи получат экран с ошибкой.

Вот код для базового classа AuthorizationAttribute.cs .

controller:

 public ActionResult Index() { return this.View(); } [CustomAuthorize(Roles = Roles.Admin)] public ActionResult About() { return this.View(); } 

CustomAuthorizeAttribute:

 // The left bit shifting gives the values 1, 2, 4, 8, 16 and so on. [Flags] public enum Roles { Admin = 1, User = 1 << 1 } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class CustomAuthorizeAttribute : AuthorizeAttribute { private readonly string adminGroupName; private readonly string userGroupName; public CustomAuthorizeAttribute() : this("Domain Admins", "Domain Users") { } private CustomAuthorizeAttribute(string adminGroupName, string userGroupName) { this.adminGroupName = adminGroupName; this.userGroupName = userGroupName; } ///  /// Gets or sets the allowed roles. ///  public new Roles Roles { get; set; } ///  /// Checks to see if the user is authenticated and has the /// correct role to access a particular view. ///  /// The HTTP context. /// [True] if the user is authenticated and has the correct role ///  /// This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method. ///  protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } if (!httpContext.User.Identity.IsAuthenticated) { return false; } var usersRoles = this.GetUsersRoles(httpContext.User); return this.Roles == 0 || usersRoles.Any(role => (this.Roles & role) == role); } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } filterContext.Result = new ViewResult { ViewName = "NotAuthorized" }; } private IEnumerable GetUsersRoles(IPrincipal principal) { var roles = new List(); if (principal.IsInRole(this.adminGroupName)) { roles.Add(Roles.Admin); } if (principal.IsInRole(this.userGroupName)) { roles.Add(Roles.User); } return roles; } } 

Чтобы добавить код CalebHC и ответить на вопрос ssmith о работе с пользователями, имеющими несколько ролей …

Наш пользовательский принцип безопасности возвращает массив строк, представляющий все группы / роли, в которых находится пользователь. Поэтому сначала мы должны преобразовать все строки в массиве, соответствующие элементам enums. Наконец, мы ищем любое совпадение – если да, то пользователь авторизован.

Обратите внимание, что мы также перенаправляем неавторизованного пользователя в пользовательский вид «NotAuthorized».

Весь class выглядит следующим образом:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class CustomAuthorizeAttribute : AuthorizeAttribute { ///  /// Add the allowed roles to this property. ///  public Roles Is { get; set; } ///  /// Checks to see if the user is authenticated and has the /// correct role to access a particular view. ///  ///  ///  protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) throw new ArgumentNullException("httpContext"); if (!httpContext.User.Identity.IsAuthenticated) return false; var iCustomPrincipal = (ICustomPrincipal) httpContext.User; var roles = iCustomPrincipal.CustomIdentity .GetGroups() .Select(s => Enum.Parse(typeof (Roles), s)) .ToArray(); if (Is != 0 && !roles.Cast().Any(role => ((Is & role) == role))) { return false; } return true; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentNullException("filterContext"); filterContext.Result = new ViewResult { ViewName = "NotAuthorized" }; } } 

Или вы можете объединиться, как:

[Авторизовать (Роли = Common.Lookup.Item.SecurityRole.Administrator + “,” + Common.Lookup.Item.SecurityRole.Intake)]

  • Как отображать косвенные данные в Jqgrid
  • как реализовать идентификатор ASP.NET для пустого проекта MVC
  • получение значений из вложенного сложного объекта, который передается частичному представлению
  • Почему свойство, которое я хочу высмеять, должно быть виртуальным?
  • Где я могу найти DLL System.Linq.Dynamic?
  • Кто-нибудь рядом со мной просто НЕ получает ASP.NET MVC?
  • Razor actionlink автогенерирует? Length = 7 в URL?
  • Как использовать маршрутизацию ASP.NET MVC и AngularJS?
  • Html.EnumDropdownListFor: отображение текста по умолчанию
  • Условная проверка модели в MVC
  • Просмотр отчетов SSRS на сайте ASP.net MVC
  • Давайте будем гением компьютера.