Sejf przechowywanie wpisów tajnych aplikacji podczas programowania w programie ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autorzy: Rick Anderson i Kirk Larkin

Wyświetl lub pobierz przykładowy kod (jak pobrać)

W tym dokumencie wyjaśniono, jak zarządzać poufnymi danymi dla aplikacji ASP.NET Core na maszynie deweloperów. Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie źródłowym. Wpisy tajne produkcyjne nie powinny być używane do programowania ani testowania. Wpisy tajne nie powinny być wdrażane za pomocą aplikacji. Zamiast tego dostęp do wpisów tajnych produkcyjnych należy uzyskać za pośrednictwem kontrolowanych środków, takich jak zmienne środowiskowe lub usługa Azure Key Vault. Wpisy tajne testowania i produkcji platformy Azure można przechowywać i chronić za pomocą dostawcy konfiguracji usługi Azure Key Vault.

Aby użyć wpisów tajnych użytkownika w aplikacji konsolowej platformy .NET, zobacz ten problem z usługą GitHub.

Zmienne środowiskowe

Zmienne środowiskowe służą do unikania przechowywania wpisów tajnych aplikacji w kodzie lub w lokalnych plikach konfiguracji. Zmienne środowiskowe zastępują wartości konfiguracji dla wszystkich wcześniej określonych źródeł konfiguracji.

Rozważmy aplikację internetową ASP.NET Core, w której włączono zabezpieczenia poszczególnych kont użytkowników. Domyślna parametry połączenia bazy danych jest zawarta appsettings.json w pliku projektu z kluczem DefaultConnection. Domyślnym parametry połączenia jest localDB, który działa w trybie użytkownika i nie wymaga hasła. Podczas wdrażania DefaultConnection aplikacji wartość klucza może zostać zastąpiona wartością zmiennej środowiskowej. Zmienna środowiskowa może przechowywać kompletne parametry połączenia z poufnymi poświadczeniami.

Ostrzeżenie

Zmienne środowiskowe są zwykle przechowywane w postaci zwykłego, niezaszyfrowanego tekstu. W przypadku naruszenia zabezpieczeń maszyny lub procesu zmienne środowiskowe mogą być dostępne dla niezaufanych stron. Mogą być wymagane dodatkowe środki zapobiegające ujawnieniu wpisów tajnych użytkownika.

Separator : nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Symbol __ (podwójne podkreślenie):

  • Jest obsługiwany przez wszystkie platformy. Na przykład separator : nie jest obsługiwany przez powłokę Bash, a separator __ jest.
  • Jest automatycznie zastępowany przez :

Menedżer wpisów tajnych

Narzędzie Secret Manager przechowuje poufne dane podczas tworzenia aplikacji. W tym kontekście element poufnych danych jest wpisem tajnym aplikacji. Wpisy tajne aplikacji są przechowywane w oddzielnej lokalizacji od drzewa projektu. Wpisy tajne aplikacji są skojarzone z określonym projektem lub współużytkowane w kilku projektach. Wpisy tajne aplikacji nie są zaewidencjonowane w kontroli źródła.

Ostrzeżenie

Narzędzie Secret Manager nie szyfruje przechowywanych wpisów tajnych i nie powinno być traktowane jako zaufany magazyn. Jest to tylko do celów programistycznych. Klucze i wartości są przechowywane w JSpliku konfiguracji ON w katalogu profilu użytkownika.

Jak działa narzędzie Secret Manager

Narzędzie Secret Manager ukrywa szczegóły implementacji, takie jak miejsce i sposób przechowywania wartości. Możesz użyć narzędzia bez znajomości tych szczegółów implementacji. Wartości są przechowywane w JSpliku ON w folderze profilu użytkownika komputera lokalnego:

Ścieżka systemu plików:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

W poprzednich ścieżkach plików zastąp UserSecretsId wartość <user_secrets_id> określoną w pliku projektu.

Nie zapisuj kodu, który zależy od lokalizacji lub formatu danych zapisanych za pomocą narzędzia Secret Manager. Te szczegóły implementacji mogą ulec zmianie. Na przykład wartości wpisów tajnych nie są szyfrowane, ale mogą być w przyszłości.

Włączanie magazynu wpisów tajnych

Narzędzie Secret Manager działa na ustawieniach konfiguracji specyficznych dla projektu przechowywanych w profilu użytkownika.

