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 Kennwörter oder andere vertrauliche Daten niemals im Quellcode. Produktionsgeheimnisse sollten nicht für Entwicklungs- oder Testumgebungen verwendet werden. Geheimnisse sollten nicht mit der App bereitgestellt werden. Stattdessen sollte der Zugriff auf Produktionsgeheimnisse über kontrollierte Mittel wie Umgebungsvariablen oder Azure Key Vault. 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 App-Geheimnissen im Code oder in lokalen Konfigurationsdateien zu vermeiden. Umgebungsvariablen überschreiben Konfigurationswerte für alle zuvor angegebenen Konfigurationsquellen.

Stellen Sie sich ASP.NET Core Web-App vor, in der die Sicherheit einzelner Benutzerkonten aktiviert ist. Eine Standardverbindungszeichenfolge für die Datenbank ist in der Datei des Projekts appsettings.json mit dem Schlüssel DefaultConnection enthalten. Die Standardverbindungszeichenfolge ist für LocalDB, die im Benutzermodus ausgeführt wird und kein Kennwort erfordert. Während der App-Bereitstellung kann der Schlüsselwert mit dem Wert einer DefaultConnection Umgebungsvariablen überschrieben werden. Die Umgebungsvariable kann die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen speichern.

Warnung

Umgebungsvariablen werden im Allgemeinen als unverschlüsselter Text gespeichert. Wenn der Computer oder Prozess kompromittiert ist, können nicht vertrauenswürdige Parteien auf Umgebungsvariablen zugreifen. Möglicherweise sind zusätzliche Maßnahmen erforderlich, um die Offenlegung von Benutzergeheimnissen zu verhindern.

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.

Secret Manager

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

Warnung

Das Geheimnis-Manager-Tool verschlüsselt die gespeicherten Geheimnisse nicht und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Dies dient nur zu Entwicklungszwecken. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Benutzerprofilverzeichnis gespeichert.

Funktionsweise des Secret Manager-Tools

Das Geheimnis-Manager-Tool 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 in den obigen Dateipfaden <user_secrets_id> durch den in der UserSecretsId Projektdatei angegebenen Wert.

Schreiben Sie keinen Code, der vom Speicherort oder Format der mit dem Secret Manager-Tool gespeicherten Daten abhängt. Diese Implementierungsdetails können sich ändern. Beispielsweise werden die Geheimniswerte nicht verschlüsselt, können aber in der Zukunft liegen.

Aktivieren des Geheimnisspeichers

Das Geheimnis-Manager-Tool arbeitet mit projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

Das Geheimnis-Manager-Tool enthält einen init Befehl. Um Benutzergeheimnisse zu verwenden, führen Sie den folgenden Befehl im Projektverzeichnis aus:

dotnet user-secrets init

Mit dem vorherigen Befehl wird ein UserSecretsId -Element in einer PropertyGroup der Projektdatei hinzufügt. Standardmäßig ist der innere Text UserSecretsId von eine GUID. Der innere Text ist willkürlich, aber für das Projekt eindeutig.

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

Klicken 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 -Element hinzu, das mit einer UserSecretsId GUID aufgefüllt wird.

Festlegen eines Geheimnisses

Definieren Sie ein App-Geheimnis, das aus einem Schlüssel und dessen Wert besteht. Das Geheimnis 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 gibt der Doppelpunkt an, dass ein Movies Objektliteral mit einer -Eigenschaft ServiceApiKey ist.

Das Geheimnis-Manager-Tool kann auch aus anderen Verzeichnissen verwendet werden. Verwenden Sie --project die Option , um den Dateisystempfad für die Projektdatei einderherzustellen. Beispiel:

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

JSON-Strukturabflaung in Visual Studio

Visual Studio die Geste Benutzergeheimnisse verwalten öffnet eine datei secrets.json im Text-Editor. Ersetzen Sie den Inhalt von secrets.json durch die schlüssel-Wert-Paare, die gespeichert werden sollen. Beispiel:

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

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

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimnisse

Ein Batch von Geheimnissen kann festgelegt werden, indem JSON an den Befehl set gepipet wird. Im folgenden Beispiel wird der Inhalt der Datei input.json an den Befehl über die Pipeline set gepipet.

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

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

Zugreifen auf ein Geheimnis

Führen Sie die folgenden Schritte aus, um auf ein Geheimnis zu zugreifen:

  1. Registrieren der Konfigurationsquelle für Benutzergeheimnisse
  2. Lesen des Geheimnisses über die Konfigurations-API

Registrieren der Konfigurationsquelle für Benutzergeheimnisse

Der Konfigurationsanbieter für Benutzergeheimnisse registriert die entsprechende Konfigurationsquelle bei 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. Der initialisierte WebApplicationBuilder ( ) stellt die builder Standardkonfiguration und Aufrufe zur AddUserSecrets Verwendung von EnvironmentName Development bei:

Lesen des Geheimnisses über die Konfigurations-API

Sehen Sie sich die folgenden Beispiele zum Lesen des Movies:ServiceApiKey Schlüssels an:

Program.cs-Datei:

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 Geheimnissen zu einem POCO

Das Zuordnen eines gesamten Objektliterals zu einem POCO (eine einfache .NET-Klasse mit Eigenschaften) ist nützlich, um verwandte Eigenschaften zu aggregieren.

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

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

Verwenden Sie die Objektdiagrammbindungsfunktion der .NET-Konfigurations-API, um die oben genannten Geheimnisse einem POCO zu zuordnen. Der folgende Code wird an ein benutzerdefiniertes MovieSettings POCO gebunden und greifen auf den ServiceApiKey -Eigenschaftswert zu:

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

Die Movies:ConnectionString Geheimnisse und werden den jeweiligen Eigenschaften in Movies:ServiceApiKey MovieSettings zugeordnet:

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

    public string ServiceApiKey { get; set; }
}

Ersetzen von Zeichenfolgen durch Geheimnisse

Das Speichern von Kennwörtern im Nur-Text-Text ist unsicher. Beispielsweise kann eine in gespeicherte appsettings.json Datenbankverbindungszeichenfolge 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 in der Speicherung des Kennworts als Geheimnis. Beispiel:

dotnet user-secrets set "DbPassword" "pass123"

Entfernen Sie Password das Schlüssel-Wert-Paar aus der Verbindungszeichenfolge in appsettings.json . Beispiel:

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

Der Wert des Geheimnisses kann für die -Eigenschaft eines -Objekts festgelegt SqlConnectionStringBuilder Password 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 Geheimnisse

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

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

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 in secrets.json an.

Entfernen eines einzelnen Geheimnisses

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

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

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

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list zeigt die folgende Meldung an:

Movies:ServiceApiKey = 12345

Entfernen aller Geheimnisse

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

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

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

dotnet user-secrets clear

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

{}

Wird dotnet user-secrets list ausgeführt, wird die folgende Meldung angezeigt:

No secrets configured for this application.

Verwalten von Benutzergeheimnissen mit Visual Studio

Klicken Sie zum Verwalten von Benutzergeheimnissen in Visual Studio im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Benutzergeheimnisse verwalten aus:

Visual Studio zum Verwalten von Benutzergeheimnissen

Zusätzliche Ressourcen

Von Rick Anderson, Kirk Andersonkin, Daniel Rothund 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 für Tests verwendet werden. Geheimnisse sollten nicht mit der App bereitgestellt werden. Stattdessen sollte auf Produktionsgeheimnisse über kontrollierte 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.

Umgebungsvariablen

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

Stellen Sie sich eine ASP.NET Core Web-App vor, in der die Sicherheit einzelner Benutzerkonten aktiviert ist. Eine Standardverbindungszeichenfolge der Datenbank ist in der Datei des Projekts appsettings.json mit dem Schlüssel DefaultConnection enthalten. 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 Umgebungsvariablen überschrieben werden. Die Umgebungsvariable kann die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen speichern.

Warnung

Umgebungsvariablen werden im Allgemeinen in einfachem, unverschlüsselten Text gespeichert. Wenn der Computer oder Prozess kompromittiert ist, können nicht vertrauenswürdige Parteien auf Umgebungsvariablen zugreifen. Möglicherweise sind zusätzliche Maßnahmen erforderlich, um die Offenlegung von Benutzergeheimnissen zu verhindern.

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.

Secret Manager

Das Secret Manager-Tool speichert vertrauliche Daten während der Entwicklung eines ASP.NET Core-Projekts. In diesem Kontext ist ein Teil vertraulicher Daten ein App-Geheimnis. App-Geheimnisse werden an einem anderen Speicherort als 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 Geheimnis-Manager-Tool verschlüsselt die gespeicherten Geheimnisse nicht und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Sie dient nur zu Entwicklungszwecken. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Benutzerprofilverzeichnis gespeichert.

Funktionsweise des Secret Manager-Tools

Das Geheimnis-Manager-Tool 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 in den vorherigen Dateipfaden durch <user_secrets_id> den UserSecretsId in der Projektdatei angegebenen Wert.

Schreiben Sie keinen Code, der vom Speicherort oder Format der mit dem Geheimnis-Manager-Tool gespeicherten Daten abhängt. Diese Implementierungsdetails können sich ändern. Beispielsweise werden die Geheimniswerte nicht verschlüsselt, können aber in Zukunft liegen.

Aktivieren des Geheimnisspeichers

Das Geheimnis-Manager-Tool arbeitet mit projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

Das Geheimnis-Manager-Tool enthält einen init Befehl in .NET Core SDK 3.0.100 oder höher. Führen Sie den folgenden Befehl im Projektverzeichnis aus, um Benutzergeheimnisse zu verwenden:

dotnet user-secrets init

Der vorangehende Befehl fügt ein UserSecretsId -Element innerhalb einer PropertyGroup der Projektdatei hinzu. Standardmäßig ist der innere Text von UserSecretsId eine GUID. Der innere Text ist willkürlich, 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 im Kontextmenü Benutzergeheimnisse verwalten aus. Diese Geste fügt der UserSecretsId Projektdatei ein Element hinzu, das mit einer GUID aufgefüllt wird.

