Sicheres Speichern von App-Geheimnissen bei der Entwicklung in ASP.NET Core

Note

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

Warning

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

Von Rick Anderson und Kirk Larkin

In diesem Artikel 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 in Quellcode- oder Konfigurationsdateien. Produktionsgeheimnisse sollten nicht für die Entwicklung oder für Tests verwendet werden. Geheimnisse sollten nicht mit der App bereitgestellt werden. Auf geheime Produktionsgeheimnisse sollte über ein kontrolliertes Mittel wie Azure Key Vault zugegriffen werden. Azure-Test- und Produktionsgeheimnisse können mit dem Azure Key Vault-Konfigurationsanbieter gespeichert und geschützt werden.

Anzeigen oder Herunterladen des Beispielcodes (herunterladen)

Weitere Informationen zur Authentifizierung für bereitgestellte Test- und Produktions-Apps finden Sie unter Sichere Authentifizierungsflows.

Informationen zum Verwenden von geheimen Benutzerschlüsseln in einer .NET Konsolen-App finden Sie unter GitHub dotnet/entityframework.docs Issue #3939.

Arbeiten mit Umgebungsvariablen

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

Erwägen Sie eine ASP.NET Core-Web-App, in der die Sicherheit einzelner Konten aktiviert ist. Eine Standard-Datenbankverbindungszeichenfolge ist in der Projektdatei appsettings.json unter dem Schlüssel DefaultConnection enthalten. Die standardmäßige Verbindungszeichenfolge ist für LocalDB vorgesehen, die im Benutzermodus ausgeführt wird und kein Kennwort erfordert. Während der App-Bereitstellung können Sie den DefaultConnection Schlüsselwert mit dem Wert einer Umgebungsvariable überschreiben. Die Umgebungsvariable speichert möglicherweise die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen.

Warning

Umgebungsvariablen werden häufig als nur unverschlüsselter Text gespeichert. Wenn der Computer oder der Prozess kompromittiert ist, sind Umgebungsvariablen für nicht vertrauenswürdige Parteien zugänglich. Zusätzliche Maßnahmen zur Verhinderung der Offenlegung von geheimen Benutzergeheimnissen sind möglicherweise erforderlich.

Das Trennzeichen : funktioniert nicht mit den hierarchischen Schlüsseln von Umgebungsvariablen auf allen Plattformen. Bash unterstützt z. B. keinen Doppelpunkt (:) als Trennzeichen. Alle Plattformen unterstützen die Syntax doppelter Unterstriche (__) und ersetzen sie automatisch durch einen Doppelpunkt (:).

Verwenden des Tools "Geheimer Manager"

Secret Manager ist ein Tool, mit dem vertrauliche Daten während der Anwendungsentwicklung gespeichert werden. In diesem Zusammenhang ist ein Teil vertraulicher Daten ein App-Geheimnis.

  • App-Geheimnisse werden an einem von der Projektstruktur getrennten Ort gespeichert.
  • Sie sind einem bestimmten Projekt zugeordnet oder für mehrere Projekte freigegeben.
  • Sie werden nicht in die Quellcodeverwaltung eingecheckt.

Warning

Der geheime Manager verschlüsselt die gespeicherten geheimen Schlüssel nicht und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Er dient nur zu Entwicklungszwecken. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Profilverzeichnis von Benutzenden gespeichert.

Der geheime 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 im Dateisystempfad den <user_secrets_id> Teil durch den UserSecretsId in der Projektdatei angegebenen Wert.

Schreiben Sie keinen Code, der vom Speicherort oder Format der mit dem Geheimen Manager gespeicherten Daten abhängt. Diese Implementierungsdetails können sich ändern. Beispielsweise sind die geheimen Werte nicht verschlüsselt.

Aktivieren der Geheimnisspeicherung

Der geheime Manager arbeitet mit projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

Verwenden Sie die Befehlszeilenschnittstelle

Der geheime Manager enthält einen init Befehl. Um Benutzergeheimnisse zu verwenden, führen Sie den folgenden Befehl im Projektverzeichnis aus:

dotnet user-secrets init