Korzystanie z interfejsu wiersza polecenia

Narzędzie Secret Manager zawiera init polecenie . Aby użyć wpisów tajnych użytkownika, uruchom następujące polecenie w katalogu projektu:

dotnet user-secrets init

Poprzednie polecenie dodaje UserSecretsId element w PropertyGroup pliku projektu. Domyślnie tekst UserSecretsId wewnętrzny elementu jest identyfikatorem GUID. Tekst wewnętrzny jest dowolny, ale jest unikatowy dla projektu.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

Korzystanie z programu Visual Studio

W programie Visual Studio kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań, a następnie wybierz polecenie Zarządzaj wpisami tajnymi użytkownika z menu kontekstowego. Ten gest dodaje UserSecretsId element wypełniony identyfikatorem GUID do pliku projektu.

Jeśli GenerateAssemblyInfo jest false

Jeśli generowanie atrybutów informacji o zestawie jest wyłączone, ręcznie dodaj element UserSecretsIdAttribute w AssemblyInfo.cspliku . Na przykład:

[assembly: UserSecretsId("your_user_secrets_id")]

Podczas ręcznego dodawania atrybutu UserSecretsId do UserSecretsIdAssemblyInfo.cselementu wartość musi być zgodna z wartością w pliku projektu.

Ustawianie wpisu tajnego

Zdefiniuj wpis tajny aplikacji składający się z klucza i jego wartości. Wpis tajny jest skojarzony z wartością UserSecretsId projektu. Na przykład uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

W poprzednim przykładzie dwukropek oznacza, że Movies jest to literał obiektu z właściwością ServiceApiKey .

Narzędzie Secret Manager może być również używane z innych katalogów. --project Użyj opcji , aby podać ścieżkę systemu plików, w której istnieje plik projektu. Na przykład:

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

JSSpłaszczanie struktury w programie Visual Studio

Gest Zarządzanie wpisami tajnymi użytkownika programu Visual Studio otwiera secrets.json plik w edytorze tekstów. Zastąp zawartość secrets.json par klucz-wartość, które mają być przechowywane. Na przykład:

{
  "Movies": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
    "ServiceApiKey": "12345"
  }
}

Struktura JSON jest spłaszczana po modyfikacjach za pośrednictwem metody dotnet user-secrets remove lub dotnet user-secrets set. Na przykład uruchomienie dotnet user-secrets remove "Movies:ConnectionString" zwija Movies literał obiektu. Zmodyfikowany plik wygląda podobnie do następującego JS:

{
  "Movies:ServiceApiKey": "12345"
}

Ustawianie wielu wpisów tajnych

Partię wpisów tajnych można ustawić, potokując JSwł. na set polecenie . W poniższym przykładzie input.json zawartość pliku jest potokowana do set polecenia .

Otwórz powłokę poleceń i wykonaj następujące polecenie:

type .\input.json | dotnet user-secrets set

Uzyskiwanie dostępu do wpisu tajnego

Aby uzyskać dostęp do wpisu tajnego, wykonaj następujące kroki:

  1. Rejestrowanie źródła konfiguracji wpisów tajnych użytkownika
  2. Odczytywanie wpisu tajnego za pośrednictwem interfejsu API konfiguracji

Rejestrowanie źródła konfiguracji wpisów tajnych użytkownika

Dostawca konfiguracji wpisów tajnych użytkownika rejestruje odpowiednie źródło konfiguracji za pomocą interfejsu API konfiguracji platformy .NET.

Aplikacje internetowe ASP.NET Core utworzone za pomocą platformy dotnet new lub programu Visual Studio generują następujący kod:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplication.CreateBuilder inicjuje nowe wystąpienie klasy WebApplicationBuilder ze wstępnie skonfigurowanymi wartościami domyślnymi. Zainicjowany WebApplicationBuilder (builder) udostępnia konfigurację domyślną i wywołuje metodę AddUserSecrets , gdy parametr EnvironmentName to Development:

Odczytywanie wpisu tajnego za pośrednictwem interfejsu API konfiguracji

Rozważmy następujące przykłady odczytywania Movies:ServiceApiKey klucza:

plik Program.cs:

var builder = WebApplication.CreateBuilder(args);
var movieApiKey = builder.Configuration["Movies:ServiceApiKey"];

