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


97

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

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

[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 const string RoleA = "RoleA"를 사용하고 있습니까? 또는 당신이 질문에서 쓴대로?
Mukesh Modhvadiya 2014-06-12

답변:


188

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

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

12
이제 맥 Gyver의 가치 아이디어입니다)
기독교 사우어

2
아주 좋은 해결책 :)
aup

1
또한이 솔루션을 많이 좋아합니다. 특히 내 역할을 문자열이 아닌 열거 형으로 만들 수 있기 때문입니다. 이 사용자 지정 권한 부여 특성을 배치하기위한 프로젝트 계층 구조에서 좋은 네임 스페이스와 위치는 무엇입니까?
Simon Shine

4
나는 여기서 무슨 일이 일어나고 있는지 잘 모르겠지만 이것은 도움이되지 않았으며 역할에 관계없이 모든 사용자가 메소드에 액세스 할 수있었습니다.
Urielzen

2
@Urielzen과 동일한 문제이지만 Jerry Finegan ( "System.Web.Mvc.AuthorizeAttribute 및 Not System.Web.Http.AuthorizeAttribute 사용"사용)의 아래 답변에 의해 해결되었습니다
RJB

13

사용자 정의 속성 클래스를 파생 System.Web.Mvc.AuthorizeAttribute시키지 않고 파생하고 있는지 확인하십시오 System.Web.Http.AuthorizeAttribute.

나는 같은 문제에 부딪쳤다. 일단 변경하면 모든 것이 작동했습니다.

사용자 정의 속성 클래스에 다음을 추가 할 수도 있습니다.

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

나는 방금 이것을 시도하고 도서관 System.Web.Http.AuthorizeAttributeINSTEAD OFSystem.Web.Mvc.AuthorizeAttribute
fraser jordan을

10

이 문제를 해결하기 위해 찾은 가장 좋고 간단한 방법은 Authorize 속성에서 역할을 연결하는 것입니다.

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

CustomRole을 사용하여 다음과 같은 상수 문자열을 가진 클래스 :

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

2
가치있는; 그러나 이것은 주석이어야합니다. 대답이 아닙니다.
GhostCat

1
간단하고 우아한 솔루션!
Iosif Bancioiu

귀하의 답변과 수락 된 답변 모두 올바르게 구현되면 승인이 트리거됩니다 (프로덕션 웹 앱에서 수락 된 것을 사용하고 있습니다). 수락 된 답변에 대한 주석을 제거하기위한 편집을 제안합니다.
Eric Eskildsen

3

내가 한 것은 @Tieson의 대답입니다.

나는 그의 대답을 약간 조정했습니다. string.Join 대신 목록으로 변환하지 않으시겠습니까?

내 대답은 다음과 같습니다.

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

그런 다음 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);
            }
        }

이제 역할이 리소스에 액세스 할 수있는 권한이 있는지 확인하고 있습니다.


1

역할이 많지 않으면 사용자 지정 권한 부여 속성이이 문제에 대해 과도하다고 생각합니다.

문자열은 컴파일 타임에 알려야하므로 정의한 역할의 공용 문자열이 포함 된 정적 Role 클래스를 만든 다음 권한을 부여하려는 특정 역할과 함께 쉼표로 구분 된 문자열을 추가하는 것이 좋습니다.

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

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

그런 다음 컨트롤러 클래스 또는 컨트롤러 메서드 (또는 둘 다)에서 권한 부여 속성을 사용할 수 있습니다.

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

1
이 예는 작동하지 않거나 적어도 생각하는 방식이 아닙니다. 예를 들어, 새롭지 만 ADMIN_OR_VIEWER작업에 대한 역할은 중복됩니다 . 역할이 Create아직 없으면 메서드에 액세스 할 수 없기 때문 ADMIN입니다. 이 경우 메서드 VIEWER를 호출 할 수 없습니다 Create.
존 Leidegren

이 솔루션도 확장 가능하지 않습니다. 거기 당신은 다른 작업에 너무 많은 역할을 어디에 포인트가 될 것입니다 그리고 당신은 모든 조합을 만들 야해
EduLopez
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.