사용자 지정 권한 부여 정책
인터페이스를 IAuthorizationRequirementData 사용하여 특성 정의에서 권한 부여 정책과 관련된 요구 사항을 지정합니다.
샘플 앱
이 문서에서 설명하는 전체 샘플은 AuthRequirementsData 샘플 앱(dotnet/AspNetCore.Docs.Samples GitHub 리포지토리) (다운로드 방법)입니다. 샘플 앱은 사용자에게 최소 연령 처리기를 구현하여 사용자가 21세 이상임을 나타내는 생년월일 클레임을 제시하도록 요구합니다.
최소 연령 권한 부여 특성
MinimumAgeAuthorizeAttribute의 IAuthorizationRequirementData 구현은 인증 연령을 설정합니다.
using Microsoft.AspNetCore.Authorization;
namespace AuthRequirementsData.Authorization;
class MinimumAgeAuthorizeAttribute(int age) : AuthorizeAttribute,
IAuthorizationRequirement, IAuthorizationRequirementData
{
public int Age { get; set; } = age;
public IEnumerable<IAuthorizationRequirement> GetRequirements()
{
yield return this;
}
}
최소 연령 인증 처리기
MinimumAgeAuthorizationHandler 클래스는 제네릭 매개 변수 IAuthorizationRequirement에 의해 MinimumAgeAuthorizeAttribute가 제공한 단일 MinimumAgeAuthorizeAttribute을 처리합니다.
HandleRequirementAsync 메서드는 다음 작업을 수행합니다.
- 사용자의 생년월일 클레임을 가져옵니다.
- 클레임에서 사용자의 나이를 가져옵니다.
- 사용자가 올해 생일을 맞이하지 않은 경우 연령을 조정합니다.
- 사용자가 연령 요구 사항을 충족하는 경우 인증 요구 사항이 성공했음을 표시합니다.
- 데모용으로 로깅을 구현합니다.
using System.Globalization;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
namespace AuthRequirementsData.Authorization;
class MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
: AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
// Check whether a given minimum age requirement is satisfied.
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MinimumAgeAuthorizeAttribute requirement)
{
logger.LogInformation(
"Evaluating authorization requirement for age >= {age}",
requirement.Age);
// Get the user's birth date claim.
var dateOfBirthClaim =
context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth);
if (dateOfBirthClaim != null)
{
// If the user has a date of birth claim, obtain their age.
var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value,
CultureInfo.InvariantCulture);
var age = DateTime.Now.Year - dateOfBirth.Year;
// Adjust age if the user hasn't had a birthday yet this year.
if (dateOfBirth > DateTime.Now.AddYears(-age))
{
age--;
}
// If the user meets the age requirement, mark the authorization
// requirement succeeded.
if (age >= requirement.Age)
{
logger.LogInformation(
"Minimum age authorization requirement {age} satisfied",
requirement.Age);
context.Succeed(requirement);
}
else
{
logger.LogInformation(
"Current user's DateOfBirth claim ({dateOfBirth}) doesn't " +
"satisfy the minimum age authorization requirement {age}",
dateOfBirthClaim.Value,
requirement.Age);
}
}
else
{
logger.LogInformation("No DateOfBirth claim present");
}
return Task.CompletedTask;
}
}
앱의 MinimumAgeAuthorizationHandler 파일에서 IAuthorizationHandler이(가) 싱글톤 Program 서비스로 등록됩니다.
builder.Services.AddSingleton<IAuthorizationHandler,
MinimumAgeAuthorizationHandler>();
사용자는 GreetingsController 특성으로 21세의 나이를 사용할 때 여기서 [MinimumAgeAuthorize({AGE})] 자리 표시자는 연령을 나타내며 최소 연령 정책을 충족하면 {AGE}에 자신의 이름이 표시됩니다.
using Microsoft.AspNetCore.Mvc;
using AuthRequirementsData.Authorization;
namespace AuthRequirementsData.Controllers;
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{
[MinimumAgeAuthorize(21)]
[HttpGet("hello")]
public string Hello() =>
$"Hello {HttpContext.User.Identity?.Name}!";
}
사용자의 생년월일 클레임이 21세 이상임을 나타내는 경우 컨트롤러는 인사말 문자열을 표시하여 200(OK) 상태 코드를 실행합니다. 사용자에게 생년월일 클레임이 없거나 클레임에 21세 이상이 아님을 나타내는 경우 인사말이 표시되지 않고 403(금지됨) 상태 코드가 발급됩니다.
JWT 전달자 인증 서비스는 앱의 Program 파일에 추가됩니다.
builder.Services.AddAuthentication().AddJwtBearer();
앱 설정 파일(appsettings.json)은 JWT 전달자 인증에 대한 대상 그룹 및 발급자를 구성합니다.
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudiences": [
"https://localhost:51100"
],
"ValidIssuer": "dotnet-user-jwts"
}
}
}
앞의 예제에서 localhost 대상 그룹은 앱의 시작 프로필(applicationUrl)에 지정된 Properties/launchSettings.json localhost 주소와 일치합니다.
데모
샘플을 dotnet user-jwts 및 curl로 테스트합니다.
명령 셸의 프로젝트 폴더에서 다음 명령을 실행하여 사용자의 나이를 21세 이상으로 하는 생년월일 클레임을 포함한 JWT 토큰을 생성합니다.
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01
출력은 명령 셸에서 "Token:" 후 토큰을 생성합니다.
New JWT saved with ID '{JWT ID}'.
Name: {USER}
Custom Claims: [http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01]
Token: {TOKEN}
나중에 사용할 수 있도록 토큰의 값(앞의 출력에 자리 표시자가 표시되는 위치 {TOKEN} )을 따로 설정합니다.
온라인 JWT 디코더에서 토큰을 디코딩할 수 있습니다(예: jwt.ms 해당 콘텐츠를 확인하여 사용자의 생년월일이 포함된 클레임이 포함됨 birthdate ).
{
"alg": "HS256",
"typ": "JWT"
}.{
"unique_name": "{USER}",
"sub": "{USER}",
"jti": "{JWT ID}",
"birthdate": "1989-01-01",
"aud": [
"https://localhost:51100",
"http://localhost:51101"
],
"nbf": 1747315312,
"exp": 1755264112,
"iat": 1747315313,
"iss": "dotnet-user-jwts"
}.[Signature]
21세 미만의 사용자를 만드는 값으로 dateofbirth 명령을 다시 실행합니다.
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=2020-01-01
두 번째 토큰의 값을 따로 설정합니다.
Visual Studio에서 또는 .NET CLI의 dotnet watch 명령을 사용하여 앱을 시작합니다.
.NET CLI에서 다음 curl.exe 명령을 실행하여 엔드포인트를 요청합니다 api/greetings/hello .
{TOKEN} 자리 표시자를 이전에 저장한 첫 번째 JWT 전달자 토큰으로 바꿉다.
curl.exe -i -H "Authorization: Bearer {TOKEN}" https://localhost:51100/api/greetings/hello
사용자의 생년월일 클레임이 21세 이상임을 나타내므로 출력은 성공을 나타냅니다.
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Thu, 15 May 2025 22:58:10 GMT
Server: Kestrel
Transfer-Encoding: chunked
Hello {USER}!
로깅은 연령 요구 사항이 충족되었음을 나타냅니다.
MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21
MinimumAgeAuthorizationHandler: Information: Minimum age authorization requirement 21 satisfied
사용자가 21세 미만임을 나타내는 두 번째 토큰을 사용하여 명령을 다시 실행 curl.exe 합니다. 출력은 요구 사항이 충족되지 않음을 나타냅니다. 엔드포인트에 대한 액세스가 금지되어 있습니다(상태 코드 403).
HTTP/1.1 403 Forbidden
Content-Length: 0
Date: Thu, 15 May 2025 22:58:36 GMT
Server: Kestrel
MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21
MinimumAgeAuthorizationHandler: Information: Current user's DateOfBirth claim (2020-01-01) doesn't satisfy the minimum age authorization requirement 21
ASP.NET Core