var app = builder.Build();

app.MapGet("/", () => movieApiKey);

app.Run();

Razor Model strony stron:

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
    }
}

Aby uzyskać więcej informacji, zobacz Konfiguracja na platformie ASP.NET Core.

Mapowanie wpisów tajnych na element POCO

Mapowanie całego literału obiektu na obiekt POCO (prosta klasa .NET z właściwościami) jest przydatne w przypadku agregowania powiązanych właściwości.

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Aby zamapować powyższe wpisy tajne na element POCO, użyj funkcji powiązania grafu obiektów interfejsu API konfiguracji platformy .NET. Poniższy kod wiąże się z niestandardowym MovieSettings elementem POCO i uzyskuje ServiceApiKey dostęp do wartości właściwości:

var moviesConfig = 
    Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;

Wpisy Movies:ConnectionString tajne i Movies:ServiceApiKey są mapowane na odpowiednie właściwości w pliku MovieSettings:

public class MovieSettings
{
    public string ConnectionString { get; set; }

    public string ServiceApiKey { get; set; }
}

Zastępowanie ciągu wpisami tajnymi

Przechowywanie haseł w postaci zwykłego tekstu jest niezabezpieczone. Na przykład baza danych parametry połączenia przechowywana w programie appsettings.json może zawierać hasło dla określonego użytkownika:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;Password=pass123;MultipleActiveResultSets=true"
  }
}

Bezpieczniejszym podejściem jest przechowywanie hasła jako wpisu tajnego. Na przykład:

dotnet user-secrets set "DbPassword" "pass123"

Password Usuń parę klucz-wartość z parametry połączenia w pliku appsettings.json. Na przykład:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;MultipleActiveResultSets=true"
  }
}

Wartość wpisu tajnego SqlConnectionStringBuilder można ustawić we właściwości obiektu Password w celu ukończenia parametry połączenia:

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();

Wyświetlanie listy wpisów tajnych

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets list

Wyświetlane są następujące dane wyjściowe:

Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345

W poprzednim przykładzie dwukropek w nazwach kluczy określa hierarchię obiektów w programie secrets.json.

Usuwanie pojedynczego wpisu tajnego

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets remove "Movies:ConnectionString"

Plik aplikacji secrets.json został zmodyfikowany w celu usunięcia pary klucz-wartość skojarzonej z kluczem Movies:ConnectionString :

{
  "Movies": {
    "ServiceApiKey": "12345"
  }
}

dotnet user-secrets list wyświetla następujący komunikat:

Movies:ServiceApiKey = 12345

Usuń wszystkie wpisy tajne

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets clear

Wszystkie wpisy tajne użytkownika dla aplikacji zostały usunięte z secrets.json pliku:

{}

Uruchomienie dotnet user-secrets list powoduje wyświetlenie następującego komunikatu:

No secrets configured for this application.

Zarządzanie wpisami tajnymi użytkownika za pomocą programu Visual Studio

Aby zarządzać wpisami tajnymi użytkownika w programie Visual Studio, kliknij prawym przyciskiem myszy projekt w Eksploratorze rozwiązań i wybierz polecenie Zarządzaj wpisami tajnymi użytkownika:

Program Visual Studio przedstawiający zarządzanie wpisami tajnymi użytkownika

Migrowanie wpisów tajnych użytkownika z platformy ASP.NET do platformy ASP.NET Core

Zobacz ten problem z usługą GitHub.

Wpisy tajne użytkownika w aplikacjach innych niż internetowe

Projekty przeznaczone Microsoft.NET.Sdk.Web automatycznie obejmują obsługę wpisów tajnych użytkownika. W przypadku projektów przeznaczonych dla Microsoft.NET.Sdkprogramu , takich jak aplikacje konsolowe, zainstaluj jawnie pakiety NuGet rozszerzenia konfiguracji i wpisów tajnych użytkownika.

Za pomocą programu PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

Korzystanie z interfejsu wiersza polecenia platformy .NET:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

Po zainstalowaniu pakietów zainicjuj projekt i ustaw wpisy tajne w taki sam sposób jak w przypadku aplikacji internetowej. W poniższym przykładzie pokazano aplikację konsolową, która pobiera wartość wpisu tajnego ustawionego za pomocą klucza "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"]);
    }
}

Dodatkowe zasoby

