Sichere Speicherung von App-Geheimnissen in der Entwicklung in ASP.NET Core

Von Rick Anderson und Kirk Larkin

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

In diesem Dokument wird erläutert, wie vertrauliche Daten für eine ASP.NET Core-App auf einem Entwicklungscomputer verwaltet werden. Speichern Sie niemals Kennwörter oder andere vertrauliche Daten im Quellcode. Produktionsschlüssel sollten nicht für die Entwicklung oder den Test verwendet werden. Geheime Schlüssel sollten nicht mit der App bereitgestellt werden. Stattdessen sollte auf Produktionsschlüssel über ein kontrolliertes Mittel wie Umgebungsvariablen oder Azure Key Vault zugegriffen werden. Sie können Azure-Test- und -Produktionsgeheimnisse mit dem Konfigurationsanbieter Azure Key Vault speichern und schützen.

Informationen zum Verwenden von Benutzerschlüsseln in einer .NET-Konsolen-App finden Sie in diesem GitHub-Problem.

Umgebungsvariablen

Umgebungsvariablen werden verwendet, um die Speicherung von App-Geheimen im Code oder in lokalen Konfigurationsdateien zu vermeiden. Umgebungsvariablen überschreiben Konfigurationswerte für alle zuvor angegebenen Konfigurationsquellen.

Betrachten Sie eine ASP.NET Core Web-App, in der die Sicherheit einzelner Benutzerkonten aktiviert ist. Eine Standarddatenbankverbindungszeichenfolge ist in der Datei des Projekts appsettings.json mit dem Schlüssel DefaultConnectionenthalten. Die Standardverbindungszeichenfolge ist für LocalDB, die im Benutzermodus ausgeführt wird und kein Kennwort erfordert. Während der App-Bereitstellung kann der DefaultConnection Schlüsselwert mit dem Wert einer Umgebungsvariable überschrieben werden. Die Umgebungsvariable speichert möglicherweise die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen.

Warnung

Umgebungsvariablen werden im Allgemeinen in einfachem, nicht verschlüsselten Text gespeichert. Wenn der Computer oder Prozess kompromittiert ist, können Umgebungsvariablen von nicht vertrauenswürdigen Parteien zugegriffen werden. Zusätzliche Maßnahmen zur Verhinderung der Offenlegung von Benutzerschlüsseln können erforderlich sein.

Das Trennzeichen : funktioniert nicht auf allen Plattformen mit den hierarchischen Schlüsseln von Umgebungsvariablen. Der doppelte Unterstrich __:

  • wird auf allen Plattformen unterstützt. Das Trennzeichen : wird beispielsweise nicht von Bash unterstützt, __ hingegen schon.
  • automatisch durch : ersetzt.

Geheimer Manager

Das Geheim-Manager-Tool speichert vertrauliche Daten während der Entwicklung eines ASP.NET Core Projekts. In diesem Zusammenhang ist ein Teil vertraulicher Daten ein App-Geheimer. App-Geheimnisse werden an einem separaten Speicherort aus der Projektstruktur gespeichert. Die App-Geheimnisse werden einem bestimmten Projekt zugeordnet oder für mehrere Projekte freigegeben. Die App-Geheimnisse werden nicht in die Quellcodeverwaltung eingecheckt.

Warnung

Das Geheim-Manager-Tool verschlüsselt nicht die gespeicherten Geheimnisse und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Es ist nur für Entwicklungszwecke vorgesehen. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Benutzerprofilverzeichnis gespeichert.

Funktionsweise des Tools "Geheimer Manager"

Das Tool "Geheimer Manager" blendet Implementierungsdetails aus, z. B. wo und wie die Werte gespeichert werden. Sie können das Tool verwenden, ohne diese Implementierungsdetails zu kennen. Die Werte werden in einer JSON-Datei im Benutzerprofilordner des lokalen Computers gespeichert:

Dateisystempfad:

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

