ASP.NET Core의 역할 기반 권한 부여

ID를 만들 때 하나 이상의 역할에 속할 수 있습니다. 예를 들어, Tracy는 AdministratorUser 역할에도 속할 수 있지만 Scott은 User 역할에만 속할 수 있습니다. 이러한 역할을 만들고 관리하는 방법은 권한 부여 프로세스의 백업 저장소에 따라 달라집니다. 역할은 클래스의 메서드를 IsInRole 통해 개발자에게 ClaimsPrincipal 노출됩니다. AddRoles은 역할 서비스에 추가하여야 합니다.

역할은 클레임에 해당하지만, 모든 클레임이 곧 역할은 아닙니다. ID 발급자에 따라 역할은 그룹 구성원에 대한 클레임 혹은 ID에 대한 실제 클레임을 적용할 수 있는 사용자 집단일 수 있습니다. 하지만 클레임은 개별 사용자에 대한 정보로서 의도를 가지고 있습니다. 역할을 사용하여 사용자에게 클레임을 추가하는 경우 사용자와 그 각각의 클레임 간 경계에 혼란이 올 수 있습니다. 이렇게 혼란 가능성이 있다는 점에서 SPA 템플릿은 역할을 중심으로 설계하지 아니하였습니다. 또한 온-프레미스 레거시 시스템으로부터 마이그레이션하는 조직의 경우로서 수 년 간 역할이 확산되는 경우 역할 클레임이 SPA가 사용할 수 있는 토큰 내에 포함시키기 너무 클 수 있습니다. SPA를 보호하려면 SPA에 대한 Web API 백 엔드 보안을 위한 사용을 Identity 참조하세요.

Identity에 역할 서비스 추가

역할 기반 권한 부여 서비스는 앱의 Identity 설정 내 AddRoles 역할 유형 호출을 통하여 Program.cs 상에서 등록할 수 있습니다. 다음 예제에서 역할 유형은 IdentityRole입니다.

builder.Services.AddDefaultIdentity<IdentityUser>( ... )
    .AddRoles<IdentityRole>()
    ...

역할 검사 추가

역할 기반 권한 부여 확인은 다음의 성격을 가집니다.

  • 선언적이며 요청한 리소스에 액세스하기 위해 현재 사용자가 멤버 자격을 가져야 하는 역할을 지정합니다.
  • Razor 페이지, 컨트롤러, 컨트롤러 내 작업에 적용됩니다.
  • 페이지에 반드시 적용되어야 하며 Razor 페이지 처리기 수준에서는 적용될 수 없습니다.

예를 들어 다음 코드는 AdministrationController의 모든 작업에 대한 액세스를 Administrator 역할의 멤버인 사용자로 제한합니다.

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

여러 역할을 쉼표로 구분된 목록으로 지정할 수 있습니다.

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

SalaryControllerHRManager 역할 또는 Finance 역할 멤버인 사용자만 액세스할 수 있습니다.

여러 특성이 적용되는 경우, 액세스하는 사용자는모든 지정한 역할의 멤버여야 합니다. 다음 샘플에서 사용자는 각각PowerUserControlPanelUser 역할의 멤버여야 합니다.

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

작업 수준에서 추가 역할 권한 부여 특성을 적용하는 것으로서 작업에 대한 액세스를 제한할 수 있습니다.

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

상기 ControlAllPanelController 컨트롤러에서의 경우입니다.

  • Administrator 역할 혹은 PowerUser 역할 멤버는 컨트롤러 및 SetTime 작업에 액세스할 수 있습니다.
  • Administrator 역할의 멤버만 ShutDown 작업에 액세스할 수 있습니다.

컨트롤러를 잠그면서도 다음과 같이 개별 작업에 대한 익명의, 무인증 액세스를 허용할 수 있습니다.

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

Razor 페이지의 경우, 다음 중 하나로서 [Authorize]를 적용할 수 있습니다.

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public IActionResult OnPost() =>
         Content("OnPost RequireAdministratorRole");
}

Important

AuthorizeAttribute를 포함한 필터 특성은 PageModel에만 적용할 수 있으며 특정 페이지 처리기 메서드에 적용할 수 없습니다.

정책 기반 역할 검사

역할 요구 사항은 정책 구문, 즉 개발자가 인증 서비스 설정 부분으로서 애플리케이션 시작 과정에서 개발자가 정책을 등록하는 구문을 통하여 표현할 수도 있습니다. 이러한 경우는 통상 Program.cs 파일에서 발생합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdministratorRole",
         policy => policy.RequireRole("Administrator"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

정책은 [Authorize] 특성의 Policy 속성을 사용하여 적용됩니다.

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

요구 사항에 허용된 역할을 여러 개 지정하려는 경우 RequireRole 메서드에 대한 매개 변수로 지정할 수 있습니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ElevatedRights", policy =>
          policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));
});