Autor : Rick Anderson, Kirk Larkin, Daniel Roth i Scott Addie

Wyświetl lub pobierz przykładowy kod (jak pobrać)

W tym dokumencie wyjaśniono, jak zarządzać poufnymi danymi dla aplikacji ASP.NET Core na maszynie deweloperów. Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie źródłowym. Wpisy tajne produkcyjne nie powinny być używane do programowania ani testowania. Wpisy tajne nie powinny być wdrażane za pomocą aplikacji. Zamiast tego dostęp do wpisów tajnych produkcyjnych należy uzyskać za pośrednictwem kontrolowanych środków, takich jak zmienne środowiskowe lub usługa Azure Key Vault. Wpisy tajne testowania i produkcji platformy Azure można przechowywać i chronić za pomocą dostawcy konfiguracji usługi Azure Key Vault.

Zmienne środowiskowe

Zmienne środowiskowe służą do unikania przechowywania wpisów tajnych aplikacji w kodzie lub w lokalnych plikach konfiguracji. Zmienne środowiskowe zastępują wartości konfiguracji dla wszystkich wcześniej określonych źródeł konfiguracji.

Rozważmy aplikację internetową ASP.NET Core, w której włączono zabezpieczenia poszczególnych kont użytkowników. Domyślna parametry połączenia bazy danych jest zawarta appsettings.json w pliku projektu z kluczem DefaultConnection. Domyślnym parametry połączenia jest localDB, który działa w trybie użytkownika i nie wymaga hasła. Podczas wdrażania DefaultConnection aplikacji wartość klucza może zostać zastąpiona wartością zmiennej środowiskowej. Zmienna środowiskowa może przechowywać kompletne parametry połączenia z poufnymi poświadczeniami.

Ostrzeżenie

Zmienne środowiskowe są zwykle przechowywane w postaci zwykłego, niezaszyfrowanego tekstu. W przypadku naruszenia zabezpieczeń maszyny lub procesu zmienne środowiskowe mogą być dostępne dla niezaufanych stron. Mogą być wymagane dodatkowe środki zapobiegające ujawnieniu wpisów tajnych użytkownika.

Separator : nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Symbol __ (podwójne podkreślenie):

  • Jest obsługiwany przez wszystkie platformy. Na przykład separator : nie jest obsługiwany przez powłokę Bash, a separator __ jest.
  • Jest automatycznie zastępowany przez :

Menedżer wpisów tajnych

Narzędzie Secret Manager przechowuje poufne dane podczas tworzenia aplikacji. W tym kontekście element poufnych danych jest wpisem tajnym aplikacji. Wpisy tajne aplikacji są przechowywane w oddzielnej lokalizacji od drzewa projektu. Wpisy tajne aplikacji są skojarzone z określonym projektem lub współużytkowane w kilku projektach. Wpisy tajne aplikacji nie są zaewidencjonowane w kontroli źródła.

Ostrzeżenie

Narzędzie Secret Manager nie szyfruje przechowywanych wpisów tajnych i nie powinno być traktowane jako zaufany magazyn. Jest to tylko do celów programistycznych. Klucze i wartości są przechowywane w JSpliku konfiguracji ON w katalogu profilu użytkownika.

Jak działa narzędzie Secret Manager

Narzędzie Secret Manager ukrywa szczegóły implementacji, takie jak miejsce i sposób przechowywania wartości. Możesz użyć narzędzia bez znajomości tych szczegółów implementacji. Wartości są przechowywane w JSpliku ON w folderze profilu użytkownika komputera lokalnego:

Ścieżka systemu plików:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

W poprzednich ścieżkach plików zastąp UserSecretsId wartość <user_secrets_id> określoną w pliku projektu.

Nie zapisuj kodu, który zależy od lokalizacji lub formatu danych zapisanych za pomocą narzędzia Secret Manager. Te szczegóły implementacji mogą ulec zmianie. Na przykład wartości wpisów tajnych nie są szyfrowane, ale mogą być w przyszłości.

Włączanie magazynu wpisów tajnych

Narzędzie Secret Manager działa na ustawieniach konfiguracji specyficznych dla projektu przechowywanych w profilu użytkownika.

Narzędzie Secret Manager zawiera init polecenie w zestawie .NET Core SDK 3.0.100 lub nowszym. Aby użyć wpisów tajnych użytkownika, uruchom następujące polecenie w katalogu projektu:

