web-dev-qa-db-ja.com

複数の役割がコントローラーアクションにアクセスできるようにする

今、このようなメソッドをデコレートして、「メンバー」がコントローラーアクションにアクセスできるようにします

[Authorize(Roles="members")]

複数のロールを許可するにはどうすればよいですか?たとえば、以下は機能しませんが、何をしようとしているかを示しています(「メンバー」および「管理者」アクセスを許可します)。

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

もう1つのオプションは、投稿時に単一の承認フィルターを使用し、内部引用符を削除することです。

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

カスタムロールを使用する場合は、次の操作を実行できます。

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)]
115
Pablo Claus

1つの可能な簡略化は、AuthorizeAttributeをサブクラス化することです。

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

使用法:

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

意味的には、ジム・シュメヒルの答えと同じです。

74
Mihkel Müür

MVC4の場合、ロールでEnumUserRoles)を使用して、カスタム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;
        }
    }
}

これは、FabricioMartínezTamayoによって修正されたFNHMVCの一部です https://github.com/fabriciomrtnz/FNHMVC/

16

これらの2つの役割を頻繁に適用していることに気付いた場合は、それらを独自のAuthorizeでラップできます。これは実際に受け入れられた答えの延長です。

using System.Web.Mvc;

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

そして、新しい認証をアクションに適用します。これはすっきりしていて、読みやすいと思います。

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

サブクラス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();
}
1
kinzzy goel

別の明確な解決策は、定数を使用して規則を維持し、複数の[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
1
Renê R. Silva

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