Ersetzen Sie <user_secrets_id> in den vorhergehenden Dateipfaden den UserSecretsId in der Projektdatei angegebenen Wert.

Schreiben Sie keinen Code, der vom Speicherort oder dem Format der Daten abhängt, die mit dem Geheim-Manager-Tool gespeichert sind. Diese Implementierungsdetails können sich ändern. Beispielsweise sind die geheimen Werte nicht verschlüsselt, könnten aber in Zukunft sein.

Geheimer Speicher aktivieren

Das Tool "Geheimer Manager" funktioniert auf projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

Das Tool "Geheimer Manager" enthält einen init Befehl. Führen Sie zum Verwenden von Benutzerschlüsseln den folgenden Befehl im Projektverzeichnis aus:

dotnet user-secrets init

Der vorherige Befehl fügt ein UserSecretsId Element in einer PropertyGroup Projektdatei hinzu. Standardmäßig ist der innere Text UserSecretsId einer GUID. Der innere Text ist beliebig, ist aber für das Projekt eindeutig.

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

Klicken Sie in Visual Studio mit der rechten Maustaste auf das Projekt in Projektmappen-Explorer, und wählen Sie "Benutzerschlüssel verwalten" im Kontextmenü aus. Diese Geste fügt einem Projektdatei ein Element hinzu, das mit einer UserSecretsId GUID gefüllt ist.

Festlegen eines Geheimnisses

Definieren Sie einen App-Geheimschlüssel, der aus einem Schlüssel und seinem Wert besteht. Der Geheime ist dem Wert des Projekts UserSecretsId zugeordnet. Führen Sie beispielsweise den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

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

Im vorherigen Beispiel bezeichnet der Doppelpunkt, der Movies ein Objekt literal mit einer ServiceApiKey Eigenschaft ist.

Das Tool "Geheimer Manager" kann auch von anderen Verzeichnissen verwendet werden. Verwenden Sie die --project Option zum Angeben des Dateisystempfads, bei dem die Projektdatei vorhanden ist. Beispiel:

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

JSON-Strukturschläfung in Visual Studio

Die Geste "Benutzerschlüssel verwalten" von Visual Studio öffnet eine secrets.json Datei im Text-Editor. Ersetzen Sie den Inhalt der secrets.json zu speichernden Schlüsselwertpaare. Beispiel:

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

Die JSON-Struktur wird nach Änderungen über dotnet user-secrets remove oder dotnet user-secrets set. Wenn Sie z. B. das Objekt literal ausführen, dotnet user-secrets remove "Movies:ConnectionString" wird das Movies Objekt reduziert. Die geänderte Datei ähnelt dem folgenden JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimschlüssel

Eine Batch von Geheimschlüsseln kann festgelegt werden, indem Sie EIN an den Befehl anfügenJSset. Im folgenden Beispiel werden die Inhalte der input.json Datei an den set Befehl weitergeleitet.

Öffnen Sie eine Befehlsshell, und führen Sie den folgenden Befehl aus:

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

Zugriff auf einen geheimen Schlüssel

Um auf einen Geheimen zuzugreifen, führen Sie die folgenden Schritte aus:

  1. Registrieren der Konfigurationsquelle für Benutzerschlüssel
  2. Lesen des Geheimen über die Konfigurations-API

Registrieren der Konfigurationsquelle für Benutzerschlüssel

Der Benutzerschlüsselkonfigurationsanbieter registriert die entsprechende Konfigurationsquelle mit der .NET-Konfigurations-API.

ASP.NET Core-Web-Apps, die mit dotnet new oder Visual Studio erstellt wurden, generieren den folgenden Code:

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

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

app.Run();

WebApplication.CreateBuilder Initialisiert eine neue Instanz der WebApplicationBuilder-Klasse mit vorkonfigurierten Standardwerten. Die initialisierte WebApplicationBuilder () stellt standardmäßige Konfiguration und Aufrufe AddUserSecrets bereit, wenn diesbuilder ist EnvironmentNameDevelopment:

Lesen des Geheimen über die Konfigurations-API

Betrachten Sie die folgenden Beispiele zum Lesen des Movies:ServiceApiKey Schlüssels:

Datei "Program.cs":

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

var app = builder.Build();

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

app.Run();

Razor Seitenseitenmodell:

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

Weitere Informationen finden Sie unter Konfiguration in ASP.NET Core.

Zuordnen von Geheimschlüsseln zu einem POCO

Die Zuordnung eines gesamten Objekts literal zu einer POCO (eine einfache .NET-Klasse mit Eigenschaften) ist nützlich für die Aggregatierung verwandter Eigenschaften.

Angenommen, die Datei der secrets.json App enthält die folgenden beiden Geheimnisse:

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

Verwenden Sie das Objektdiagramm-Bindungsfeature der .NET-Konfigurations-API, um den vorherigen Schlüssel einem POCO zuzuordnen. Der folgende Code bindet an einen benutzerdefinierten MovieSettings POCO und greift auf den ServiceApiKey Eigenschaftswert zu:

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

Die Movies:ConnectionString schlüsselhaften Movies:ServiceApiKey Eigenschaften werden den jeweiligen Eigenschaften zugeordnet in MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Zeichenfolgenersetzung mit Geheimschlüsseln

Das Speichern von Kennwörtern in Nur-Text ist unsicher. Beispielsweise kann eine datenbankverbindungszeichenfolge, die in appsettings.json gespeichert ist, ein Kennwort für den angegebenen Benutzer enthalten:

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

Ein sichererer Ansatz besteht darin, das Kennwort als Geheimschlüssel zu speichern. Beispiel:

dotnet user-secrets set "DbPassword" "pass123"

Entfernen Sie das Password Schlüsselwertpaar aus der Verbindungszeichenfolge in appsettings.json. Beispiel:

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

Der Wert des Geheimen kann für die Eigenschaft eines SqlConnectionStringBuilder Objekts Password festgelegt werden, um die Verbindungszeichenfolge abzuschließen:

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

Auflisten der Geheimen Schlüssel

Gehen Sie davon aus, dass die Datei der App secrets.json die folgenden beiden Geheimnisse enthält:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets list

Die folgende Ausgabe wird angezeigt:

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

Im vorherigen Beispiel gibt ein Doppelpunkt in den Schlüsselnamen die Objekthierarchie innerhalb secrets.jsonder Schlüsselnamen an.

Entfernen eines einzelnen geheimen Schlüssels

Gehen Sie davon aus, dass die Datei der App secrets.json die folgenden beiden Geheimnisse enthält:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets remove "Movies:ConnectionString"

Die Datei der secrets.json App wurde geändert, um das Schlüsselwertpaar zu entfernen, das dem MoviesConnectionString Schlüssel zugeordnet ist:

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

dotnet user-secrets list zeigt die folgende Meldung an:

Movies:ServiceApiKey = 12345

Alle geheimen Schlüssel entfernen

Gehen Sie davon aus, dass die Datei der App secrets.json die folgenden beiden Geheimnisse enthält:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets clear

Alle Geheimen Benutzerschlüssel für die App wurden aus der secrets.json Datei gelöscht:

{}

Beim Ausführen dotnet user-secrets list wird die folgende Meldung angezeigt:

No secrets configured for this application.

Verwalten von Geheimen Benutzerschlüsseln mit Visual Studio

Um Benutzerschlüssel in Visual Studio zu verwalten, klicken Sie mit der rechten Maustaste auf das Projekt im Projektmappen-Explorer, und wählen Sie " Benutzergeheimnisse verwalten" aus:

Visual Studio mit

Zusätzliche Ressourcen

Von Rick Anderson, Kirk Larkin, Daniel Roth und Scott Addie

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