var app = builder.Build();

이 예제는 Administrator, PowerUser 또는 BackupAdministrator 역할에 속한 사용자에게 권한을 부여합니다.

ID를 만들 때 하나 이상의 역할에 속할 수 있습니다. 예를 들어, Scott이 사용자 역할에만 속할 때, Tracy는 관리자 및 사용자 역할에 속할 수 있습니다. 이러한 역할을 만들고 관리하는 방법은 권한 부여 프로세스의 백업 저장소에 따라 달라집니다. 역할은 클래스의 메서드를 IsInRole 통해 개발자에게 ClaimsPrincipal 노출됩니다.

역할을 클레임으로 사용하는 것보다, 클레임을 사용하는 것을 권장합니다. SPA(단일 페이지 앱)를 사용하는 경우 SPA에 대한 Web API 백 엔드 보안을 위한 사용을 Identity 참조하세요.

역할 검사 추가

역할 기반 권한 부여 확인은 다음의 성격을 가집니다.

  • 선언적입니다.
  • Razor 페이지, 컨트롤러, 컨트롤러 내 작업에 적용됩니다.
  • 페이지에 반드시 적용되어야 하며 Razor 페이지 처리기 수준에서는 적용될 수 없습니다.

역할 기반 권한 부여 검사에서는 현재 요청한 리소스에 접근하기 위하여 현재 사용자가 멤버 자격을 가져야 하는 역할을 지정합니다.

예를 들어 다음 코드는 AdministrationController의 모든 작업에 대한 액세스를 Administrator 역할의 멤버인 사용자로 제한합니다.

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

여러 역할을 쉼표로 구분된 목록으로 지정할 수 있습니다.

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

SalaryController 컨트롤러는 HRManager 역할 혹은Finance 역할 멤버만 접근할 수 있습니다.

여러 특성을 적용하는 경우 액세스하는 사용자는 지정된 모든 역할의 멤버여야 합니다. 다음 샘플에서는 사용자가 및 PowerUser 역할의 ControlPanelUser 멤버여야 합니다.

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

작업 수준에서 추가 역할 권한 부여 특성을 적용하여 액세스를 추가로 제한할 수 있습니다.

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

컨트롤러 및 작업 수준에서 여러 특성을 적용하는 경우 액세스 권한이 부여되기 전에 모든 특성이 전달되어야 합니다.

[Authorize(Roles = "Administrator")]
public class ControlAllPanelController2 : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator only");

    [Authorize(Roles = "PowerUser")]
    public IActionResult ShutDown() =>
        Content("Administrator && PowerUser");
}

상기 ControlAllPanelController 컨트롤러에서의 경우입니다.

  • Administrator 역할 혹은 PowerUser 역할 멤버는 컨트롤러 및 SetTime 작업에 액세스할 수 있습니다.
  • Administrator 역할의 멤버만 ShutDown 작업에 액세스할 수 있습니다.

또한 컨트롤러를 잠글 수 있지만 개별 작업에 대한 인증되지 않은 익명 액세스를 허용할 수 있습니다.

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

Razor Pages의 경우 다음 중 하나를 통해 [Authorize]를 적용할 수 있습니다.

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public ActionResult OnPost()
    {
    }
}

Important

AuthorizeAttribute를 포함한 필터 특성은 PageModel에만 적용할 수 있으며 특정 페이지 처리기 메서드에 적용할 수 없습니다.

정책 기반 역할 검사

개발자가 시작 시 권한 부여 서비스 구성의 일부로 정책을 등록하는 새 정책 구문을 사용하여 역할 요구 사항을 표현할 수도 있습니다. 일반적으로 파일에서 ConfigureServices() 발생합니다 Startup.cs .

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdministratorRole",
             policy => policy.RequireRole("Administrator"));
    });
}

정책은 [Authorize] 특성 내 Policy 속성을 통해 적용됩니다.

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

요구 사항에 허용된 역할을 여러 개 지정하려는 경우 RequireRole 메서드에 대한 매개 변수로 지정할 수 있습니다.

options.AddPolicy("ElevatedRights", policy =>
                  policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));

이 예제는 Administrator, PowerUser 또는 BackupAdministrator 역할에 속한 사용자에게 권한을 부여합니다.

Identity에 역할 서비스 추가

역할 서비스를 추가하려면 다음을 추가 AddRoles 합니다.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}