web-dev-qa-db-fra.com

Autoriser plusieurs rôles à accéder à l'action du contrôleur

En ce moment, je décore une méthode comme celle-ci pour permettre aux "membres" d'accéder à l'action de mon contrôleur

[Authorize(Roles="members")]

Comment puis-je autoriser plus d'un rôle? Par exemple, ce qui suit ne fonctionne pas mais montre ce que je tente de faire (autoriser les accès "membres" et "admin"):

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

Une autre option consiste à utiliser un seul filtre d'autorisation lors de la publication, mais à supprimer les citations internes.

[Authorize(Roles="members, admin")]
529
Jim Schmehil

Si vous souhaitez utiliser des rôles personnalisés, vous pouvez procéder comme suit:

CustomRoles class: 

public static class CustomRoles
{
    public const string Administrator = "Administrador";
    public const string User = "Usuario";
}

Usage

[Authorize(Roles = CustomRoles.Administrator +","+ CustomRoles.User)]

Si vous avez peu de rôles, vous pouvez peut-être les combiner (pour plus de clarté) comme ceci:

public static class CustomRoles
{
     public const string Administrator = "Administrador";
     public const string User = "Usuario";
     public const string AdministratorOrUser = Administrator + "," + User;  
}

Usage

[Authorize(Roles = CustomRoles.AdministratorOrUser)]
111
Pablo Claus

Une simplification possible consisterait à sous-classe AuthorizeAttribute:

public class RolesAttribute : AuthorizeAttribute
{
    public RolesAttribute(params string[] roles)
    {
        Roles = String.Join(",", roles);
    }
}

Usage:

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

Sémantiquement, c'est la même chose que la réponse de Jim Schmehil.

70
Mihkel Müür

Pour MVC4, en utilisant une Enum (UserRoles) avec mes rôles, j'utilise une AuthorizeAttribute personnalisée.

Sur mon action contrôlée, je fais:

[CustomAuthorize(UserRoles.Admin, UserRoles.User)]
public ActionResult ChangePassword()
{
    return View();
}

Et j'utilise une coutume AuthorizeAttribute comme celle-ci:

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

Cela fait partie de FNHMVC modifié par Fabricio Martínez Tamayo https://github.com/fabriciomrtnz/FNHMVC/

16
Bernardo Loureiro

Si vous vous trouvez souvent en train d'appliquer ces deux rôles, vous pouvez les envelopper dans leur propre autorisation. C'est vraiment une extension de la réponse acceptée.

using System.Web.Mvc;

public class AuthorizeAdminOrMember : AuthorizeAttribute
{
    public AuthorizeAdminOrMember()
    {
        Roles = "members, admin";
    }
}

Et appliquez ensuite votre nouvelle autorisation à l'action. Je pense que cela semble plus propre et se lit facilement.

public class MyController : Controller
{
    [AuthorizeAdminOrMember]
    public ActionResult MyAction()
    {
        return null;
    }
}
2
GER

Meilleur code avec l'ajout d'une sous-classe 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 }
                  }
              );
            }
        }
    }

Comment utiliser cette

[AuthorizeRole(Rolenames.Admin,Rolenames.Member)]

public ActionResult Index()
{
return View();
}
1
kinzzy goel

Une autre solution claire consiste à utiliser des constantes pour respecter les conventions et ajouter plusieurs attributs [Autoriser]. Regarde ça:

public static class RolesConvention
{
    public const string Administrator = "Administrator";
    public const string Guest = "Guest";
}

Puis dans le contrôleur:

[Authorize(Roles = RolesConvention.Administrator )]
[Authorize(Roles = RolesConvention.Guest)]
[Produces("application/json")]
[Route("api/[controller]")]
public class MyController : Controller
1
Renê R. Silva

Avec AspNetCore 2.x, vous devez procéder de manière légèrement différente:

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

juste l'utiliser comme ça:

[Authorize(YourEnum.Role1, YourEnum.Role2)]