Mit diesem Befehl wird ein UserSecretsId Element in einer PropertyGroup Projektdatei hinzugefügt. Standardmäßig ist der innere Text von UserSecretsId eine GUID. Der innere Text ist willkürlich, aber für das Projekt eindeutig. Das folgende Beispiel zeigt einen GUID-Wert von 0000a1a1-b2b2-c3c3-d4d4-eeeeee555555.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <UserSecretsId>0000a1a1-b2b2-c3c3-d4d4-eeeeee555555</UserSecretsId>
  </PropertyGroup>

</Project>

Verwenden von Visual Studio

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

Wenn "GenerateAssemblyInfo" auf "false" festgelegt ist

Wenn die Generierung von AssemblyInfo-Attributen (GenerateAssemblyInfo) deaktiviert ist (auf false festgelegt), fügen Sie UserSecretsIdAttribute manuell in der Datei AssemblyInfo.cs hinzu. Beispiel:

[assembly: UserSecretsId("your_user_secrets_id")]

Wenn Sie das UserSecretsId Attribut manuell zur AssemblyInfo.cs Datei hinzufügen, muss der UserSecretsId Wert mit dem Wert in der Projektdatei übereinstimmen.

Festlegen eines Geheimnisses

Definieren Sie ein App-Geheimnis, das aus einem Schlüssel und seinem Wert besteht. Das Geheimnis ist dem UserSecretsId-Wert des Projekts zugeordnet. Führen Sie z. B. den folgenden Befehl von dem Verzeichnis aus, in dem sich die Projektdatei befindet:

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

In diesem Beispiel zeigt der Doppelpunkt an, dass Movies ein Objektliteral mit der Eigenschaft ServiceApiKey ist.

Sie können den Geheimen Manager auch aus anderen Verzeichnissen verwenden. Geben Sie die Option --project an, um den Dateisystempfad anzugeben, unter dem sich die Projektdatei befindet. Beispiel:

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

JSON-Strukturvereinfachung in Visual Studio

Die Geste Visual Studio Manage User Secrets öffnet eine secrets.jsondatei im Text-Editor. Ersetzen Sie den Inhalt der Datei secrets.json durch die zu speichernden Schlüssel-Wert-Paare. Beispiel:

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

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

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimnisse

Sie können einen Batch von Geheimnissen festlegen, indem Sie JSON per Pipeline an den Befehl set weiterreichen. Im folgenden Beispiel wird der Inhalt der Datei input.json an den setBefehl weitergeleitet.

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 Sie die Konfigurationsquelle für geheime Benutzerschlüssel.

  2. Lesen Sie den geheimen Schlüssel über die Konfigurations-API.

Registrierung der Konfigurationsquelle für Benutzergeheimnisse

Der Konfigurationsanbieter von Benutzergeheimnissen registriert die entsprechende Konfigurationsquelle mit der .NET-Konfigurations-API.

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

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

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

app.Run();

Die WebApplication.CreateBuilder-Methode initialisiert eine neue Instanz der WebApplicationBuilder Klasse mit vorkonfigurierten Standardwerten. Die initialisierte WebApplicationBuilder (builder) stellt die Standardkonfiguration bereit und ruft die AddUserSecrets-Methode auf, wenn die EnvironmentName-Eigenschaft Development ist.

Lesen Sie das Secret über die Konfigurations-API

Die folgenden Beispiele veranschaulichen das Lesen des Movies:ServiceApiKey Schlüssels:

Program.cs-Datei

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

var app = builder.Build();

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

app.Run();

Razor Pages-Seitenmodell

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.

Geheimnisse einem POCO zuordnen

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

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

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

Um die oben genannten Geheimnisse einem POCO zuzuordnen, verwenden Sie das Feature Objektgraphenbindung 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 Geheimnisse Movies:ConnectionString und Movies:ServiceApiKey werden den entsprechenden Eigenschaften in MovieSettings zugeordnet:

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

    public string ServiceApiKey { get; set; }
}

Zeichenfolgenersetzung mit Secrets verwenden

Die Speicherung von Kennwörtern in Nur-Text ist keine sichere Methode. Speichern Sie geheime Schlüssel niemals in einer Konfigurationsdatei wie appsettings.json, die möglicherweise in ein Quellcode-Repository eingecheckt werden.

