2017-01-08 4 views
3

역할 및 URL 경로를 확인하기 위해 사용자 지정 인증 특성을 만들려고합니다.Asp.Net Core에서 역할 및 URL 경로를 확인하기 위해 사용자 지정 인증 특성을 만드는 방법은 무엇입니까?

나는 Policy-Based-Authorization을 사용하여 Asp.Net Core에서이를 수행하는 방법을 찾았지만 구현하려고 시도했지만 incomming url로 HttpContext를 얻을 수 없다.

AuthorizationHandlerContext은 HttpContext에 대한 액세스 권한이 없습니다.

url 경로로 현재 HttpContext를 가져 오는 방법은 무엇입니까? 그것 또는 다른 방법으로 할 수 있습니까?

나는 사용자 정의 정책을 만들기위한이 코드를 시도했다 :

public class RoleUrlValidationHandler : AuthorizationHandler<RoleUrlValidationRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleUrlValidationRequirement requirement) 
    {   
     var path = //Here I need get current url path for example - /api/posts/4545411 
     var pathPart = path.Split('/'); 
     var clientId = pathPart[3]; 

     if (context.User.IsInRole(clientId)) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

내가 다음 만들려 :

[Authorize(Policy="RoleUrlValidation")] //Get ClientId from Url and check User's roles 
public class PostsController : Controller 
{ 
    public ActionResult Get() 
    { 
    } 
} 
+0

Frist 당신은 Autzorize 속성을 구현하지 않아야합니다. 정책의 접근법은 정확합니다. 둘째로 DI를 핸들러 내에서 사용할 수 있습니다. – Tseng

+0

@Tseng 죄송합니다. "Autosorize 속성을 구현하지 않아도됩니다."라는게 무슨 뜻입니까? 그리고 왜? –

+1

@ b.ben : ASP.NET 핵심 팀이 'AuthorizeAttribute' 메서드에 대해 특정 메서드를 가상이 아니거나 삭제 했으므로 더 이상 재정의 할 수 없음을 의미합니다 (예전 ASP.NET에서 작동하는 것처럼). 그들은 대체로 정책 기반 권한 부여를 도입했습니다. 타사가 새 정책을 추가하는 것이보다 유연하고 쉽기 때문입니다. blowdart의 [이 답변] (https://stackoverflow.com/a/31465227/455493)을 참조하십시오. ASP.NET 코어 보안 – Tseng

답변

5

정책 접근 방식은 바로 하나입니다. 당신이 놓친 비트는 Handler에서 Dependency Injection을 사용할 수 있다는 것입니다.

public class RoleUrlValidationHandler : AuthorizationHandler<RoleUrlValidationRequirement> 
{ 
    private readonly IHttpContextAccessor contextAccessor; 
    public class RoleUrlValidationHandler(IHttpContextAccessor contextAccessor) 
    { 
     this.contextAccessor = contextAccessor; 
    } 

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleUrlValidationRequirement requirement) 
    { 
     var httpContext = contextAccessor.HttpContext; 
     var path = httpContext.Request.Path; 
     var pathPart = path.Split('/'); 
     var clientId = pathPart[3]; 

     if (context.User.IsInRole(clientId)) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

당신은 또한 기본적으로 등록되지로 IHttpContextAccessor을 등록 할 수 있습니다.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

추가 비트 : 쉽게 경로에서 매개 변수 값을 읽을 수 있도록

var routeData = httpContext.GetRouteData()를 사용하는 대신에 그것의 값을 읽기 위해 path.Split('/')을 사용하는 것이 좋습니다.

+0

놀라운 것 같습니다. 시도해 볼게. 그렇습니다, 당신 말이 맞습니다. 나는 DI 가능성을 놓쳤습니다. :-) 감사. – Jenan

+0

당신은 httpContext.GetRouteData()를 의미합니까? 유망한 후보자? – Jenan

+0

네, 맞아요. 실제로 위의 코드와 관련이 없으며 일반적인 형식 일뿐입니다. 혼란을 피하기 위해 고칠 것입니다. – Tseng