ASP.NET Core에서 사용자 지정 권한 부여 특성을 만들려고합니다. 이전 버전에서는 재정의 할 수있었습니다 bool AuthorizeCore(HttpContextBase httpContext)
. 그러나에 더 이상 존재하지 않습니다 AuthorizeAttribute
.
사용자 정의 AuthorizeAttribute를 작성하는 현재 방법은 무엇입니까?
내가 달성하려는 것 : 헤더 인증에서 세션 ID를 받고 있습니다. 그 ID에서 특정 작업이 유효한지 알 수 있습니다.
답변
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();
}
}