ASP.NET Core에서 개발 중인 앱 비밀의 안전한 스토리지
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.
Important
이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.
현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.
작성자: Rick Anderson 및 Kirk Larkin
이 문서에서는 개발 머신에서 ASP.NET Core 앱의 중요한 데이터를 관리하는 방법을 설명합니다. 소스 코드 또는 구성 파일에 암호 또는 기타 중요한 데이터를 저장하지 않습니다. 프로덕션 비밀은 개발 또는 테스트에 사용되어서는 안 됩니다. 비밀은 앱과 함께 배포해서는 안 됩니다. 프로덕션 비밀은 Azure Key Vault와 같은 제어된 수단을 통해 액세스해야 합니다. Azure 테스트 및 프로덕션 비밀은 Azure Key Vault 구성 공급자를 사용하여 저장 및 보호할 수 있습니다.
배포된 테스트 및 프로덕션 앱의 인증에 대한 자세한 내용은 보안 인증 흐름을 참조 하세요.
.NET 콘솔 앱에서 사용자 비밀을 사용하려면 이 GitHub 이슈를 참조하세요.
환경 변수
환경 변수는 코드 또는 로컬 구성 파일에 앱 비밀이 저장되지 않도록 하는 데 사용됩니다. 환경 변수는 이전에 지정된 모든 구성 소스에 대한 구성 값을 재정의합니다.
개별 사용자 계정 보안이 활성화된 ASP.NET Core 웹앱을 고려합니다. 기본 데이터베이스 연결 문자열은 DefaultConnection
키가 있는 프로젝트의 appsettings.json
파일에 포함됩니다. 기본 연결 문자열은 사용자 모드로 실행되며 암호가 필요하지 않은 LocalDB용입니다. 앱을 배포하는 동안 DefaultConnection
환경 변수의 값으로 키 값을 재정의할 수 있습니다. 환경 변수는 중요한 자격 증명을 사용하여 전체 연결 문자열을 저장할 수 있습니다.
Warning
환경 변수는 일반적으로 암호화되지 않은 일반 텍스트로 저장됩니다. 머신 또는 프로세스가 손상되면 신뢰할 수 없는 당사자가 환경 변수에 액세스할 수 있습니다. 사용자 비밀 공개를 방지하는 추가 조치가 필요할 수 있습니다.
:
구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 예를 들어 구분 기호 :
는 Bash에서 지원되지 않습니다. 이중 밑줄은 __
다음과 같습니다.
- 모든 플랫폼에서 지원됩니다.
- 콜론으로 자동 대체됩니다
:
.
비밀 관리자
Secret Manager 도구는 애플리케이션 개발 중에 중요한 데이터를 저장합니다. 이 컨텍스트에서 중요한 데이터의 조각은 앱 비밀입니다. 앱 비밀은 프로젝트 트리와는 별도의 위치에 저장됩니다. 앱 비밀은 특정 프로젝트에 연결되거나 여러 프로젝트에서 공유됩니다. 앱 비밀이 소스 제어에 체크 인되지 않습니다.
Warning
비밀 관리자 도구는 저장된 비밀을 암호화하지 않으며 신뢰할 수 있는 저장소로 취급해서는 안 됩니다. 개발용으로만 사용됩니다. 키와 값은 사용자 프로필 디렉터리의 JSON 구성 파일에 저장됩니다.
비밀 관리자 도구의 작동 방식
비밀 관리자 도구는 값이 저장되는 위치 및 방법과 같은 구현 세부 정보를 숨깁니다. 이러한 구현 세부 정보를 몰라도 도구를 사용할 수 있습니다. 값은 로컬 컴퓨터의 사용자 프로필 폴더에 있는 JSON 파일에 저장됩니다.
파일 시스템 경로:
%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
위의 파일 경로에서 <user_secrets_id>
를 프로젝트 파일에 지정된 UserSecretsId
값으로 바꿉니다.
비밀 관리자 도구를 사용하여 저장된 데이터의 위치 또는 형식에 따라 달라지는 코드를 작성하지 마세요. 이러한 구현 세부 정보는 변경될 수 있습니다. 예를 들어 비밀 값은 암호화되지 않습니다.
비밀 스토리지 사용
비밀 관리자 도구는 사용자 프로필에 저장된 프로젝트별 구성 설정에서 작동합니다.
CLI 사용
비밀 관리자 도구에는 init
명령이 포함되어 있습니다. 사용자 비밀을 사용하려면 프로젝트 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets init
이전 명령은 프로젝트 파일의 PropertyGroup
내에 UserSecretsId
요소를 추가합니다. 기본적으로 UserSecretsId
의 내부 텍스트는 GUID입니다. 내부 텍스트는 임의적이지만 프로젝트에 고유합니다.
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>
Visual Studio 사용
Visual Studio의 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 사용자 비밀 관리를 선택합니다. 이 제스처는 GUID로 채워진 UserSecretsId
요소를 프로젝트 파일에 추가합니다.
GenerateAssemblyInfo
가 false
인 경우
어셈블리 정보 특성 생성을 사용하지 않도록 설정한 경우 수동으로 추가AssemblyInfo.cs
합니다UserSecretsIdAttribute. 예시:
[assembly: UserSecretsId("your_user_secrets_id")]
특성을 AssemblyInfo.cs
수동으로 추가할 UserSecretsId
때 값은 UserSecretsId
프로젝트 파일의 값과 일치해야 합니다.
비밀 설정
키와 해당 값으로 구성된 앱 비밀을 정의합니다. 비밀은 프로젝트의 UserSecretsId
값과 연결됩니다. 예를 들어 프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets set "Movies:ServiceApiKey" "12345"
앞의 예제에서 콜론은 Movies
가 ServiceApiKey
속성을 사용하는 개체 리터럴이어야 함을 나타냅니다.
비밀 관리자 도구는 다른 디렉터리에서도 사용할 수 있습니다. --project
옵션을 사용하여 프로젝트 파일이 있는 파일 시스템 경로를 제공합니다. 예시:
dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"
Visual Studio의 JSON 구조 평면화
Visual Studio의 사용자 비밀 관리 제스처는 secrets.json
텍스트 편집기에서 파일을 엽니다. 콘텐츠를 secrets.json
저장할 키-값 쌍으로 바꿉니다. 예시:
{
"Movies": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"ServiceApiKey": "12345"
}
}
JSON 구조는 dotnet user-secrets remove
또는 dotnet user-secrets set
을 통해 수정한 후에 평면화됩니다. 예를 들어 dotnet user-secrets remove "Movies:ConnectionString"
을 실행하면 Movies
개체 리터럴이 축소됩니다. 수정된 파일은 다음 JSON과 유사합니다.
{
"Movies:ServiceApiKey": "12345"
}
여러 비밀 설정
비밀 일괄 처리는 set
명령에 JSON을 파이프하여 설정할 수 있습니다. 다음 예제 input.json
에서는 파일의 내용이 명령에 파이프됩니다 set
.
명령 셸을 열고 다음 명령을 실행합니다.
type .\input.json | dotnet user-secrets set
비밀 액세스
비밀에 액세스하려면 다음 단계를 완료합니다.
사용자 비밀 구성 소스 등록
사용자 비밀 구성 공급자는 .NET 구성 API를 사용하여 적절한 구성 소스를 등록합니다.
dotnet new 또는 Visual Studio를 사용하여 만든 ASP.NET Core 웹앱은 다음 코드를 생성합니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
WebApplication.CreateBuilder는 미리 구성된 기본값을 사용하여 WebApplicationBuilder 클래스의 새 인스턴스를 초기화합니다. 초기화된 WebApplicationBuilder
(builder
)는 기본 구성을 제공하고 EnvironmentName이 Development일 때 AddUserSecrets를 호출합니다.
구성 API를 통해 비밀 읽기
Movies:ServiceApiKey
키를 읽는 다음 예제를 고려하세요.
Program.cs 파일:
var builder = WebApplication.CreateBuilder(args);
var movieApiKey = builder.Configuration["Movies:ServiceApiKey"];
var app = builder.Build();
app.MapGet("/", () => movieApiKey);
app.Run();
Razor Pages 페이지 모델:
public class IndexModel : PageModel
{
private readonly IConfiguration _config;
public IndexModel(IConfiguration config)
{
_config = config;
}
public void OnGet()
{
var moviesApiKey = _config["Movies:ServiceApiKey"];
// call Movies service with the API key
}
}
자세한 내용은 ASP.NET Core의 구성을 참조하세요.
POCO에 비밀 매핑
전체 개체 리터럴을 POCO(속성이 있는 간단한 .NET 클래스)에 매핑하면 관련 속성을 집계하는 데 유용합니다.
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
위의 비밀을 POCO에 매핑하려면 .NET 구성 API의 개체 그래프 바인딩 기능을 사용합니다. 다음 코드는 사용자 지정 MovieSettings
POCO에 바인딩하고 ServiceApiKey
속성 값에 액세스합니다.
var moviesConfig =
Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;
Movies:ConnectionString
및 Movies:ServiceApiKey
비밀은 MovieSettings
의 해당 속성에 매핑됩니다.
public class MovieSettings
{
public string ConnectionString { get; set; }
public string ServiceApiKey { get; set; }
}
비밀을 사용하여 문자열 대체
암호를 일반 텍스트로 저장하는 것은 안전하지 않습니다. 소스 코드 리포지토리에 체크 인될 수 있는 것과 같은 appsettings.json
구성 파일에 비밀을 저장하지 마세요.
예를 들어 저장된 appsettings.json
데이터베이스 연결 문자열 암호를 포함하면 안 됩니다. 대신 암호를 비밀로 저장하고 런타임에 연결 문자열 암호를 포함합니다. 예시:
dotnet user-secrets set "DbPassword" "`<secret value>`"
앞의 <secret value>
예제에서 자리 표시자를 암호 값으로 바꿉다. 개체 Password 의 속성에 비밀 SqlConnectionStringBuilder 값을 설정하여 연결 문자열 암호 값으로 포함합니다.
using System.Data.SqlClient;
var builder = WebApplication.CreateBuilder(args);
var conStrBuilder = new SqlConnectionStringBuilder(
builder.Configuration.GetConnectionString("Movies"));
conStrBuilder.Password = builder.Configuration["DbPassword"];
var connection = conStrBuilder.ConnectionString;
var app = builder.Build();
app.MapGet("/", () => connection);
app.Run();
비밀 나열
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets list
다음과 같은 출력이 표시됩니다.
Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345
앞의 예제에서 키 이름의 콜론은 내의 개체 계층 구조를 secrets.json
나타냅니다.
단일 비밀 제거
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets remove "Movies:ConnectionString"
앱의 secrets.json
파일이 키와 Movies:ConnectionString
연결된 키-값 쌍을 제거하도록 수정되었습니다.
{
"Movies": {
"ServiceApiKey": "12345"
}
}
dotnet user-secrets list
는 다음 메시지를 표시합시다.
Movies:ServiceApiKey = 12345
모든 비밀 제거
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets clear
앱의 모든 사용자 비밀이 파일에서 secrets.json
삭제되었습니다.
{}
dotnet user-secrets list
를 실행하면 다음 메시지가 표시됩니다.
No secrets configured for this application.
Visual Studio를 사용하여 사용자 비밀 관리
Visual Studio에서 사용자 비밀을 관리하려면 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 사용자 비밀 관리를 선택합니다.
ASP.NET Framework에서 ASP.NET Core로 사용자 비밀 마이그레이션
이 GitHub 문제를 참조하세요.
비 웹 애플리케이션의 사용자 비밀
대상 Microsoft.NET.Sdk.Web
프로젝트에는 사용자 비밀에 대한 지원이 자동으로 포함됩니다. 콘솔 애플리케이션과 같은 대상 Microsoft.NET.Sdk
프로젝트의 경우 구성 확장 및 사용자 비밀 NuGet 패키지를 명시적으로 설치합니다.
PowerShell 사용:
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets
.NET CLI 사용:
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
패키지가 설치되면 프로젝트를 초기화하고 웹앱과 동일한 방식으로 비밀을 설정합니다. 다음 예제에서는 "AppSecret" 키로 설정된 비밀의 값을 검색하는 콘솔 애플리케이션을 보여 줍니다.
using Microsoft.Extensions.Configuration;
namespace ConsoleApp;
class Program
{
static void Main(string[] args)
{
IConfigurationRoot config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.Build();
Console.WriteLine(config["AppSecret"]);
}
}
추가 리소스
- IIS에서 사용자 비밀에 액세스하는 방법에 대한 자세한 내용은 이 문제와 이 문제를 참조하세요.
- ASP.NET Core의 구성
- ASP.NET Core의 Azure Key Vault 구성 공급자
작성자: Rick Anderson, Kirk Larkin, Daniel Roth 및 Scott Addie
이 문서에서는 개발 머신에서 ASP.NET Core 앱의 중요한 데이터를 관리하는 방법을 설명합니다. 소스 코드 또는 구성 파일에 암호 또는 기타 중요한 데이터를 저장하지 않습니다. 프로덕션 비밀은 개발 또는 테스트에 사용되어서는 안 됩니다. 비밀은 앱과 함께 배포해서는 안 됩니다. 프로덕션 비밀은 Azure Key Vault와 같은 제어된 수단을 통해 액세스해야 합니다. Azure 테스트 및 프로덕션 비밀은 Azure Key Vault 구성 공급자를 사용하여 저장 및 보호할 수 있습니다.
테스트 및 프로덕션 환경에 대한 인증에 대한 자세한 내용은 보안 인증 흐름을 참조 하세요.
환경 변수
환경 변수는 코드 또는 로컬 구성 파일에 앱 비밀이 저장되지 않도록 하는 데 사용됩니다. 환경 변수는 이전에 지정된 모든 구성 소스에 대한 구성 값을 재정의합니다.
개별 사용자 계정 보안이 활성화된 ASP.NET Core 웹앱을 고려합니다. 기본 데이터베이스 연결 문자열은 DefaultConnection
키가 있는 프로젝트의 appsettings.json
파일에 포함됩니다. 기본 연결 문자열은 사용자 모드로 실행되며 암호가 필요하지 않은 LocalDB용입니다. 앱을 배포하는 동안 DefaultConnection
환경 변수의 값으로 키 값을 재정의할 수 있습니다. 환경 변수는 중요한 자격 증명을 사용하여 전체 연결 문자열을 저장할 수 있습니다.
Warning
환경 변수는 일반적으로 암호화되지 않은 일반 텍스트로 저장됩니다. 머신 또는 프로세스가 손상되면 신뢰할 수 없는 당사자가 환경 변수에 액세스할 수 있습니다. 사용자 비밀 공개를 방지하는 추가 조치가 필요할 수 있습니다.
:
구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 예를 들어 구분 기호 :
는 Bash에서 지원되지 않습니다. 이중 밑줄은 __
다음과 같습니다.
- 모든 플랫폼에서 지원됩니다.
- 콜론으로 자동 대체됩니다
:
.
비밀 관리자
Secret Manager 도구는 애플리케이션 개발 중에 중요한 데이터를 저장합니다. 이 컨텍스트에서 중요한 데이터의 조각은 앱 비밀입니다. 앱 비밀은 프로젝트 트리와는 별도의 위치에 저장됩니다. 앱 비밀은 특정 프로젝트에 연결되거나 여러 프로젝트에서 공유됩니다. 앱 비밀이 소스 제어에 체크 인되지 않습니다.
Warning
비밀 관리자 도구는 저장된 비밀을 암호화하지 않으며 신뢰할 수 있는 저장소로 취급해서는 안 됩니다. 개발용으로만 사용됩니다. 키와 값은 사용자 프로필 디렉터리의 JSON 구성 파일에 저장됩니다.
비밀 관리자 도구의 작동 방식
비밀 관리자 도구는 값이 저장되는 위치 및 방법과 같은 구현 세부 정보를 숨깁니다. 이러한 구현 세부 정보를 몰라도 도구를 사용할 수 있습니다. 값은 로컬 컴퓨터의 사용자 프로필 폴더에 있는 JSON 파일에 저장됩니다.
파일 시스템 경로:
%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
위의 파일 경로에서 <user_secrets_id>
를 프로젝트 파일에 지정된 UserSecretsId
값으로 바꿉니다.
비밀 관리자 도구를 사용하여 저장된 데이터의 위치 또는 형식에 따라 달라지는 코드를 작성하지 마세요. 이러한 구현 세부 정보는 변경될 수 있습니다. 예를 들어 비밀 값은 암호화되지 않지만 나중에 암호화될 수 있습니다.
비밀 스토리지 사용
비밀 관리자 도구는 사용자 프로필에 저장된 프로젝트별 구성 설정에서 작동합니다.
비밀 관리자 도구에는 .NET Core SDK 3.0.100 이상의 init
명령이 포함되어 있습니다. 사용자 비밀을 사용하려면 프로젝트 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets init
이전 명령은 프로젝트 파일의 PropertyGroup
내에 UserSecretsId
요소를 추가합니다. 기본적으로 UserSecretsId
의 내부 텍스트는 GUID입니다. 내부 텍스트는 임의적이지만 프로젝트에 고유합니다.
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>
Visual Studio의 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 사용자 비밀 관리를 선택합니다. 이 제스처는 GUID로 채워진 UserSecretsId
요소를 프로젝트 파일에 추가합니다.
비밀 설정
키와 해당 값으로 구성된 앱 비밀을 정의합니다. 비밀은 프로젝트의 UserSecretsId
값과 연결됩니다. 예를 들어 프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets set "Movies:ServiceApiKey" "12345"
앞의 예제에서 콜론은 Movies
가 ServiceApiKey
속성을 사용하는 개체 리터럴이어야 함을 나타냅니다.
비밀 관리자 도구는 다른 디렉터리에서도 사용할 수 있습니다. --project
옵션을 사용하여 프로젝트 파일이 있는 파일 시스템 경로를 제공합니다. 예시:
dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"
Visual Studio의 JSON 구조 평면화
Visual Studio의 사용자 비밀 관리 제스처는 secrets.json
텍스트 편집기에서 파일을 엽니다. 콘텐츠를 secrets.json
저장할 키-값 쌍으로 바꿉니다. 예시:
{
"Movies": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"ServiceApiKey": "12345"
}
}
JSON 구조는 dotnet user-secrets remove
또는 dotnet user-secrets set
을 통해 수정한 후에 평면화됩니다. 예를 들어 dotnet user-secrets remove "Movies:ConnectionString"
을 실행하면 Movies
개체 리터럴이 축소됩니다. 수정된 파일은 다음 JSON과 유사합니다.
{
"Movies:ServiceApiKey": "12345"
}
여러 비밀 설정
비밀 일괄 처리는 set
명령에 JSON을 파이프하여 설정할 수 있습니다. 다음 예제 input.json
에서는 파일의 내용이 명령에 파이프됩니다 set
.
명령 셸을 열고 다음 명령을 실행합니다.
type .\input.json | dotnet user-secrets set
비밀 액세스
비밀에 액세스하려면 다음 단계를 완료합니다.
사용자 비밀 구성 소스 등록
사용자 비밀 구성 공급자는 .NET 구성 API를 사용하여 적절한 구성 소스를 등록합니다.
사용자 비밀 구성 소스는 프로젝트가 CreateDefaultBuilder를 호출할 때 개발 모드에서 자동으로 추가됩니다. EnvironmentName이 Development일 때 CreateDefaultBuilder
는 AddUserSecrets를 호출합니다.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
CreateDefaultBuilder
가 호출되지 않으면 ConfigureAppConfiguration에서 AddUserSecrets를 호출하여 사용자 비밀 구성 소스를 명시적으로 추가합니다. 다음 예제와 같이 개발 환경에서 앱이 실행되는 경우에만 AddUserSecrets
를 호출합니다.
public class Program
{
public static void Main(string[] args)
{
var host = new HostBuilder()
.ConfigureAppConfiguration((hostContext, builder) =>
{
// Add other providers for JSON, etc.
if (hostContext.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Program>();
}
})
.Build();
host.Run();
}
}
구성 API를 통해 비밀 읽기
사용자 비밀 구성 소스가 등록되면 .NET 구성 API가 비밀을 읽을 수 있습니다. 생성자 주입을 사용하여 .NET 구성 API에 액세스할 수 있습니다. Movies:ServiceApiKey
키를 읽는 다음 예제를 고려하세요.
시작 클래스:
public class Startup
{
private string _moviesApiKey = null;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
_moviesApiKey = Configuration["Movies:ServiceApiKey"];
}
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
await context.Response.WriteAsync($"Secret is {result}");
});
}
}
Razor Pages 페이지 모델:
public class IndexModel : PageModel
{
private readonly IConfiguration _config;
public IndexModel(IConfiguration config)
{
_config = config;
}
public void OnGet()
{
var moviesApiKey = _config["Movies:ServiceApiKey"];
// call Movies service with the API key
}
}
자세한 내용은 시작 시 액세스 구성 및 Razor 페이지의 액세스 구성을 참조하세요.
POCO에 비밀 매핑
전체 개체 리터럴을 POCO(속성이 있는 간단한 .NET 클래스)에 매핑하면 관련 속성을 집계하는 데 유용합니다.
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
위의 비밀을 POCO에 매핑하려면 .NET 구성 API의 개체 그래프 바인딩 기능을 사용합니다. 다음 코드는 사용자 지정 MovieSettings
POCO에 바인딩하고 ServiceApiKey
속성 값에 액세스합니다.
var moviesConfig =
Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;
Movies:ConnectionString
및 Movies:ServiceApiKey
비밀은 MovieSettings
의 해당 속성에 매핑됩니다.
public class MovieSettings
{
public string ConnectionString { get; set; }
public string ServiceApiKey { get; set; }
}
비밀을 사용하여 문자열 대체
암호를 일반 텍스트로 저장하는 것은 안전하지 않습니다. 소스 코드 리포지토리에 체크 인될 수 있는 것과 같은 appsettings.json
구성 파일에 비밀을 저장하지 마세요.
예를 들어 저장된 appsettings.json
데이터베이스 연결 문자열 암호를 포함하면 안 됩니다. 대신 암호를 비밀로 저장하고 런타임에 연결 문자열 암호를 포함합니다. 예시:
dotnet user-secrets set "DbPassword" "<secret value>"
앞의 <secret value>
예제에서 자리 표시자를 암호 값으로 바꿉다. 개체 Password 의 속성에 비밀 SqlConnectionStringBuilder 값을 설정하여 연결 문자열 암호 값으로 포함합니다.
using System.Data.SqlClient;
var builder = WebApplication.CreateBuilder(args);
var conStrBuilder = new SqlConnectionStringBuilder(
builder.Configuration.GetConnectionString("Movies"));
conStrBuilder.Password = builder.Configuration["DbPassword"];
var connection = conStrBuilder.ConnectionString;
var app = builder.Build();
app.MapGet("/", () => connection);
app.Run();
비밀 나열
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets list
다음과 같은 출력이 표시됩니다.
Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345
앞의 예제에서 키 이름의 콜론은 내의 개체 계층 구조를 secrets.json
나타냅니다.
단일 비밀 제거
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets remove "Movies:ConnectionString"
앱의 secrets.json
파일이 키와 MoviesConnectionString
연결된 키-값 쌍을 제거하도록 수정되었습니다.
{
"Movies": {
"ServiceApiKey": "12345"
}
}
dotnet user-secrets list
는 다음 메시지를 표시합시다.
Movies:ServiceApiKey = 12345
모든 비밀 제거
앱의 secrets.json
파일에 다음 두 비밀이 포함되어 있다고 가정합니다.
{
"Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"Movies:ServiceApiKey": "12345"
}
프로젝트 파일이 있는 디렉터리에서 다음 명령을 실행합니다.
dotnet user-secrets clear
앱의 모든 사용자 비밀이 파일에서 secrets.json
삭제되었습니다.
{}
dotnet user-secrets list
를 실행하면 다음 메시지가 표시됩니다.
No secrets configured for this application.
Visual Studio를 사용하여 사용자 비밀 관리
Visual Studio에서 사용자 비밀을 관리하려면 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 사용자 비밀 관리를 선택합니다.
ASP.NET Framework에서 ASP.NET Core로 사용자 비밀 마이그레이션
이 GitHub 문제를 참조하세요.
비 웹 애플리케이션의 사용자 비밀
대상 Microsoft.NET.Sdk.Web
프로젝트에는 사용자 비밀에 대한 지원이 자동으로 포함됩니다. 콘솔 애플리케이션과 같은 대상 Microsoft.NET.Sdk
프로젝트의 경우 구성 확장 및 사용자 비밀 NuGet 패키지를 명시적으로 설치합니다.
PowerShell 사용:
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets
.NET CLI 사용:
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
패키지가 설치되면 프로젝트를 초기화하고 웹앱과 동일한 방식으로 비밀을 설정합니다. 다음 예제에서는 "AppSecret" 키로 설정된 비밀의 값을 검색하는 콘솔 애플리케이션을 보여 줍니다.
using Microsoft.Extensions.Configuration;
namespace ConsoleApp;
class Program
{
static void Main(string[] args)
{
IConfigurationRoot config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.Build();
Console.WriteLine(config["AppSecret"]);
}
}
추가 리소스
- IIS에서 사용자 비밀에 액세스하는 방법에 대한 자세한 내용은 이 문제와 이 문제를 참조하세요.
- ASP.NET Core의 구성
- ASP.NET Core의 Azure Key Vault 구성 공급자
ASP.NET Core