dotnet user-jwts를 사용하여 개발 중인 JSON 웹 토큰 관리
작성자: Rick Anderson
명령줄 도구는 dotnet user-jwts
앱별 로컬 JWT(JSON 웹 토큰 )를 만들고 관리할 수 있습니다.
개요
dotnet user-jwts [<PROJECT>] [command]
dotnet user-jwts [command] -h|--help
설명
프로젝트별 로컬 JSON 웹 토큰을 만들고 관리합니다.
인수
PROJECT | SOLUTION
명령을 적용할 MSBuild 프로젝트입니다. 프로젝트 파일을 지정하지 않으면 MSBuild는 현재 작업 디렉터리에서 proj로 끝나는 파일 확장명이 있는 파일을 검색하고 그 파일을 사용합니다.
명령
명령 | 설명 |
---|---|
clear | 프로젝트에 대해 발급된 모든 JWT를 삭제합니다. |
만들기 | 새 JSON 웹 토큰을 발급합니다. |
remove | 지정된 JWT를 삭제합니다. |
key | JWT를 발급하는 데 사용되는 서명 키를 표시하거나 다시 설정합니다. |
list | 프로젝트에 대해 발급된 JWT를 나열합니다. |
지정된 JWT의 세부 정보를 표시합니다. |
만들기
사용법: dotnet user-jwts create [options]
옵션 | 설명 |
---|---|
-p | --project | 작업할 프로젝트의 경로입니다. 기본값은 현재 디렉터리의 프로젝트입니다. |
--scheme | 생성된 토큰에 사용할 스키마 이름입니다. 기본값은 'Bearer'입니다. |
-n | --name | JWT를 만들 사용자의 이름입니다. 기본값은 현재 환경 사용자입니다. |
--audience | JWT를 만들 대상 그룹입니다. 기본값은 프로젝트의 launchSettings.json에 구성된 URL입니다. |
--issuer | JWT의 발급자입니다. 기본값은 'dotnet-user-jwts'입니다. |
--scope | JWT에 추가할 범위 클레임입니다. 각 범위에 대해 한 번 지정합니다. |
--역할 | JWT에 추가할 역할 클레임입니다. 각 역할에 대해 한 번 지정합니다. |
--claim | JWT에 추가할 클레임입니다. 각 클레임에 대해 "name=value" 서식으로 한 번 지정합니다. |
--not-before | JWT가 'yy-MM-dd [[HH:mm[:ss]]]]] 형식으로 유효하지 않아야 하는 UTC 날짜 및 시간입니다. 기본적으로 JWT가 만들어진 날짜 및 시간으로 설정됩니다. |
--expires-on | JWT가 'yyyy-MM-dd [[[ [HH:mm]]:ss]] 형식으로 만료되어야 하는 UTC 날짜 및 시간입니다. 기본값은 --not-before 날짜 이후 6개월입니다. 이 옵션은 --valid-for 옵션과 함께 사용하면 안 됩니다. |
--valid-for | JWT가 만료되어야 하는 기간입니다. 일의 경우 'd', 시간에는 'h', 분은 'm', 초는 's'와 같은 기간 유형(예: 365d)을 사용하여 지정합니다. 이 옵션은 --expires-on 옵션과 함께 사용하면 안 됩니다. |
-o | --output | 명령의 출력을 표시하는 데 사용할 형식입니다. '기본값', '토큰' 또는 'json' 중 하나를 사용할 수 있습니다. |
-h | --help | 도움말 정보 표시 |
예제
다음 명령을 실행하여 빈 웹 프로젝트를 만들고 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 패키지를 추가합니다.
dotnet new web -o MyJWT
cd MyJWT
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Program.cs
의 내용을 다음 코드로 바꿉니다.
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();
var app = builder.Build();
app.UseAuthorization();
app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
.RequireAuthorization();
app.Run();
이전 코드에서 /secret
에 대한 GET 요청은 401 Unauthorized
오류를 반환합니다. 프로덕션 앱은 자격 증명 집합을 통해 로그인에 대한 응답으로 STS(보안 토큰 서비스)에서 JWT를 가져올 수 있습니다. 로컬 개발 중에 API를 사용하기 위해 dotnet user-jwts
명령줄 도구를 사용하여 앱별 로컬 JWT를 만들고 관리할 수 있습니다.
이 user-jwts
도구는 사용자 비밀 도구와 개념상 유사하며 로컬 컴퓨터의 개발자에게만 유효한 앱의 값을 관리하는 데 사용할 수 있습니다. 실제로 user-jwts 도구는 user-secrets
인프라를 활용하여 JWT가 서명된 키를 관리하고 키가 사용자 프로필에 안전하게 저장되도록 합니다.
user-jwts
도구는 값이 저장되는 위치 및 방법과 같은 구현 세부 정보를 숨깁니다. 구현 세부 정보를 몰라도 도구를 사용할 수 있습니다. 값은 로컬 컴퓨터의 사용자 프로필 폴더에 있는 JSON 파일에 저장됩니다.
파일 시스템 경로:
%APPDATA%\Microsoft\UserSecrets\<secrets_GUID>\user-jwts.json
JWT 만들기
다음 명령은 로컬 JWT를 만듭니다.
dotnet user-jwts create
위의 명령은 JWT를 만들고 프로젝트의 파일을 다음과 유사한 JSON으로 업데이트합니다 appsettings.Development.json
.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudiences": [
"http://localhost:8401",
"https://localhost:44308",
"http://localhost:5182",
"https://localhost:7076"
],
"ValidIssuer": "dotnet-user-jwts"
}
}
}
}
이전 명령에서 만든 JWT 및 ID
를 복사합니다. Curl과 같은 도구를 사용하여 /secret
를 테스트합니다.
curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/secret
여기서 {token}
은 이전에 생성된 JWT입니다.
JWT 보안 정보 표시
다음 명령은 만료, 범위, 역할, 토큰 헤더 및 페이로드 및 압축 토큰을 포함한 JWT 보안 정보를 표시합니다.
dotnet user-jwts print {ID} --show-all
특정 사용자 및 범위에 대한 토큰 만들기
지원되는 만들기 옵션은 이 토픽의 만들기를 참조하세요.
다음 명령은 MyTestUser
라는 사용자에 대한 JWT를 만듭니다.
dotnet user-jwts create --name MyTestUser --scope "myapi:secrets"
이전 명령에는 다음과 유사한 출력이 있습니다.
New JWT saved with ID '43e0b748'.
Name: MyTestUser
Scopes: myapi:secrets
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{Remaining token deleted}
이전 토큰을 사용하여 다음 코드에서 /secret2
엔드포인트를 테스트할 수 있습니다.
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();
var app = builder.Build();
app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
.RequireAuthorization();
app.MapGet("/secret2", () => "This is a different secret!")
.RequireAuthorization(p => p.RequireClaim("scope", "myapi:secrets"));
app.Run();
ASP.NET Core