Beispielsweise sollte eine in der Datei appsettings.json gespeicherte Datenbank-Verbindungszeichenfolge kein Kennwort enthalten. Speichern Sie stattdessen das Kennwort als geheimen Schlüssel, und fügen Sie das Kennwort zur Laufzeit in die Verbindungszeichenfolge ein. Beispiel:

dotnet user-secrets set "DbPassword" "`<secret value>`"

Ersetzen Sie den <secret value> Platzhalter im Beispiel durch den Kennwortwert. Legen Sie den Wert des geheimen Schlüssels für die Eigenschaft eines SqlConnectionStringBuilder Objekts Password fest, um ihn als Kennwortwert in die Verbindungszeichenfolge einzuschließ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();

Geheimnisse auflisten

Angenommen, die Anwendungsdatei secrets.json 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

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 Beispiel bezeichnet ein Doppelpunkt (:) in den Schlüsselnamen die Objekthierarchie innerhalb der secrets.json Datei.

Entfernen eines einzelnen Geheimnisses

Angenommen, die Anwendungsdatei secrets.json 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

dotnet user-secrets remove "Movies:ConnectionString"

Die Anwendung secrets.json Datei wird geändert, um das Schlüssel-Wert-Paar zu entfernen, das dem Movies:ConnectionString Schlüssel zugeordnet ist:

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

Der dotnet user-secrets list Befehl zeigt die folgende Meldung an:

Movies:ServiceApiKey = 12345

Entfernen aller Geheimnisse

Gehen Sie davon aus, dass die Anwendungsdatei 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

dotnet user-secrets clear

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

{}

Wenn Sie den dotnet user-secrets list Befehl ausführen, wird die folgende Meldung angezeigt:

No secrets configured for this application.

Verwalten von Benutzergeheimnissen mit Visual Studio

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

Der Screenshot zeigt, wie Sie in Visual Studio die Option „Benutzergeheimnisse verwalten“ auswählen.

Migrieren von Geheimschlüsseln von ASP.NET Framework zu ASP.NET Core

Sie können Ihre gespeicherten Benutzerschlüssel von ASP.NET Framework zu ASP.NET Core migrieren. Weitere Informationen finden Sie unter GitHub dotnet/aspnetcore.docs Problem #27611 - In der User-Secrets-Dokumentation wird die Inkompatibilität mit AssemblyInfo.cs nicht erwähnt.

Arbeiten mit geheimen Benutzerschlüsseln in Nicht-Webanwendungen

Projekte, die auf Microsoft.NET.Sdk.Web ausgelegt sind, enthalten automatisch Unterstützung für Benutzergeheimnisse. Installieren Sie ausdrücklich die Konfigurationserweiterung und die NuGet-Pakete für Benutzergeheimnisse für Projekte, die auf Microsoft.NET.Sdk abzielen, wie Konsolenanwendungen.

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

Nachdem Sie die Pakete installiert haben, initialisieren Sie das Projekt , und legen Sie geheime Schlüssel auf die gleiche Weise wie für eine Web-App fest. Das folgende Beispiel zeigt eine Konsolenanwendung, die den Wert eines geheimen Satzes mit dem AppSecret Schlüssel abruft:

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

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

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

In diesem Artikel 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 in Quellcode- oder Konfigurationsdateien. Produktionsgeheimnisse sollten nicht für die Entwicklung oder für Tests verwendet werden. Geheimnisse sollten nicht mit der App bereitgestellt werden. Auf geheime Produktionsgeheimnisse sollte über ein kontrolliertes Mittel wie Azure Key Vault zugegriffen werden. Azure-Test- und Produktionsgeheimnisse können mit dem Azure Key Vault-Konfigurationsanbieter gespeichert und geschützt werden.

Weitere Informationen zur Authentifizierung für Test- und Produktionsumgebungen finden Sie unter Sichere Authentifizierungsflüsse.

Umgebungsvariablen

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