Festlegen eines Geheimnisses

Definieren Sie ein App-Geheimnis, das aus einem Schlüssel und dessen Wert besteht. Das Geheimnis 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 gibt der Doppelpunkt an, dass Movies ein Objektliteral mit einer ServiceApiKey -Eigenschaft ist.

Das Geheimnis-Manager-Tool kann auch aus anderen Verzeichnissen verwendet werden. Verwenden Sie die --project Option , um den Dateisystempfad zur Verfügung zu stellen, unter dem die Projektdatei vorhanden ist. Beispiel:

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

Json-Struktur-Flattening in Visual Studio

mit der Geste Benutzergeheimnisse verwalten von Visual Studio wird die Datei secrets.json im Text-Editor geöffnet. Ersetzen Sie den Inhalt von secrets.json durch die schlüssel-wert-Paare, die gespeichert werden sollen. 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 flacher. dotnet user-secrets set Wenn Sie z. B. ausführen, dotnet user-secrets remove "Movies:ConnectionString" wird das Movies Objektliteral reduziert. Die geänderte Datei ähnelt dem folgenden JSON-Code:

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimnisse

Ein Batch von Geheimnissen kann durch Piping von JSON an den Befehl festgelegt set werden. Im folgenden Beispiel wird der Inhalt der Datei input.json an den Befehl über die Pipeline set übertragen.

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

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

Zugreifen auf ein Geheimnis

Führen Sie die folgenden Schritte aus, um auf ein Geheimnis zuzugreifen:

  1. Registrieren der Konfigurationsquelle für Benutzergeheimnisse
  2. Lesen des Geheimnisses über die Konfigurations-API

Registrieren der Konfigurationsquelle für Benutzergeheimnisse

Der Konfigurationsanbieter für Benutzergeheimnisse registriert die entsprechende Konfigurationsquelle bei der .NET-Konfigurations-API.

Die Konfigurationsquelle für Benutzergeheimnisse wird automatisch im Entwicklungsmodus hinzugefügt, wenn das Projekt CreateDefaultBuilder aufruft. CreateDefaultBuilder ruft AddUserSecrets auf, wenn EnvironmentName Development ist:

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

Wenn CreateDefaultBuilder nicht aufgerufen wird, fügen Sie die Konfigurationsquelle für Benutzergeheimnisse explizit hinzu, indem Sie AddUserSecrets in ConfigureAppConfiguration aufrufen. Rufen Sie AddUserSecrets nur auf, 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 Geheimnisses über die Konfigurations-API

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

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 configuration in Startup and Access configuration in Razor Pages.

Zuordnen von Geheimnissen zu einem POCO

Das Zuordnen eines gesamten Objektliterals zu einem POCO (eine einfache .NET-Klasse mit Eigenschaften) ist nützlich, um verwandte Eigenschaften zu aggregieren.

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

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

Verwenden Sie die Objektdiagrammbindungsfunktion der .NET-Konfigurations-API, um die oben genannten Geheimnisse einem POCO zu zuordnen. Der folgende Code wird an ein benutzerdefiniertes MovieSettings POCO gebunden und greifen auf den ServiceApiKey -Eigenschaftswert zu:

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

Die Movies:ConnectionString Geheimnisse und werden den jeweiligen Eigenschaften in Movies:ServiceApiKey MovieSettings zugeordnet:

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

    public string ServiceApiKey { get; set; }
}

Ersetzen von Zeichenfolgen durch Geheimnisse

Das Speichern von Kennwörtern im Nur-Text-Text ist unsicher. Beispielsweise kann eine in gespeicherte appsettings.json Datenbankverbindungszeichenfolge 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 in der Speicherung des Kennworts als Geheimnis. Beispiel:

dotnet user-secrets set "DbPassword" "pass123"

Entfernen Sie Password das Schlüssel-Wert-Paar aus der Verbindungszeichenfolge in appsettings.json . Beispiel:

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

Der Wert des Geheimnisses kann für die -Eigenschaft eines -Objekts festgelegt werden, SqlConnectionStringBuilder Password um die Verbindungszeichenfolge zu vervollständigen:

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 secrets.js der App in der Datei enthält die folgenden beiden Geheimnisse:

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

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 in secrets.json an.

Entfernen eines einzelnen Geheimnisses

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

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

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

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list zeigt die folgende Meldung an:

Movies:ServiceApiKey = 12345

Entfernen aller Geheimnisse

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

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

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

dotnet user-secrets clear

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

{}

Wird dotnet user-secrets list ausgeführt, wird die folgende Meldung angezeigt:

No secrets configured for this application.

Verwalten von Benutzergeheimnissen mit Visual Studio

Klicken Sie zum Verwalten von Benutzergeheimnissen in Visual Studio im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Benutzergeheimnisse verwalten aus:

Visual Studio anzeigen von "Benutzergeheimnisse verwalten"

Zusätzliche Ressourcen