ASP.NET Core에서 사용자 정의 AuthorizeAttribute를 어떻게 작성합니까?


428

ASP.NET Core에서 사용자 지정 권한 부여 특성을 만들려고합니다. 이전 버전에서는 재정의 할 수있었습니다 bool AuthorizeCore(HttpContextBase httpContext). 그러나에 더 이상 존재하지 않습니다 AuthorizeAttribute.

사용자 정의 AuthorizeAttribute를 작성하는 현재 방법은 무엇입니까?

내가 달성하려는 것 : 헤더 인증에서 세션 ID를 받고 있습니다. 그 ID에서 특정 작업이 유효한지 알 수 있습니다.


어떻게 해야할지 모르겠지만 MVC는 오픈 소스입니다. github 저장소를 가져 와서 IAuthorizationFilter 구현을 찾을 수 있습니다. 오늘 시간이 있다면 나는 당신을 찾고 실제 답변을 게시하지만 약속은 없습니다. github repo : github.com/aspnet/Mvc
bopapa_1979

시간이 없더라도 aspnet / Security 리포지토리 에서 AuthorizeAttribute를 사용하는 MVC 리포지토리에서 github.com/aspnet/Security 의 AuthorizationPolicy 사용법을 찾으십시오 . 또는 MVC 리포지토리에서 관심있는 보안 항목이있는 네임 스페이스 (Microsoft.AspNet.Authorization)를 찾으십시오. 더 도움을 줄 수 없어서 죄송합니다. 행운을 빕니다!
bopapa_1979

답변:


446

ASP.Net Core 팀이 권장하는 접근 방식은 여기에 완전히 문서화 된 새로운 정책 설계를 사용하는 입니다. 새로운 접근 방식의 기본 아이디어는 새로운 [Authorize] 속성을 사용하여 "정책"을 지정하는 것입니다 (예 : [Authorize( Policy = "YouNeedToBe18ToDoThis")]정책이 응용 프로그램의 Startup.cs에 등록되어 일부 코드 블록을 실행하는 경우 (예 : 사용자에게 연령 주장이 있는지 확인) 나이가 18 세 이상인 경우).

정책 설계는 프레임 워크에 큰 도움이되며 ASP.Net Security Core 팀을 소개하도록 권장해야합니다. 즉, 모든 경우에 적합하지 않습니다. 이 접근 방식의 단점은 주어진 컨트롤러 또는 작업에 주어진 클레임 유형이 필요하다고 주장하는 가장 일반적인 요구에 편리한 솔루션을 제공 할 수 없다는 것입니다. 응용 프로그램에 개별 REST 리소스 ( "CanCreateOrder", "CanReadOrder", "CanUpdateOrder", "CanDeleteOrder"등)에 대한 CRUD 작업을 관리하는 수백 개의 개별 권한이있을 수있는 경우 새로운 접근 방식에는 일대일 반복 작업이 필요합니다. 정책 이름과 클레임 이름 간 매핑 (예 :options.AddPolicy("CanUpdateOrder", policy => policy.RequireClaim(MyClaimTypes.Permission, "CanUpdateOrder));) 또는 런타임에 이러한 등록을 수행하기위한 코드 작성 (예 : 데이터베이스에서 모든 클레임 유형을 읽고 위에서 언급 한 호출을 루프로 수행). 대부분의 경우이 접근 방식의 문제점은 불필요한 오버 헤드라는 것입니다.

ASP.Net Core Security 팀은 자체 솔루션을 만들지 말 것을 권장하지만 경우에 따라 가장 신중한 옵션이 될 수 있습니다.

다음은 IAuthorizationFilter를 사용하여 지정된 컨트롤러 또는 작업에 대한 클레임 요구 사항을 표현하는 간단한 방법을 제공하는 구현입니다.

public class ClaimRequirementAttribute : TypeFilterAttribute
{
    public ClaimRequirementAttribute(string claimType, string claimValue) : base(typeof(ClaimRequirementFilter))
    {
        Arguments = new object[] {new Claim(claimType, claimValue) };
    }
}

public class ClaimRequirementFilter : IAuthorizationFilter
{
    readonly Claim _claim;

    public ClaimRequirementFilter(Claim claim)
    {
        _claim = claim;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value);
        if (!hasClaim)
        {
            context.Result = new ForbidResult();
        }
    }
}


[Route("api/resource")]
public class MyController : Controller
{
    [ClaimRequirement(MyClaimTypes.Permission, "CanReadResource")]
    [HttpGet]
    public IActionResult GetResource()
    {
        return Ok();
    }
}

78
이것은 올바른 답변으로 표시되어야합니다. 여기에서는 Microsoft 직원들이 개발자 피드백을 고려하는 방법을 보여줍니다. 나는 그들이 그렇게 "마음에 얽힌"이유를 이해하지 못한다. 왜냐하면 수많은 다른 권한을 갖는 것은 매우 일반적인 상황이기 때문이다. 각 정책마다 하나의 정책을 작성하는 것은 완전한 오버 킬이다. 나는 이것을 오랫동안 찾고있었습니다 ... (나는 이미 거의 2 년 전에 vNext가 아직 내기 일 때이 질문을 물었습니다 : stackoverflow.com/questions/32181400/… 그러나 우리는 여전히 거기에 붙어 있습니다)
Vi100

3
이것은 좋은 물건입니다. 웹 API에는 인증 미들웨어가 있지만 역할별로 권한 부여 권한에 대한 세분화 된 보안이 있습니다. [MyAuthorize (MyClaimTypes.Permission, MyClaimValueTypes.Write, MyPermission.Employee)]와 같은 속성을 입력해야합니다.
Mariano Peinador

4
@Derek Greer : 이것이 가장 좋은 대답입니다. 그러나 조치 필터 권한 부여 후에 실행되는 ActionFilter를 구현합니다. 어쨌든 액션 필터를 구현하고 승인해야합니까?
Jacob Phan

6
@JacobPhan 정확합니다. IAuthorizationFilter 인터페이스를 사용하여 더 잘 구현할 수 있습니다. 변경 사항을 반영하도록 코드를 업데이트했습니다.
Derek Greer

3
그래서 new ForbidResult()일을하지 않는 (원인 예외 / 500)는 관련 인증 체계를 가지고 있지 않기 때문에. 이 경우에 무엇을 사용 하시겠습니까?
Sinaesthetic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.