asp.net mvc decorare con enumerazioni multiple

Ho un controller e voglio che due ruoli siano in grado di accedervi. 1-admin O 2-moderatore

So che puoi fare [Autorizza (ruoli = “admin, moderatori”)] ma ho i miei ruoli in un enum. Con l’enum posso solo autorizzare UN ruolo. Non riesco a capire come autorizzare due.

Ho provato qualcosa come [Authorize (Roles = MyEnum.Admin, MyEnum.Moderator)] ma che non verrà compilato.

Qualcuno una volta ha suggerito questo:

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

ma non funziona come un OR. Penso che in questo caso l’utente debba far parte di ENTRAMBI i ruoli. Sto trascurando qualche syntax? O è questo un caso in cui devo rilasciare la mia authorization personalizzata?

    Prova a utilizzare l’operatore bit OR in questo modo:

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

    Se ciò non funziona, potresti semplicemente tirare il tuo. Al momento ho appena fatto questo sul mio progetto. Ecco cosa ho fatto:

     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() {} 

    Inoltre, assicurati di aggiungere un attributo flags al tuo enum e assicurati che siano tutti valutati da 1 in su. Come questo:

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

    Lo spostamento del bit sinistro fornisce i valori 1, 2, 4, 8, 16 e così via.

    Bene, spero che questo aiuti un po '.

    Ecco una soluzione semplice ed elegante che ti permette di usare semplicemente la seguente syntax:

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

    Quando crei il tuo attributo, usa la parola chiave params nel tuo costruttore:

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

    Questo ti permetterà di usare l’attributo come segue:

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

    Ho combinato alcune delle soluzioni qui per creare il mio preferito. Il mio attributo personalizzato cambia semplicemente i dati per essere nel modulo che SimpleMembership si aspetta e consente di gestire tutto il resto.

    I miei ruoli enum:

     public enum MyRoles { Admin, User, } 

    Per creare ruoli:

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

    Attributo personalizzato:

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

    Usato così:

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

    Provare

     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(); } } 

    Ecco la mia versione, basata sulle risposte di @CalebHC e @Lee Harold.

    Ho seguito lo stile dell’utilizzo dei parametri con nome nell’attributo e ho sovrascritto la proprietà Roles classi di base.

    @ La risposta di CalebHC usa una nuova proprietà di Is che, a mio avviso, non è necessaria, poiché AuthorizeCore() viene sovrascritto (che nella class base utilizza i ruoli), quindi ha senso utilizzare anche i nostri Roles . Usando i nostri Roles possiamo scrivere Roles = Roles.Admin sul controller, che segue lo stile di altri attributi .Net.

    Ho usato due costruttori su CustomAuthorizeAttribute per mostrare i nomi dei gruppi di directory attivi reali passati. In produzione, utilizzo il costruttore parametrizzato per evitare stringhe magiche nella class: i nomi dei gruppi vengono estratti da web.config durante Application_Start() e inoltrati in creazione usando uno strumento DI.

    Avrai bisogno di NotAuthorized.cshtml o simile nella tua cartella Views\Shared o gli utenti non autorizzati visualizzeranno una schermata di errore.

    Ecco il codice per la class base 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; } } 

    Per aggiungere al codice CalebHC e rispondere alla domanda di ssmith sulla gestione degli utenti che hanno più ruoli …

    Il nostro principio di sicurezza personalizzato restituisce un array di stringhe che rappresenta tutti i gruppi / ruoli in cui si trova un utente. Quindi, prima dobbiamo convertire tutte le stringhe dell’array che corrispondono agli elementi nell’enumerazione. Infine, cerchiamo qualsiasi corrispondenza, se è così, l’utente è autorizzato.

    Tieni presente che stiamo reindirizzando un utente non autorizzato a una vista “NotAuthorized” personalizzata.

    L’intera class ha questo aspetto:

     [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" }; } } 

    O potresti concatenare come:

    [Autorizza (Ruoli = Common.Lookup.Item.SecurityRole.Administrator + “,” + Common.Lookup.Item.SecurityRole.Intake)]