In diesem Dokument wird erläutert, wie Vertrauliche Daten für eine ASP.NET Core-App auf einem Entwicklungscomputer verwaltet werden. Speichern Sie niemals Kennwörter oder andere vertrauliche Daten im Quellcode. Produktionsgeheimnisse sollten nicht für die Entwicklung oder den Test verwendet werden. Geheime Schlüssel sollten nicht mit der App bereitgestellt werden. Stattdessen sollten auf Produktionsgeheimnisse über eine kontrollierte Möglichkeit wie Umgebungsvariablen oder Azure-Key Vault zugegriffen werden. Sie können Azure-Test- und -Produktionsgeheimnisse mit dem Konfigurationsanbieter Azure Key Vault speichern und schützen.

Umgebungsvariablen

Umgebungsvariablen werden verwendet, um die Speicherung von Geheimen Apps im Code oder in lokalen Konfigurationsdateien zu vermeiden. Umgebungsvariablen überschreiben Konfigurationswerte für alle zuvor angegebenen Konfigurationsquellen.

Erwägen Sie eine ASP.NET Core Web-App, in der die Sicherheit einzelner Benutzerkonten aktiviert ist. Eine Standarddatenbankverbindungszeichenfolge appsettings.json ist in der Datei des Projekts mit dem Schlüssel DefaultConnectionenthalten. Die Standardverbindungszeichenfolge ist für LocalDB vorgesehen, die im Benutzermodus ausgeführt wird und kein Kennwort erfordert. Während der App-Bereitstellung kann der DefaultConnection Schlüsselwert mit dem Wert einer Umgebungsvariable überschrieben werden. Die Umgebungsvariable speichert möglicherweise die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen.

Warnung

Umgebungsvariablen werden im Allgemeinen in nur unverschlüsselten Text gespeichert. Wenn der Computer oder Prozess kompromittiert ist, können Umgebungsvariablen von nicht vertrauenswürdigen Parteien zugegriffen werden. Zusätzliche Maßnahmen zur Verhinderung der Offenlegung von Benutzergeheimnissen können erforderlich sein.

Das Trennzeichen : funktioniert nicht auf allen Plattformen mit den hierarchischen Schlüsseln von Umgebungsvariablen. Der doppelte Unterstrich __:

  • wird auf allen Plattformen unterstützt. Das Trennzeichen : wird beispielsweise nicht von Bash unterstützt, __ hingegen schon.
  • automatisch durch : ersetzt.

Geheimer Manager

Das Tool "Geheimer Manager" speichert vertrauliche Daten während der Entwicklung eines ASP.NET Core Projekts. In diesem Zusammenhang ist ein Teil vertraulicher Daten ein App-Geheimnis. Geheime App-Schlüssel werden an einem separaten Speicherort aus der Projektstruktur gespeichert. Die Geheimen App-Schlüssel sind einem bestimmten Projekt oder mehreren Projekten zugeordnet. Die Geheimen App-Schlüssel werden nicht in die Quellcodeverwaltung eingecheckt.

Warnung

Das Tool "Geheimer Manager" verschlüsselt nicht die gespeicherten Geheimnisse und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Dies gilt nur für Entwicklungszwecke. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Benutzerprofilverzeichnis gespeichert.

Funktionsweise des Tools "Geheimer Manager"

Das Tool "Geheimer Manager" blendet Implementierungsdetails aus, z. B. wo und wie die Werte gespeichert werden. Sie können das Tool verwenden, ohne diese Implementierungsdetails zu kennen. Die Werte werden in einer JSON-Datei im Benutzerprofilordner des lokalen Computers gespeichert:

Dateisystempfad:

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

Ersetzen Sie <user_secrets_id> in den vorherigen Dateipfaden den UserSecretsId in der Projektdatei angegebenen Wert.

Schreiben Sie keinen Code, der vom Speicherort oder Format von Daten abhängt, die mit dem Tool "Geheimer Manager" gespeichert sind. Diese Implementierungsdetails können sich ändern. Beispielsweise werden die geheimen Werte nicht verschlüsselt, könnten aber in Zukunft sein.

