권한부여: 클레임 기반 권한부여

등록일시: 2017-01-15 08:00,  수정일시: 2017-01-20 11:12
조회수: 6,795
이 문서는 ASP.NET Core 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.
본문에서는 클레임(Claim) 기반의 권한부여 방식에 관해서 살펴봅니다.

신원(Identity)을 생성할 때 신뢰할 수 있는 기관에서 발급한 하나 이상의 클레임을 부여할 수 있습니다. 클레임(Claim)은 주체가 수행할 수 있는 작업보다는 주체가 무엇인지를 표현하는 이름과 값의 쌍입니다. 예를 들어서, 여러분이 지역 운전면허 발급기관에서 발급한 운전 면허증을 갖고 있다고 가정해보겠습니다. 운전 면허증에는 생년월일이 기재되어 있을 것입니다. 이 경우, 클레임 이름은 DateOfBirth가 되고, 클레임 값은 8th June 1970 같은 생년월일, 그리고 발급자는 운전면허 발급기관이 됩니다. 간단한 클레임 기반 권한부여 사례에서는 클레임 값을 검사한 다음, 그 값을 기반으로 리소스에 대한 접근을 허용합니다. 가령, 나이트 클럽에 들어가려고 하면 권한부여 절차가 진행될 것입니다.

이때, 나이트 클럽의 출입문 보안 담당자는 접근을 허용하기 전에, 먼저 생년월일 클레임의 값과 발급자(운전면허 발급기관)를 신뢰할 수 있는지 여부부터 확인합니다.

특정 신원에는 여러 값들 갖고 있는 여러 클레임들이 포함될 수 있으며, 동일한 유형의 클레임들이 다수 포함될 수도 있습니다.

클레임 검사 추가하기

클레임 기반의 권한 검사는 선언적인 방식으로 구성됩니다. 개발자는 요청된 리소스에 사용자가 접근하기 위해서 필요한 클레임을, 그리고 필요에 따라 해당 클레임이 갖고 있어야 하는 값을 컨트롤러나 컨트롤러 액션 코드에 지정하는 방식으로 클레임 기반 권한 검사를 구현합니다. 클레임 요구사항은 정책을 기반으로 수행되기 때문에 개발자는 먼저 클레임 요구사항을 표현하는 정책을 만들어서 등록해야 합니다.

가장 간단한 유형의 클레임 정책에서는 클레임이 존재하는지 여부만 확인하고 값은 검사하지 않습니다.

먼저 해야 할 일은 정책을 작성하고 등록하는 것입니다. 이 작업은 Authorization 서비스 구성의 일부로 수행되며, 일반적으로 Startup.cs 파일의 ConfigureServices() 메서드에 작성됩니다:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
    });
}

이 예제 코드에서 등록되는 EmployeeOnly 정책은 현재 신원에 EmployeeNumber 클레임이 존재하는지 여부를 검사합니다.

그런 다음, Authorize 어트리뷰트의 Policy 속성에 정책 이름을 지정함으로써 정책을 적용할 수 있습니다:

[Authorize(Policy = "EmployeeOnly")]
public IActionResult VacationBalance()
{
    return View();
}

컨트롤러 전체에 Authorize 어트리뷰트를 적용할 수도 있으며, 이 경우 정책과 일치하는 신원들만 해당 컨트롤러의 모든 액션에 접근이 허용됩니다:

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }
}

컨트롤러 전체를 Authorize 어트리뷰트로 보호하지만 특정 액션에 대한 익명 접근은 허용하고 싶다면, 해당 액션에 AllowAnonymous 어트리뷰트를 적용합니다:

[Authorize(Policy = "EmployeeOnly")]
public class VacationController : Controller
{
    public ActionResult VacationBalance()
    {
    }

    [AllowAnonymous]
    public ActionResult VacationPolicy()
    {
    }
}

대부분의 클레임에는 값이 존재합니다. 정책을 생성할 때 허용되는 값들의 목록을 함께 지정할 수 있습니다. 다음 예제 코드의 정책은 사번이 1, 2, 3, 4, 5인 직원들에 대해서만 성공합니다:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Founders", policy =>
                          policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
    }
}

다중 정책 평가

만약 컨트롤러나 액션에 하나 이상의 정책을 적용했다면 모든 정책을 만족해야만 접근이 허용됩니다. 예를 들어서;

[Authorize(Policy = "EmployeeOnly")]
public class SalaryController : Controller
{
    public ActionResult Payslip()
    {
    }

    [Authorize(Policy = "HumanResources")]
    public ActionResult UpdateSalary()
    {
    }
}

이 예제 코드에서는 컨트롤러에 적용된 정책에 따라, EmployeeOnly 정책을 만족하는 모든 신원이 Payslip 액션에 접근할 수 있습니다. 그러나 UpdateSalary 액션을 호출할 수 있으려면, 신원이 EmployeeOnly 정책과 HumanResources 정책을 모두 만족해야만 합니다.

만약, 생년월일 클레임의 날짜를 가져와서 나이를 계산하고 21살 이상인지 확인하는 것 같은 복잡한 정책이 필요하다면 사용자 지정 처리기를 작성해야 합니다.