AddAuthorization을 사용한 역할 기반 권한 정책
AddAuthorization을 사용한 관리자, 매니저, 전역 관리자(GlobalAdministrators) 권한 정책 구성
이 문서에서는 ASP.NET Core 애플리케이션에서 AddAuthorization
메서드를 사용하여 역할 기반 권한 정책(Role-based Authorization Policies)을 설정하는 방법을 설명합니다.
특히, 전역 관리자(Administrators
+ 특정 이메일), 일반 관리자(Administrators
), 매니저(Managers
) 역할을 기준으로 정책을 구성하는 방법을 다룹니다.
코드 예시
https://github.com/VisualAcademy/Hawaso
#region GlobalAdministrators Policy 설정
// GlobalAdministrators 이메일 목록 읽기
// - appsettings.json의 "AuthorizationSettings:GlobalAdministrators" 배열을 읽어옵니다.
// - 값이 없으면 빈 리스트로 초기화하여 NullReferenceException을 방지합니다.
var globalAdminEmails = builder.Configuration
.GetSection("AuthorizationSettings:GlobalAdministrators")
.Get<List<string>>() ?? new List<string>();
#endregion
#region Authorization Policy Configuration
// 정책 기반 권한 설정
builder.Services.AddAuthorization(options =>
{
// "AdminOnly" 정책:
// - "Administrators" 역할을 가진 사용자만 접근 허용
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Administrators"));
// "ManagerOnly" 정책:
// - "Managers" 역할을 가진 사용자만 접근 허용
options.AddPolicy("ManagerOnly", policy =>
policy.RequireRole("Managers"));
#region GlobalAdministrators Policy 설정
// "GlobalAdministrators" 정책 정의
// - 조건 1: "Administrators" 역할(Role)에 속해야 합니다.
// - 조건 2: 이메일(ClaimTypes.Email)이 globalAdminEmails 리스트에 포함되어야 합니다.
options.AddPolicy("GlobalAdministrators", policy =>
policy.RequireAssertion(context =>
context.User.IsInRole("Administrators") &&
context.User.HasClaim(c =>
c.Type == ClaimTypes.Email &&
globalAdminEmails.Contains(c.Value, StringComparer.OrdinalIgnoreCase))
)
);
#endregion
});
#endregion
appsettings.json 설정 예시
{
"AppName": "Hawaso",
"AuthorizationSettings": {
"GlobalAdministrators": [
"a@a.com",
"b@b.com"
]
}
}
AuthorizationSettings:GlobalAdministrators
배열에 이메일을 등록하여, 코드 수정 없이 관리자가 될 이메일을 손쉽게 변경할 수 있습니다.
설정 값이 없을 경우를 대비하여 빈 리스트(new List<string>()
)로 안전하게 초기화합니다.
정책별 설명
AddAuthorization
메서드는 애플리케이션 전반에서 사용할 정책 기반 권한(Policy-Based Authorization)을 정의합니다.AddPolicy
메서드를 사용하여 고유한 정책 이름과 조건을 설정할 수 있습니다.RequireRole
메서드는 지정된 역할(Role)을 가진 사용자만 해당 정책을 통과할 수 있도록 제한합니다.RequireAssertion
메서드를 사용하면 역할(Role)과 이메일(Claim) 같은 복합 조건을 자유롭게 작성할 수 있습니다.
정책 적용 예시
AdminOnly 정책 적용
@attribute [Authorize(Policy = "AdminOnly")]
Administrators
역할을 가진 사용자만 접근할 수 있습니다.
ManagerOnly 정책 적용
@attribute [Authorize(Policy = "ManagerOnly")]
Managers
역할을 가진 사용자만 접근할 수 있습니다.
GlobalAdministrators 정책 적용
@attribute [Authorize(Policy = "GlobalAdministrators")]
Administrators
역할을 가지면서, 등록된 이메일 목록에 포함된 사용자만 접근할 수 있습니다.
주의사항
AddAuthorization
메서드는 한 번만 호출해야 하며, 중복 호출할 경우 마지막 설정만 적용됩니다.- 정책 이름은 중복되면 안 됩니다.
RequireRole
메서드는 내부적으로User.IsInRole
메서드를 기반으로 작동하므로, 역할 이름을 정확히 일치시켜야 합니다.RequireAssertion
메서드를 사용하여 복합 조건을 설정하는 경우, 사용자의Claims
정보가 로그인 시점에 정확히 발급되고 매핑되어야 합니다.- 이메일 리스트를 appsettings.json으로 관리하면, 운영 중에도 코드 수정 없이 권한 대상을 변경할 수 있습니다.
ASP.NET Core UI에서 정책 사용하기
ASP.NET Core에서는 정의된 정책을 UI 레벨에서도 다양하게 활용할 수 있습니다.
주로 Razor Components, Razor Pages, MVC Views에서 메뉴 표시, 버튼 노출, 페이지 접근 제어 등에 적용할 수 있습니다.
Razor 컴포넌트에 [Authorize] 적용
@attribute [Authorize(Policy = "GlobalAdministrators")]
<h3>Global Admin 전용 페이지</h3>
<p>이 페이지는 최고 관리자만 볼 수 있습니다.</p>
이 컴포넌트는 GlobalAdministrators
정책을 통과한 사용자만 접근할 수 있습니다.
Razor Page나 MVC Controller에 [Authorize] 적용
[Authorize(Policy = "AdminOnly")]
public class AdminDashboardModel : PageModel
{
public void OnGet()
{
// 관리자 전용 페이지 로직
}
}
[Authorize(Policy = "ManagerOnly")]
public class ManagerReportsController : Controller
{
public IActionResult Index()
{
return View();
}
}
각각 지정된 역할에 해당하는 사용자만 접근할 수 있도록 보호합니다.
Razor 뷰(.cshtml) 안에서 조건부 렌더링
사용자 권한에 따라 메뉴나 버튼을 동적으로 표시할 수 있습니다.
@inject IAuthorizationService AuthorizationService
@{
var authResult = await AuthorizationService.AuthorizeAsync(User, "GlobalAdministrators");
}
@if (authResult.Succeeded)
{
<li class="nav-item">
<a class="nav-link" href="/Administrations/SpecialManage">
<span class="nav-icon oi oi-star" aria-hidden="true"></span> Global Admin Panel
</a>
</li>
}
GlobalAdministrators
권한을 가진 사용자만 해당 메뉴가 렌더링됩니다.
버튼 표시/숨김 제어
@{
var adminOnly = await AuthorizationService.AuthorizeAsync(User, "AdminOnly");
}
@if (adminOnly.Succeeded)
{
<button class="btn btn-primary">관리자 전용 버튼</button>
}
권한이 없는 사용자는 버튼 자체가 렌더링되지 않습니다.
이는 UI 보안과 사용자 경험(UX)을 동시에 향상시키는 방법입니다.
UI 사용 시 주의사항
IAuthorizationService
는 Razor View(.cshtml)나 Razor Component(.razor) 파일 상단에서@inject
를 통해 주입해야 합니다.AuthorizeAsync(User, "PolicyName")
메서드는 비동기 메서드이므로await
를 반드시 사용해야 합니다.- UI에서 메뉴나 버튼을 숨기더라도, 서버 측 API나 PageModel에도
[Authorize(Policy = "...")]
를 적용하여 이중 보호를 해야 합니다.
관련 문서
- Microsoft Docs: Authorization in ASP.NET Core
- ASP.NET Core Security Fundamentals
- ASP.NET Core Authorization Policies and Requirements