Betrachten Sie eine ASP.NET Core Web-App, in der die Sicherheit für einzelne Benutzerkonten aktiviert ist. Eine standardmäßige Verbindungszeichenfolge für die Datenbank ist in der Datei appsettings.json des Projekts mit dem Schlüssel DefaultConnection enthalten. Die standardmäßige Verbindungszeichenfolge ist für LocalDB vorgesehen, die im Benutzermodus ausgeführt wird und kein Kennwort erfordert. Bei der Bereitstellung einer App kann der Wert des Schlüssels DefaultConnection durch den Wert einer Umgebungsvariablen außer Kraft gesetzt werden. Die Umgebungsvariable kann die vollständige Verbindungszeichenfolge mit vertraulichen Anmeldeinformationen speichern.

Warning

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

Das Trennzeichen : funktioniert nicht mit den hierarchischen Schlüsseln von Umgebungsvariablen auf allen Plattformen. Bash unterstützt z. B. keinen Doppelpunkt (:) als Trennzeichen. Alle Plattformen unterstützen die Syntax doppelter Unterstriche (__) und ersetzen sie automatisch durch einen Doppelpunkt (:).

Geheimer Manager

Das Tool „Secret Manager“ speichert vertrauliche Daten während der Anwendungsentwicklung. In diesem Zusammenhang stellt ein vertrauliches Datenfragment ein App-Geheimnis dar. App-Geheimnisse werden an einem von der Projektstruktur getrennten Ort gespeichert. Die App-Geheimnisse sind einem bestimmten Projekt zugeordnet oder werden projektübergreifend freigegeben. Die Geheimnisse der App werden nicht in die Quellcodeverwaltung eingecheckt.

Warning

Der Geheimnis-Manager verschlüsselt die gespeicherten Geheimnisse nicht und sollte nicht als vertrauenswürdiger Speicher behandelt werden. Er dient nur zu Entwicklungszwecken. Die Schlüssel und Werte werden in einer JSON-Konfigurationsdatei im Profilverzeichnis von Benutzenden gespeichert.

Funktionsweise des Secret Managers

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

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

Aktivieren der Geheimnisspeicherung

Das "Secret Manager"-Werkzeug arbeitet mit projektspezifischen Konfigurationseinstellungen, die in Ihrem Benutzerprofil gespeichert sind.

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

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 im Projektmappen-Explorer, und wählen Sie Benutzergeheimnisse verwalten aus dem Kontextmenü aus. Diese Geste fügt der Projektdatei ein UserSecretsId-Element hinzu, das mit einer GUID gefüllt ist.

Festlegen eines Geheimnisses

Definieren Sie ein App-Geheimnis, das aus einem Schlüssel und seinem Wert besteht. Das Geheimnis ist dem UserSecretsId-Wert des Projekts zugeordnet. Führen Sie z. B. den folgenden Befehl von dem Verzeichnis aus, in dem sich die Projektdatei befindet:

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

Im vorangehenden Beispiel weist der Doppelpunkt darauf hin, dass Movies ein Objekt-Literal mit einer ServiceApiKey-Eigenschaft ist.

Das Tool "Secret Manager" kann auch von anderen Verzeichnissen aus verwendet werden. Verwenden Sie die Option --project, um den Dateisystempfad anzugeben, unter dem die Projektdatei vorhanden ist. Beispiel:

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

JSON-Strukturvereinfachung in Visual Studio

Die Geste Benutzergeheimnisse verwalten von Visual Studio öffnet eine secrets.json-Datei im Text-Editor. Ersetzen Sie den Inhalt von secrets.json durch die zu speichernden Schlüssel-Wert-Paare. 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 vereinfacht. Wenn Sie z. B. dotnet user-secrets remove "Movies:ConnectionString" ausführen, wird das Objektliteral Movies reduziert. Die geänderte Datei ähnelt dem folgenden JSON-Code:

{
  "Movies:ServiceApiKey": "12345"
}

Festlegen mehrerer Geheimnisse

Sie können einen Batch von Geheimnissen festlegen, indem Sie JSON per Pipeline an den Befehl set weiterreichen. Im folgenden Beispiel wird der Inhalt der Datei input.json an den Befehl set weitergereicht.

Ö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

Registrierung der Konfigurationsquelle für Benutzergeheimnisse

Der Konfigurationsanbieter von Benutzergeheimnissen registriert die entsprechende Konfigurationsquelle mit der .NET-Konfigurations-API.

