IT박스

여러 역할이있는 속성 권한 부여

itboxs 2020. 9. 21. 07:31
반응형

여러 역할이있는 속성 권한 부여


한 번에 여러 역할에 대한 권한을 컨트롤러에 추가하고 싶습니다.

일반적으로 다음과 같습니다.

[Authorize(Roles = "RoleA,RoleB,RoleC")]
public async Task<ActionResult> Index()
{
}

하지만 특정 시점에서 변경되거나 확장 될 수 있으므로 내 역할을 const에 저장했습니다.

public const RoleA = "RoleA";
public const RoleB = "RoleB";
public const RoleC = "RoleC";

컴파일 타임에 문자열을 알아야하기 때문에이 작업을 수행 할 수 없습니다.

[Authorize(Roles = string.join(",",RoleA,RoleB,RoleC)]
public async Task<ActionResult> Index()
{
}

문제를 피할 수있는 방법이 있습니까?

나는 단순히 "RoleA, RoleB, RoleC"를 포함하는 const를 작성할 수있다. 그러나 나는 마법의 문자열을 싫어하고 이것은 마법의 문자열이다. 역할 이름을 변경하고 결합 된 문자열을 변경하는 것을 잊는 것은 재앙이 될 것입니다.

MVC5를 사용하고 있습니다. ASP.NET ID와 역할은 컴파일 타임에 알려집니다.


같은 사용자 지정 권한 부여 특성을 만들어보십시오 .

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

여러 컨트롤러에서 역할이 동일하다고 가정하고 도우미 클래스를 만듭니다.

public static class Role
{
    public const string Administrator = "Administrator";
    public const string Assistant = "Assistant";
}

그런 다음 다음과 같이 사용하십시오.

public class MyController : Controller
{
    [AuthorizeRoles(Role.Administrator, Role.Assistant)]
    public ActionResult AdminOrAssistant()
    {                       
        return View();
    }
}

Make sure you are deriving your custom attribute class off System.Web.Mvc.AuthorizeAttribute and NOT System.Web.Http.AuthorizeAttribute.

I ran into the same problem. Once I changed it, everything worked.

You may also want to add the following to your custom attribute class:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 

The best and simplest way I found to resolve this problem is just to concatenate roles in the Authorize attribute.

[Authorize(Roles = CustomRoles.Admin + "," + CustomRoles.OtherRole)]

with CustomRole a class with constant strings like this :

public static class CustomRoles
{
    public const string Admin = "Admin";
    // and so on..
}

What i did is the answer in @Tieson

I tweak a little in his answer. Instead of string.Join why not convert it to list?

Here is my answer:

public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    private new List<string> Roles;
    public AuthorizeRolesAttribute(params string[] roles) : base()
    {
        Roles = roles.toList()
    }
}

And then check the if the role is valid overriding OnAuthorization

public override void OnAuthorization(HttpActionContext actionContext)
{
            if (Roles == null)
                HandleUnauthorizedRequest(actionContext);
            else
            {
                ClaimsIdentity claimsIdentity = HttpContext.Current.User.Identity as ClaimsIdentity;
                string _role = claimsIdentity.FindFirst(ClaimTypes.Role).Value;
                bool isAuthorize = Roles.Any(role => role == _role);

                if(!isAuthorize)
                    HandleUnauthorizedRequest(actionContext);
            }
        }

And there you have it, it is now validating if the role is authorized to access the resource


I feel like a custom authorize attribute is overkill for this issue unless you have a large amount of roles.

Since the string must be known at compile time, why not make a static Role class that contains public strings of the roles you have defined, and then add comma separated strings with certain roles that you want to authorize:

public static class Roles
{
    public const string ADMIN = "Admin";
    public const string VIEWER = "Viewer";

    public const string ADMIN_OR_VIEWER = ADMIN + "," + VIEWER;
}

And then you can use the Authorize Attribute like so on the Controller Class or the Controller Method (or both):

[Authorize(Roles = Roles.ADMIN]
public class ExampleController : Controller
{
    [Authorize(Roles = Roles.ADMIN_OR_VIEWER)
    public ActionResult Create()
    {
        ..code here...
    }
}

참고URL : https://stackoverflow.com/questions/24181888/authorize-attribute-with-multiple-roles

반응형