2017-10-25 5 views
1

ASP.NET 코어 정체성에 대한 요구 사항 : 다음과 같은 기본 핸들러와계층 정책/난 그냥 ASP.NET 핵심 아이덴티티로 시작하고있어 다음과 같은 요구 사항이 정의

public sealed class IsCustomerUserRequirement : IAuthorizationRequirement 

public sealed class IsSuperUserRequirement : IAuthorizationRequirement 

:

public class IsCustomerUserHandler : AuthorizationHandler<IsCustomerUserRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsCustomerUserRequirement requirement) 
    { 
     if (context.User.HasClaim(_ => _.Type == "customer")) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

public class IsSuperUserHandler : AuthorizationHandler<IsSuperUserRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsSuperUserRequirement requirement) 
    { 
     if (context.User.IsInRole("super_user")) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

 services 
      .AddAuthorization(options => 
      { 
       options.AddPolicy("MustBeSuperUser", policy => policy.Requirements.Add(new IsSuperUserRequirement())); 
       options.AddPolicy("CustomersOnly", policy => policy.Requirements.Add(new IsCustomerUserRequirement())); 
      }); 

을 그리고을 사용하여 적용

나는 그 기본 방침 안에이를 넣을 수 있습니다, 잘 작동합니다.

내 요구 사항 슈퍼 사용자를 허용 할 수있다, 또한 만 지역 고객에 액세스 할customer 주장하지 않고 super_user 역할을하지만 와 원칙을 주장한다.

나는 현재 수동으로 확인하기 위해 핸들러를 변경하여이 구현 한 :

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsCustomerUserRequirement requirement) 
    { 
     if (context.User.HasClaim(_ => _.Type == Claims.Customer) || 
      context.User.IsInRole(Roles.SuperUser)) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 

내 문제 내가 요점 것 같은이 느낌입니다. 앞으로는 각 처리기에서 수퍼 유저 수표를 반복 할 필요가 없도록 이것을 정의하는 더 좋은 방법이 있습니까?


더 큰 그림은 IdentityServer4 (ASP.NET Identity-backed)를 사용하여 인증 한 다음 몇 가지 JWT 기반 클레임 (하나의 클레임, 두 가지 역할)을 사용하여 사용자를 더욱 식별합니다. 응용 프로그램 별 역할/권한 구조 및 Identity Server와 관련이없는 사용자 정의 미들웨어 등이 있습니다. 이 주제에 대해 모범 사례가 있다면 무엇이 있을까요?

+0

netcore에서 권한 부여를 수행하는 새로운 정책 기반 방법이 세분화 된 권한을 가질 때 약간 비합리적인 것으로 나타납니다. 우리는 권한 부여를 처리하기 위해 커스텀 액션 필터 (IAsyncActionFilter'를 상속)를 구현하고, 시작시 설정할 필요가있는 정책들을 사용하는 것보다 좀 더 유연성을 부여했습니다. 사용자는 소유권 주장의 단순한 변형으로 인해 동일한 정책의 X 변형을 원하지 않습니다. – scheien

+0

@scheien 동일한 정책의 변형이 여러 개인 경우 정책 및 요구 사항이 잘못 사용됩니다. 정책에는 일련의 요구 사항이 필요합니다. 이러한 요구 사항은 다양한 요구 사항 조합에 의해 (개별적으로) 충족 될 수 있으며, 요구 사항 처리자가 알아낼 수 있습니다. 그러나 이것이 정책을보다 복잡하게 만들지는 않습니다. - 정확한 상황을 설명하는 질문을 게시하면 새 모델에 맞게 간소화 할 수 있습니다. ASP.NET 핵심 인증 스택은 실제로 매우 깨끗하고 강력합니다. – poke

답변

2

"이 점이 누락 된 것 같습니다." - 예, 포인트가 누락되었습니다. 역할 기반 인증 : 사용자는 고객 또는 수퍼 유저가 될 수 있습니다.

대신 새 모델은 사용자가 무언가에 대한 클레임을 갖고 있으며이를 사용하여 권한을 부여하는 클레임 ​​기반 권한 부여입니다. 따라서 이상적으로 수퍼 유저는 고객이받는 것과 동일한 요구를 받게되고 그런 식으로 리소스에 대한 액세스가 허용됩니다. 그런 주장은 또한 customer이라고 부르지는 않지만, 오히려 사용자의 속성 인 것입니다.

클레임에 따라 역할 기반 인증 모델을 계속 사용할 수는 있지만 으로 혼합해서는 안됩니다. 네가 알아 차렸으니, 결국 조금 이상해진다.

다른 조건을 사용하여 정책을 성공시키는 데는 여러 가지 방법이 있습니다.

options.AddPolicy("MustBeSuperUser", policy => policy.RequireRole("super_user")); 
options.AddPolicy("CustomersOnly", policy => policy.RequireRole("customer", "super_user")); 

그 방법의 CustomersOnly 정책이 모두 customersuper_user 역할에 의해 성취 될 것입니다 : 당신이 역할 만 (대신의 customer 주장을)를 사용한다면, 당신은 단순히 내장 된 방법을 사용할 수 있습니다.

고객에게 역할을 사용하지 않으므로 여기에서 요구 사항 구현을 따라야합니다.인증 요구 사항이 작동하는 방식은 동일한 요구 사항 유형에 대해 여러 개의 처리기를 가질 수 있으며 그 중 하나만 성공해야한다는 것입니다 (아무도 이 실패한 경우).

따라서 IsSuperUserHandler에서 여러 요구 사항을 처리 할 수 ​​있습니다. 이 작품을 만들기 위해 AuthorizationHandler<T> 구현을 따를 수 :

public class IsSuperUserHandler : IAuthorizationHandler 
{ 
    public virtual async Task HandleAsync(AuthorizationHandlerContext context) 
    { 
     foreach (var req in context.Requirements) 
     { 
      if (req is IsSuperUserRequirement || req is IsCustomerUserRequirement) 
      { 
       if (context.User.IsInRole("super_user")) 
        context.Succeed(req); 
      } 
     } 
    } 
} 

그래서 당신의 IsSuperUserHandler 지금 IsSuperUserRequirementIsCustomerUserRequirement 모두 승인 처리기입니다. 따라서 IsCustomerUserRequirement이 필요한 CustomersOnly 정책은 수퍼 유저에게도 적용됩니다.

+0

'고객'이 소유권 주장 인 이유는 고객 ID의 값 (사용자는 고객과 연결되어 있고 본인의 신원 중 일부)을 가지고 있기 때문입니다. 'IsSuperUserHandler'에 대한 최종 해결책은 다중 상속 때문에 작동하지 않습니다. 두 가지 요구 사항을 정책에 추가하려고 시도했지만 대신 의도 한대로 작동하지 않았습니다. (명시 적으로 실패한 핸들러는 없지만 여전히 정책을 충족시키지 못했습니다.) 나는 모든 토큰을 사용자 토큰으로 굽기를 원하지 않으며, 내 소유권 주장은 세분화 된 사용 권한과 동의어가 될 것입니다 .- ( –

+0

나는 두 가지 개념을 혼합하기 때문에 주된 의견에 동의합니다. –

+0

그 이유에 대해 불편을 끼쳐 드려 죄송합니다. 요구 사항 처리기가 인터페이스라고 생각했기 때문에 두 요구 사항 유형을 명시 적으로 처리하는 실제 인증 처리기를 포함하도록 내 답변을 수정했습니다 - 여러 요구 사항을 동일한 정책에 추가하면 모든 요구 사항이 충족되어야합니다. 정책에 분리 된 요구 사항을 적용 할 수있는 방법이 없습니다. – poke