dotnet user-secrets init

Poprzednie polecenie dodaje UserSecretsId element w PropertyGroup pliku projektu. Domyślnie tekst UserSecretsId wewnętrzny elementu jest identyfikatorem GUID. Tekst wewnętrzny jest dowolny, ale jest unikatowy dla projektu.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

W programie Visual Studio kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań, a następnie wybierz polecenie Zarządzaj wpisami tajnymi użytkownika z menu kontekstowego. Ten gest dodaje UserSecretsId element wypełniony identyfikatorem GUID do pliku projektu.

Ustawianie wpisu tajnego

Zdefiniuj wpis tajny aplikacji składający się z klucza i jego wartości. Wpis tajny jest skojarzony z wartością UserSecretsId projektu. Na przykład uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

W poprzednim przykładzie dwukropek oznacza, że Movies jest to literał obiektu z właściwością ServiceApiKey .

Narzędzie Secret Manager może być również używane z innych katalogów. --project Użyj opcji , aby podać ścieżkę systemu plików, w której istnieje plik projektu. Na przykład:

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

JSSpłaszczanie struktury w programie Visual Studio

Gest Zarządzanie wpisami tajnymi użytkownika programu Visual Studio otwiera secrets.json plik w edytorze tekstów. Zastąp zawartość secrets.json par klucz-wartość, które mają być przechowywane. Na przykład:

{
  "Movies": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
    "ServiceApiKey": "12345"
  }
}

Struktura JSON jest spłaszczana po modyfikacjach za pośrednictwem metody dotnet user-secrets remove lub dotnet user-secrets set. Na przykład uruchomienie dotnet user-secrets remove "Movies:ConnectionString" zwija Movies literał obiektu. Zmodyfikowany plik wygląda podobnie do następującego JS:

{
  "Movies:ServiceApiKey": "12345"
}

Ustawianie wielu wpisów tajnych

Partię wpisów tajnych można ustawić, potokując JSwł. na set polecenie . W poniższym przykładzie input.json zawartość pliku jest potokowana do set polecenia .

Otwórz powłokę poleceń i wykonaj następujące polecenie:

type .\input.json | dotnet user-secrets set

Uzyskiwanie dostępu do wpisu tajnego

Aby uzyskać dostęp do wpisu tajnego, wykonaj następujące kroki:

  1. Rejestrowanie źródła konfiguracji wpisów tajnych użytkownika
  2. Odczytywanie wpisu tajnego za pośrednictwem interfejsu API konfiguracji

Rejestrowanie źródła konfiguracji wpisów tajnych użytkownika

Dostawca konfiguracji wpisów tajnych użytkownika rejestruje odpowiednie źródło konfiguracji za pomocą interfejsu API konfiguracji platformy .NET.

Źródło konfiguracji wpisów tajnych użytkownika jest automatycznie dodawane w trybie programowania, gdy projekt wywołuje element CreateDefaultBuilder. CreateDefaultBuilder wywołuje metodę AddUserSecrets , gdy parametr ma wartość EnvironmentNameDevelopment:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Jeśli CreateDefaultBuilder nie jest wywoływana, dodaj źródło konfiguracji wpisów tajnych użytkownika jawnie, wywołując polecenie AddUserSecrets w pliku ConfigureAppConfiguration. Wywołaj wywołanie AddUserSecrets tylko wtedy, gdy aplikacja działa w środowisku deweloperów, jak pokazano w poniższym przykładzie:

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();
    }
}

Odczytywanie wpisu tajnego za pośrednictwem interfejsu API konfiguracji

Jeśli źródło konfiguracji wpisów tajnych użytkownika jest zarejestrowane, interfejs API konfiguracji platformy .NET może odczytywać wpisy tajne. Iniekcja konstruktora może służyć do uzyskiwania dostępu do interfejsu API konfiguracji platformy .NET. Rozważmy następujące przykłady odczytywania Movies:ServiceApiKey klucza:

Klasa uruchamiania:

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 Model strony stron:

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
    }
}

Aby uzyskać więcej informacji, zobacz Konfiguracja dostępu w konfiguracji uruchamiania i dostępu na Razor stronach.

Mapowanie wpisów tajnych na element POCO