Geheimer Speicher aktivieren

Das Tool "Geheimer Manager" funktioniert auf projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

Das Tool "Geheimer Manager" enthält einen init Befehl in .NET Core SDK 3.0.100 oder höher. Führen Sie zum Verwenden von Benutzerschlüsseln den folgenden Befehl im Projektverzeichnis aus:

dotnet user-secrets init

Der vorherige Befehl fügt ein UserSecretsId Element in einer PropertyGroup Projektdatei hinzu. Standardmäßig ist der innere Text UserSecretsId eine GUID. Der innere Text ist beliebig, ist aber für das Projekt einzigartig.

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

Klicken Sie in Visual Studio mit der rechten Maustaste auf das Projekt in Projektmappen-Explorer, und wählen Sie im Kontextmenü "Benutzergeheimnisse verwalten" aus. Diese Geste fügt der Projektdatei ein UserSecretsId Element hinzu, das mit einer GUID gefüllt ist.

Festlegen eines Geheimnisses

Definieren Sie einen geheimen App-Schlüssel, der aus einem Schlüssel und seinem Wert besteht. Der Schlüssel ist dem Wert des UserSecretsId Projekts zugeordnet. Führen Sie beispielsweise den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

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

Im vorherigen Beispiel bezeichnet der Doppelpunkt, der Movies ein Objektliteral mit einer ServiceApiKey Eigenschaft ist.

Das Tool "Geheimer Manager" kann auch aus anderen Verzeichnissen verwendet werden. Verwenden Sie die --project Option zum Angeben des Dateisystempfads, in dem die Projektdatei vorhanden ist. Beispiel:

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

JSON-Strukturschläfung in Visual Studio

Die Geste "Benutzergeheimnisse verwalten" von Visual Studio öffnet eine secrets.json Datei im Text-Editor. Ersetzen Sie den Inhalt der secrets.json zu speichernden Schlüsselwertpaare. Beispiel:

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

Die JSON-Struktur wird nach Änderungen über dotnet user-secrets remove oder dotnet user-secrets set. Wenn Sie z. B. das Objekt literal ausführen, dotnet user-secrets remove "Movies:ConnectionString" wird das Movies Objekt reduziert. Die geänderte Datei ähnelt dem folgenden JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimschlüssel

Eine Batch von Geheimschlüsseln kann festgelegt werden, indem Sie EIN an den Befehl anfügenJSset. Im folgenden Beispiel werden die Inhalte der input.json Datei an den set Befehl weitergeleitet.

Öffnen Sie eine Befehlsshell, und führen Sie den folgenden Befehl aus:

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

Zugriff auf einen geheimen Schlüssel

Um auf einen Geheimen zuzugreifen, führen Sie die folgenden Schritte aus:

  1. Registrieren der Konfigurationsquelle für Benutzerschlüssel
  2. Lesen des Geheimen über die Konfigurations-API

Registrieren der Konfigurationsquelle für Benutzerschlüssel

Der Benutzerschlüsselkonfigurationsanbieter registriert die entsprechende Konfigurationsquelle mit der .NET-Konfigurations-API.

Die Konfigurationsquelle für Benutzerschlüssel wird automatisch im Entwicklungsmodus hinzugefügt, wenn das Projekt aufgerufen CreateDefaultBuilderwird. CreateDefaultBuilder ruft an AddUserSecrets , wenn es sich um folgendes EnvironmentName handelt Development:

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

Wenn CreateDefaultBuilder nicht aufgerufen wird, fügen Sie die Konfigurationsquelle des Benutzerschlüssels explizit hinzu, indem Sie in aufrufen AddUserSecretsConfigureAppConfiguration. Rufen Sie nur auf AddUserSecrets , wenn die App in der Entwicklungsumgebung ausgeführt wird, wie im folgenden Beispiel gezeigt:

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