Die Konfigurationsquelle für die Benutzergeheimnisse wird im Entwicklungsmodus automatisch hinzugefügt, wenn das Projekt CreateDefaultBuilder aufruft. CreateDefaultBuilder ruft AddUserSecrets auf, wenn der EnvironmentNameDevelopment 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 die Benutzergeheimnisse explizit hinzu, indem Sie AddUserSecrets in ConfigureAppConfiguration aufrufen. Rufen Sie nur auf AddUserSecrets , wenn die App in der Development Umgebung 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 Sie das Secret über die Konfigurations-API

Wenn die Konfigurationsquelle für die Benutzergeheimnisse registriert ist, kann die .NET-Konfigurations-API die Geheimnisse lesen. Die Konstruktoreinschleusung 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 Pages-Seitenmodell:

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 Zugriffskonfiguration beim Start und Zugriffskonfiguration in Razor Pages.

Geheimnisse einem POCO zuordnen

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

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

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

Um die oben genannten Geheimnisse einem POCO zuzuordnen, verwenden Sie das Feature Objektgraphenbindung 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 Geheimnisse Movies:ConnectionString und Movies:ServiceApiKey werden den entsprechenden Eigenschaften in MovieSettings zugeordnet:

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

    public string ServiceApiKey { get; set; }
}

Ersetzen von Zeichenfolgen durch Geheimnisse

Die Speicherung von Kennwörtern in Nur-Text ist keine sichere Methode. Speichern Sie niemals Geheimnisse in einer Konfigurationsdatei wie appsettings.json, da diese möglicherweise in ein Quellcode-Repository eingecheckt werden könnte.

Beispiel: Eine in appsettings.json gespeicherte Datenbank-Verbindungszeichenfolge sollte kein Kennwort enthalten. Speichern Sie stattdessen das Kennwort als geheimen Schlüssel, und fügen Sie das Kennwort zur Laufzeit in die Verbindungszeichenfolge ein. Beispiel:

dotnet user-secrets set "DbPassword" "<secret value>"

Ersetzen Sie den <secret value> Platzhalter im vorherigen Beispiel durch den Kennwortwert. Legen Sie den Wert des geheimen Schlüssels für die Eigenschaft eines SqlConnectionStringBuilder Objekts Password fest, um ihn als Kennwortwert in die Verbindungszeichenfolge einzuschließ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();

Geheimnisse auflisten

Angenommen, die Datei secrets.json der Anwendung 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

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 vorangegangenen Beispiel kennzeichnet ein Doppelpunkt in den Schlüsselnamen die Objekthierarchie innerhalb von secrets.json.

Entfernen eines einzelnen Geheimnisses

Angenommen, die Datei secrets.json der Anwendung 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

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

Gehen Sie davon aus, dass die secrets.json-Datei der Anwendung 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 in dem Verzeichnis aus, in dem sich die Projektdatei befindet:

dotnet user-secrets clear

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

{}

Wenn Sie dotnet user-secrets list ausführen, wird die folgende Meldung angezeigt:

No secrets configured for this application.

Verwalten von Benutzergeheimnissen mit Visual Studio

Um Benutzergeheimnisse 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 zeigt „Benutzergeheimnisse verwalten“ an

Migrieren von Benutzergeheimnissen von ASP.NET Framework zu ASP.NET Core

Weitere Informationen finden Sie im entsprechenden GitHub-Issue.

Geheime Benutzerschlüssel in Nicht-Webanwendungen

Projekte, die auf Microsoft.NET.Sdk.Web ausgelegt sind, enthalten automatisch Unterstützung für Benutzergeheimnisse. Installieren Sie ausdrücklich die Konfigurationserweiterung und die NuGet-Pakete für Benutzergeheimnisse für Projekte, die auf Microsoft.NET.Sdk abzielen, wie Konsolenanwendungen.

Verwenden von PowerShell:

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

Verwenden der .NET-CLI:

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

Nachdem die Pakete installiert wurden, initialisieren Sie das Projekt und legen Sie geheime Schlüssel auf die gleiche Weise wie für eine Web-App fest. Das folgende Beispiel zeigt eine Konsolenanwendung, die den Wert eines Geheimnisses abruft, das mit dem Schlüssel „AppSecret“ festgelegt wurde:

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

Weitere Ressourcen