Mapowanie całego literału obiektu na obiekt POCO (prosta klasa .NET z właściwościami) jest przydatne w przypadku agregowania powiązanych właściwości.

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Aby zamapować powyższe wpisy tajne na element POCO, użyj funkcji powiązania grafu obiektów interfejsu API konfiguracji platformy .NET. Poniższy kod wiąże się z niestandardowym MovieSettings elementem POCO i uzyskuje ServiceApiKey dostęp do wartości właściwości:

var moviesConfig = 
    Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;

Wpisy Movies:ConnectionString tajne i Movies:ServiceApiKey są mapowane na odpowiednie właściwości w pliku MovieSettings:

public class MovieSettings
{
    public string ConnectionString { get; set; }

    public string ServiceApiKey { get; set; }
}

Zastępowanie ciągu wpisami tajnymi

Przechowywanie haseł w postaci zwykłego tekstu jest niezabezpieczone. Na przykład baza danych parametry połączenia przechowywana w programie appsettings.json może zawierać hasło dla określonego użytkownika:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;Password=pass123;MultipleActiveResultSets=true"
  }
}

Bezpieczniejszym podejściem jest przechowywanie hasła jako wpisu tajnego. Na przykład:

dotnet user-secrets set "DbPassword" "pass123"

Password Usuń parę klucz-wartość z parametry połączenia w pliku appsettings.json. Na przykład:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;MultipleActiveResultSets=true"
  }
}

Wartość wpisu tajnego SqlConnectionStringBuilder można ustawić we właściwości obiektu Password w celu ukończenia parametry połączenia:

public class Startup
{
    private string _connection = null;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(
            Configuration.GetConnectionString("Movies"));
        builder.Password = Configuration["DbPassword"];
        _connection = builder.ConnectionString;

        // code omitted for brevity
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Wyświetlanie listy wpisów tajnych

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets list

Wyświetlane są następujące dane wyjściowe:

Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345

W poprzednim przykładzie dwukropek w nazwach kluczy określa hierarchię obiektów w programie secrets.json.

Usuwanie pojedynczego wpisu tajnego

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets remove "Movies:ConnectionString"

Plik aplikacji secrets.json został zmodyfikowany w celu usunięcia pary klucz-wartość skojarzonej z kluczem MoviesConnectionString :

{
  "Movies": {
    "ServiceApiKey": "12345"
  }
}

dotnet user-secrets list wyświetla następujący komunikat:

Movies:ServiceApiKey = 12345

Usuń wszystkie wpisy tajne

Załóżmy, że plik aplikacji secrets.json zawiera następujące dwa wpisy tajne:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Uruchom następujące polecenie z katalogu, w którym istnieje plik projektu:

dotnet user-secrets clear

Wszystkie wpisy tajne użytkownika dla aplikacji zostały usunięte z secrets.json pliku:

{}

Uruchomienie dotnet user-secrets list powoduje wyświetlenie następującego komunikatu:

No secrets configured for this application.

Zarządzanie wpisami tajnymi użytkownika za pomocą programu Visual Studio

Aby zarządzać wpisami tajnymi użytkownika w programie Visual Studio, kliknij prawym przyciskiem myszy projekt w Eksploratorze rozwiązań i wybierz polecenie Zarządzaj wpisami tajnymi użytkownika:

Program Visual Studio przedstawiający zarządzanie wpisami tajnymi użytkownika

Migrowanie wpisów tajnych użytkownika z platformy ASP.NET do platformy ASP.NET Core

Zobacz ten problem z usługą GitHub.

Wpisy tajne użytkownika w aplikacjach innych niż internetowe

Projekty przeznaczone Microsoft.NET.Sdk.Web automatycznie obejmują obsługę wpisów tajnych użytkownika. W przypadku projektów przeznaczonych dla Microsoft.NET.Sdkprogramu , takich jak aplikacje konsolowe, zainstaluj jawnie pakiety NuGet rozszerzenia konfiguracji i wpisów tajnych użytkownika.

Za pomocą programu PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

Korzystanie z interfejsu wiersza polecenia platformy .NET:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

Po zainstalowaniu pakietów zainicjuj projekt i ustaw wpisy tajne w taki sam sposób jak w przypadku aplikacji internetowej. W poniższym przykładzie pokazano aplikację konsolową, która pobiera wartość wpisu tajnego ustawionego za pomocą klucza "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"]);
    }
}

Dodatkowe zasoby