Lesen des Geheimen über die Konfigurations-API

Wenn die Konfigurationsquelle des Benutzerschlüssels registriert ist, kann die .NET-Konfigurations-API die Geheimnisse lesen. Die Konstruktorinjektion kann verwendet werden, um Zugriff auf die .NET-Konfigurations-API zu erhalten. Betrachten Sie die folgenden Beispiele zum Lesen des Movies:ServiceApiKey Schlüssels:

Startklasse:

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 Seitenseitenmodell:

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

Weitere Informationen finden Sie unter Access-Konfiguration in der Start - und Access-Konfiguration in Razor Seiten.

Zuordnen von Geheimschlüsseln zu einem POCO

Die Zuordnung eines gesamten Objekts literal zu einer POCO (eine einfache .NET-Klasse mit Eigenschaften) ist nützlich für die Aggregatierung verwandter Eigenschaften.

Angenommen, die Datei der secrets.json App enthält die folgenden beiden Geheimnisse:

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

Um die vorhergehenden Geheimnisse einem POCO zuzuordnen, verwenden Sie das Objektdiagrammbindungsfeature der .NET-Konfigurations-API. Der folgende Code bindet an einen benutzerdefinierten MovieSettings POCO und greift auf den ServiceApiKey Eigenschaftswert zu:

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

Die und Movies:ServiceApiKey geheimnisse Movies:ConnectionString werden den jeweiligen Eigenschaften zugeordnet inMovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Zeichenfolgenersetzung mit Geheimschlüsseln

Das Speichern von Kennwörtern im Nur-Text ist unsicher. Beispielsweise kann eine datenbankverbindungszeichenfolge, die in appsettings.json gespeichert ist, ein Kennwort für den angegebenen Benutzer enthalten:

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

Ein sichererer Ansatz besteht darin, das Kennwort als Geheimschlüssel zu speichern. Beispiel:

dotnet user-secrets set "DbPassword" "pass123"

Entfernen Sie das Password Schlüsselwertpaar aus der Verbindungszeichenfolge in appsettings.json. Beispiel:

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

Der Wert des Geheimen kann auf der Eigenschaft eines SqlConnectionStringBuilder Objekts Password festgelegt werden, um die Verbindungszeichenfolge abzuschließen:

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

Auflisten der Geheimnisse

Angenommen, die Datei der secrets.json App enthält die folgenden beiden Geheimnisse:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets list

Die folgende Ausgabe wird angezeigt:

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

Im vorherigen Beispiel wird ein Doppelpunkt in den Schlüsselnamen die Objekthierarchie innerhalb der Objekthierarchie bezeichnet secrets.json.

Entfernen eines einzelnen Geheimen

Angenommen, die Datei der secrets.json App enthält die folgenden beiden Geheimnisse:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets remove "Movies:ConnectionString"

Die Datei der App secrets.json wurde geändert, um das Schlüsselwertpaar zu entfernen, das dem MoviesConnectionString Schlüssel zugeordnet ist:

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

dotnet user-secrets list zeigt die folgende Meldung an:

Movies:ServiceApiKey = 12345

Alle Geheimnisse entfernen

Angenommen, die Datei der secrets.json App enthält die folgenden beiden Geheimnisse:

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

Führen Sie den folgenden Befehl aus dem Verzeichnis aus, in dem die Projektdatei vorhanden ist:

dotnet user-secrets clear

Alle Benutzerschlüssel für die App wurden aus der secrets.json Datei gelöscht:

{}

Die Ausführung dotnet user-secrets list zeigt die folgende Meldung an:

No secrets configured for this application.

Verwalten von Benutzerschlüsseln mit Visual Studio

Um Benutzerschlüssel in Visual Studio zu verwalten, klicken Sie mit der rechten Maustaste auf das Projekt im Projektmappen-Explorer, und wählen Sie "Benutzerschlüssel verwalten" aus:

Visual Studio mit

Zusätzliche Ressourcen