Delen via


Veilige opslag van app-geheimen in ontwikkeling in ASP.NET Core

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Door Rick Anderson en Kirk Larkin

voorbeeldcode weergeven of downloaden (hoe te downloaden)

In dit artikel wordt uitgelegd hoe u gevoelige gegevens beheert voor een ASP.NET Core-app op een ontwikkelcomputer. Sla nooit wachtwoorden of andere gevoelige gegevens op in broncode- of configuratiebestanden. Productiegeheimen mogen niet worden gebruikt voor ontwikkeling of test. Geheimen mogen niet worden geïmplementeerd met de app. Productiegeheimen moeten worden geopend via een beheerde manier, zoals Azure Key Vault. Azure-test- en productiegeheimen kunnen worden opgeslagen en beveiligd met de Azure Key Vault-configuratieprovider.

Zie Beveiligde verificatiestromenvoor meer informatie over verificatie voor geïmplementeerde test- en productie-apps.

Zie dit GitHub-probleemals u gebruikersgeheimen in een .NET-console-app wilt gebruiken.

Omgevingsvariabelen

Omgevingsvariabelen worden gebruikt om opslag van app-geheimen in code of in lokale configuratiebestanden te voorkomen. Omgevingsvariabelen overschrijven configuratiewaarden voor alle eerder opgegeven configuratiebronnen.

Overweeg een ASP.NET Core-web-app waarin de beveiliging van afzonderlijke gebruikersaccounts is ingeschakeld. Een standaarddatabaseverbindingsreeks wordt opgenomen in het appsettings.json-bestand van het project met de sleutel DefaultConnection. De standaardverbindingsreeks is voor LocalDB, die wordt uitgevoerd in de gebruikersmodus en waarvoor geen wachtwoord is vereist. Tijdens de implementatie van de app kan de DefaultConnection-sleutelwaarde worden overschreven met de waarde van een omgevingsvariabele. De omgevingsvariabele kan de volledige verbindingsreeks met gevoelige referenties opslaan.

Waarschuwing

Omgevingsvariabelen worden over het algemeen opgeslagen in niet-versleutelde tekst. Als de machine of het proces is aangetast, kunnen omgevingsvariabelen worden geopend door niet-vertrouwde partijen. Er kunnen aanvullende maatregelen nodig zijn om openbaarmaking van gebruikersgeheimen te voorkomen.

Het : scheidingsteken werkt niet met hiërarchische omgevingsvariabele sleutels op alle platforms. Het :-scheidingsteken wordt bijvoorbeeld niet ondersteund door Bash. Het dubbele onderstrepingsteken, __, is:

  • Ondersteund door alle platforms.
  • Automatisch vervangen door dubbelpunt, :.

Geheimbeheerder

Het hulpprogramma Secret Manager slaat gevoelige gegevens op tijdens het ontwikkelen van toepassingen. In deze context is een stukje gevoelige gegevens een app-geheim. App-geheimen worden opgeslagen op een afzonderlijke locatie van de projectstructuur. De app-geheimen zijn gekoppeld aan een specifiek project of worden gedeeld in verschillende projecten. De app-geheimen worden niet ingecheckt in broncodebeheer.

Waarschuwing

Het hulpprogramma Secret Manager versleutelt de opgeslagen geheimen niet en mag niet worden behandeld als een vertrouwd archief. Het is alleen voor ontwikkelingsdoeleinden. De sleutels en waarden worden opgeslagen in een JSON-configuratiebestand in de gebruikersprofielmap.

Hoe het hulpprogramma Secret Manager werkt

Het hulpprogramma Secret Manager verbergt implementatiedetails, zoals waar en hoe de waarden worden opgeslagen. U kunt het hulpprogramma gebruiken zonder deze implementatiedetails te kennen. De waarden worden opgeslagen in een JSON-bestand in de gebruikersprofielmap van de lokale computer:

Bestandssysteempad:

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

Vervang in de voorgaande bestandspaden <user_secrets_id> door de UserSecretsId waarde die is opgegeven in het projectbestand.

Schrijf geen code die afhankelijk is van de locatie of indeling van gegevens die zijn opgeslagen met het hulpprogramma Secret Manager. Deze implementatiedetails kunnen veranderen. De geheime waarden worden bijvoorbeeld niet versleuteld.

Geheime opslag inschakelen

Het hulpprogramma Secret Manager werkt op projectspecifieke configuratie-instellingen die zijn opgeslagen in uw gebruikersprofiel.

De CLI gebruiken

Het hulpprogramma Secret Manager bevat een init commando. Als u gebruikersgeheimen wilt gebruiken, voert u de volgende opdracht uit in de projectmap:

dotnet user-secrets init

Met de voorgaande opdracht wordt een UserSecretsId element toegevoegd binnen een PropertyGroup van het projectbestand. De standaard is dat de innerlijke tekst van UserSecretsId een GUID is. De binnenste tekst is willekeurig, maar is uniek voor het project.

De configuratie van de eigenschap UserSecretsId MS Build in het projectbestand van de app.

Visual Studio gebruiken

Klik in Visual Studio met de rechtermuisknop op het project in Solution Explorer en selecteer Gebruikersgeheimen beheren in het contextmenu. Met deze beweging wordt een UserSecretsId-element, gevuld met een GUID, aan het projectbestand toegevoegd.

Als GenerateAssemblyInfo is false

Als het genereren van assembly-infokenmerken is uitgeschakeld, voegt u de UserSecretsIdAttribute handmatig toe in AssemblyInfo.cs. Bijvoorbeeld:

[assembly: UserSecretsId("your_user_secrets_id")]

Wanneer u het kenmerk UserSecretsId handmatig toevoegt aan AssemblyInfo.cs, moet de UserSecretsId waarde overeenkomen met de waarde in het projectbestand.

Een geheim instellen

Definieer een app-geheim dat bestaat uit een sleutel en de bijbehorende waarde. Het geheim is gekoppeld aan de UserSecretsId waarde van het project. Voer bijvoorbeeld de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

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

In het vorige voorbeeld geeft de dubbele punt aan dat Movies een letterlijk object is met een eigenschap ServiceApiKey.

Het hulpprogramma Secret Manager kan ook worden gebruikt vanuit andere mappen. Gebruik de optie --project om het bestandssysteempad op te geven waarop het projectbestand bestaat. Bijvoorbeeld:

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

JSON-structuur platmaken in Visual Studio

Met het Gebruikersgeheimen beheren van Visual Studio beweging wordt een secrets.json bestand in de teksteditor geopend. Vervang de inhoud van secrets.json door de sleutel-waardeparen die moeten worden opgeslagen. Bijvoorbeeld:

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

De JSON-structuur wordt afgevlakt na wijzigingen via dotnet user-secrets remove of dotnet user-secrets set. Als u bijvoorbeeld dotnet user-secrets remove "Movies:ConnectionString" uitvoert, wordt de letterlijke Movies object samengevouwen. Het gewijzigde bestand lijkt op de volgende JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Meerdere geheimen instellen

Een reeks geheimen kan worden ingesteld door JSON door te sturen naar de opdracht set. In het volgende voorbeeld wordt de inhoud van het input.json bestand doorgesluisd naar de opdracht set.

Open een opdrachtshell en voer de volgende opdracht uit:

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

Toegang tot een geheim

Voer de volgende stappen uit om toegang te krijgen tot een geheim:

  1. de configuratiebron voor gebruikersgeheimen registreren
  2. het geheim lezen via de configuratie-API

De configuratiebron voor gebruikersgeheimen registreren

De gebruikersgeheimen configuratieprovider registreert de juiste configuratiebron bij de .NET Configuration-API.

ASP.NET Core-web-apps die zijn gemaakt met dotnet nieuwe of Visual Studio genereren de volgende code:

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

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

app.Run();

WebApplication.CreateBuilder initialiseert een nieuw exemplaar van de WebApplicationBuilder-klasse met vooraf geconfigureerde standaardwaarden. De geïnitialiseerde WebApplicationBuilder (builder) biedt standaardconfiguratie en roept AddUserSecrets aan wanneer de EnvironmentNameDevelopmentis.

Het geheim lezen via de configuratie-API

Bekijk de volgende voorbeelden van het lezen van de Movies:ServiceApiKey-sleutel:

Program.cs bestand:

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

var app = builder.Build();

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

app.Run();

Razor Pagina's paginamodel:

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

Zie Configuratie in ASP.NET Corevoor meer informatie.

Geheimen koppelen aan een POCO

Het toewijzen van een volledige object literal aan een POCO (een eenvoudige .NET-klasse met eigenschappen) is handig voor het verzamelen van gerelateerde eigenschappen.

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Als u de voorgaande geheimen wilt toewijzen aan een POCO, gebruikt u de objectgrafiekbinding van de .NET Configuration-API functie. De volgende code wordt gekoppeld aan een aangepaste MovieSettings POCO en opent de waarde van de ServiceApiKey eigenschap:

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

De Movies:ConnectionString en Movies:ServiceApiKey geheimen worden toegewezen aan de respectieve eigenschappen in MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Stringvervanging met geheime gegevens

Het opslaan van wachtwoorden in tekst zonder opmaak is onveilig. Sla nooit geheimen op in een configuratiebestand, zoals appsettings.json, die mogelijk worden ingecheckt in een opslagplaats met broncode.

Een databaseverbindingsreeks die is opgeslagen in appsettings.json mag bijvoorbeeld geen wachtwoord bevatten. Sla in plaats daarvan het wachtwoord op als geheim en neem het wachtwoord op in de verbindingsreeks tijdens runtime. Bijvoorbeeld:

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

Vervang de tijdelijke aanduiding <secret value> in het vorige voorbeeld door de wachtwoordwaarde. Stel de waarde van het geheim in op de eigenschap Password van een SqlConnectionStringBuilder object om deze op te nemen als de wachtwoordwaarde in de verbindingsreeks:

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

De geheimen weergeven

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets list

De volgende uitvoer wordt weergegeven:

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

In het voorgaande voorbeeld geeft een dubbele punt in de sleutelnamen de objecthiërarchie binnen secrets.jsonaan.

Eén geheim verwijderen

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets remove "Movies:ConnectionString"

Het secrets.json-bestand van de app is gewijzigd om het sleutel-waardepaar te verwijderen dat is gekoppeld aan de Movies:ConnectionString-sleutel:

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

Het volgende bericht wordt weergegeven door dotnet user-secrets list:

Movies:ServiceApiKey = 12345

Alle geheimen verwijderen

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets clear

Alle gebruikersgeheimen voor de app zijn verwijderd uit het secrets.json-bestand:

{}

Als u dotnet user-secrets list uitvoert, wordt het volgende bericht weergegeven:

No secrets configured for this application.

Gebruikersgeheimen beheren met Visual Studio

Als u gebruikersgeheimen in Visual Studio wilt beheren, klikt u met de rechtermuisknop op het project in Solution Explorer en selecteert u Gebruikersgeheimen beheren:

Visual Studio toont Beheer van gebruikersgeheimen

Gebruikersgeheimen migreren van ASP.NET Framework naar ASP.NET Core

Zie dit GitHub-probleem.

Gebruikersgeheimen in niet-webtoepassingen

Projecten die gericht zijn op Microsoft.NET.Sdk.Web bevatten automatisch ondersteuning voor gebruikersgeheimen. Installeer voor projecten die gericht zijn op Microsoft.NET.Sdk, zoals consoletoepassingen, expliciet de configuratie-extensie en gebruikersgeheimen NuGet-pakketten.

PowerShell gebruiken:

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

De .NET CLI gebruiken:

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

Zodra de pakketten zijn geïnstalleerd, het project initialiseren en geheimen instellen op dezelfde manier als voor een web-app. In het volgende voorbeeld ziet u een consoletoepassing die de waarde ophaalt van een geheim dat is ingesteld met de sleutel 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"]);
    }
}

Aanvullende informatiebronnen

Door Rick Anderson, Kirk Larkin, Daniel Rothen Scott Addie

Voorbeeldcode bekijken of downloaden (hoe te downloaden)

In dit artikel wordt uitgelegd hoe u gevoelige gegevens beheert voor een ASP.NET Core-app op een ontwikkelcomputer. Sla nooit wachtwoorden of andere gevoelige gegevens op in broncode- of configuratiebestanden. Productiegeheimen mogen niet worden gebruikt voor ontwikkeling of test. Geheimen mogen niet worden geïmplementeerd met de app. Productiegeheimen moeten worden geopend via een beheerde manier, zoals Azure Key Vault. Azure-test- en productiegeheimen kunnen worden opgeslagen en beveiligd met de Azure Key Vault-configuratieprovider.

Zie Beveiligde verificatiestromenvoor meer informatie over verificatie voor test- en productieomgevingen.

Omgevingsvariabelen

Omgevingsvariabelen worden gebruikt om opslag van app-geheimen in code of in lokale configuratiebestanden te voorkomen. Omgevingsvariabelen overschrijven configuratiewaarden voor alle eerder opgegeven configuratiebronnen.

Overweeg een ASP.NET Core-web-app waarin de beveiliging van individuele gebruikersaccounts is ingeschakeld. Een standaarddatabaseverbindingsreeks wordt opgenomen in het appsettings.json-bestand van het project met de sleutel DefaultConnection. De standaardverbindingsreeks is voor LocalDB, die wordt uitgevoerd in de gebruikersmodus en waarvoor geen wachtwoord is vereist. Tijdens de implementatie van de app kan de DefaultConnection-sleutelwaarde worden overschreven met de waarde van een omgevingsvariabele. De omgevingsvariabele kan de volledige verbindingsreeks met gevoelige referenties opslaan.

Waarschuwing

Omgevingsvariabelen worden over het algemeen opgeslagen in niet-versleutelde tekst. Als de machine of het proces is aangetast, kunnen omgevingsvariabelen worden geopend door niet-vertrouwde partijen. Er kunnen aanvullende maatregelen nodig zijn om openbaarmaking van gebruikersgeheimen te voorkomen.

Het : scheidingsteken werkt niet met hiërarchische sleutels van de omgevingsvariabele op alle platforms. Bijvoorbeeld, de :-separator wordt niet ondersteund door Bash. Het dubbele onderstrepingsteken, __, is:

  • Ondersteund door alle platforms.
  • Automatisch vervangen door een dubbele punt: :.

Geheim Beheerder

Het hulpprogramma Secret Manager slaat gevoelige gegevens op tijdens het ontwikkelen van toepassingen. In deze context is een stukje gevoelige gegevens een app-geheim. App-geheimen worden opgeslagen op een afzonderlijke locatie van de projectstructuur. De app-geheimen zijn gekoppeld aan een specifiek project of worden gedeeld in verschillende projecten. De app-geheimen worden niet ingecheckt in broncodebeheer.

Waarschuwing

Het hulpprogramma Secret Manager versleutelt de opgeslagen geheimen niet en mag niet worden behandeld als een vertrouwd archief. Het is alleen voor ontwikkelingsdoeleinden. De sleutels en waarden worden opgeslagen in een JSON-configuratiebestand in de gebruikersprofielmap.

Hoe het hulpprogramma Secret Manager werkt

Het hulpprogramma Secret Manager verbergt implementatiedetails, zoals waar en hoe de waarden worden opgeslagen. U kunt het hulpprogramma gebruiken zonder deze implementatiedetails te kennen. De waarden worden opgeslagen in een JSON-bestand in de gebruikersprofielmap van de lokale computer:

Bestandssysteempad:

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

Vervang in de voorgaande bestandspaden <user_secrets_id> door de UserSecretsId waarde die is opgegeven in het projectbestand.

Schrijf geen code die afhankelijk is van de locatie of indeling van gegevens die zijn opgeslagen met het hulpprogramma Secret Manager. Deze implementatiedetails kunnen veranderen. De geheime waarden worden bijvoorbeeld niet versleuteld, maar kunnen in de toekomst wel zijn.

Geheime opslag inschakelen

Het hulpprogramma Secret Manager werkt op projectspecifieke configuratie-instellingen die zijn opgeslagen in uw gebruikersprofiel.

Het hulpprogramma Secret Manager bevat een init opdracht in .NET Core SDK 3.0.100 of hoger. Als u gebruikersgeheimen wilt gebruiken, voert u de volgende opdracht uit in de projectmap:

dotnet user-secrets init

Met de voorgaande opdracht wordt een UserSecretsId element toegevoegd binnen een PropertyGroup van het projectbestand. Standaard is de interne tekst van UserSecretsId een GUID. De binnenste tekst is willekeurig, maar is uniek voor het project.

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

Klik in Visual Studio met de rechtermuisknop op het project in Solution Explorer en selecteer Gebruikersgeheimen beheren in het contextmenu. Met deze beweging wordt een UserSecretsId-element, gevuld met een GUID, aan het projectbestand toegevoegd.

Een geheim instellen

Definieer een app-geheim dat bestaat uit een sleutel en de bijbehorende waarde. Het geheim is gekoppeld aan de UserSecretsId waarde van het project. Voer bijvoorbeeld de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

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

In het vorige voorbeeld geeft de dubbele punt aan dat Movies een letterlijk object is met een eigenschap ServiceApiKey.

Het hulpprogramma Secret Manager kan ook worden gebruikt vanuit andere mappen. Gebruik de optie --project om het bestandssysteempad op te geven waarop het projectbestand bestaat. Bijvoorbeeld:

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

JSON-structuur platmaken in Visual Studio

Met de opdracht Gebruikergeheimen beheren van Visual Studio wordt een secrets.json bestand geopend in de teksteditor. Vervang de inhoud van secrets.json door de sleutel-waardeparen die moeten worden opgeslagen. Bijvoorbeeld:

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

De JSON-structuur wordt afgevlakt na wijzigingen via dotnet user-secrets remove of dotnet user-secrets set. Als u bijvoorbeeld dotnet user-secrets remove "Movies:ConnectionString" uitvoert, wordt de letterlijke Movies object samengevouwen. Het gewijzigde bestand lijkt op de volgende JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Meerdere geheimen instellen

Een reeks geheimen kan worden geconfigureerd door JSON door te geven aan de opdracht set. In het volgende voorbeeld wordt de inhoud van het input.json bestand doorgesluisd naar de opdracht set.

Open een opdrachtshell en voer de volgende opdracht uit:

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

Toegang tot een geheim

Voer de volgende stappen uit om toegang te krijgen tot een geheim:

  1. de configuratiebron voor gebruikersgeheimen registreren
  2. Het Geheim lezen via de configuratie-API

De configuratiebron voor gebruikersgeheimen registreren

De "User Secrets" configuratieprovider registreert de juiste configuratiebron bij de .NET Configuration API.

De configuratiebron voor gebruikersgeheimen wordt automatisch toegevoegd in de ontwikkelingsmodus wanneer het project CreateDefaultBuilderaanroept. CreateDefaultBuilder roept AddUserSecrets aan wanneer de EnvironmentNameDevelopmentis.

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

Wanneer CreateDefaultBuilder niet wordt aangeroepen, voegt u de configuratiebron van gebruikersgeheimen expliciet toe door AddUserSecrets aan te roepen in ConfigureAppConfiguration. Roep AddUserSecrets alleen aan wanneer de app wordt uitgevoerd in de ontwikkelomgeving, zoals wordt weergegeven in het volgende voorbeeld:

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

Het geheim lezen via de configuratie-API

Als de configuratiebron voor gebruikersgeheimen is geregistreerd, kan de .NET-configuratie-API de geheimen lezen. constructorinjectie kan worden gebruikt om toegang te krijgen tot de .NET-configuratie-API. Bekijk de volgende voorbeelden van het lezen van de Movies:ServiceApiKey-sleutel:

opstartklasse:

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 Pagina's paginamodel:

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

Voor meer informatie, zie Access-configuratie in Opstarten en Access-configuratie in Pagina's Razor.

Geheimen toewijzen aan een POCO

Het toewijzen van een volledige object literal aan een POCO (een eenvoudige .NET-klasse met eigenschappen) is nuttig voor het aggregeren van gerelateerde eigenschappen.

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Als u de voorgaande geheimen wilt toewijzen aan een POCO, gebruikt u de objectgrafiekbinding van de .NET Configuration-API functie. De volgende code wordt gekoppeld aan een aangepaste MovieSettings POCO en opent de waarde van de ServiceApiKey eigenschap:

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

De Movies:ConnectionString en Movies:ServiceApiKey geheimen worden toegewezen aan de respectieve eigenschappen in MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Tekenreeksvervanging met geheimen

Het opslaan van wachtwoorden in tekst zonder opmaak is onveilig. Sla nooit geheimen op in een configuratiebestand, zoals appsettings.json, die mogelijk worden ingecheckt in een opslagplaats met broncode.

Een databaseverbindingsreeks die is opgeslagen in appsettings.json mag bijvoorbeeld geen wachtwoord bevatten. Sla in plaats daarvan het wachtwoord op als geheim en neem het wachtwoord op in de verbindingsreeks tijdens runtime. Bijvoorbeeld:

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

Vervang de tijdelijke aanduiding <secret value> in het vorige voorbeeld door de wachtwoordwaarde. Stel de waarde van het geheim in op de eigenschap Password van een SqlConnectionStringBuilder object om deze op te nemen als de wachtwoordwaarde in de verbindingsreeks:

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

De geheimen weergeven

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets list

De volgende uitvoer wordt weergegeven:

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

In het voorgaande voorbeeld geeft een dubbele punt in de sleutelnamen de objecthiërarchie binnen secrets.jsonaan.

Eén geheim verwijderen

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets remove "Movies:ConnectionString"

Het secrets.json-bestand van de app is gewijzigd om het sleutel-waardepaar te verwijderen dat is gekoppeld aan de MoviesConnectionString-sleutel:

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

dotnet user-secrets list geeft het volgende bericht weer:

Movies:ServiceApiKey = 12345

Alle geheimen verwijderen

Stel dat het secrets.json-bestand van de app de volgende twee geheimen bevat:

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

Voer de volgende opdracht uit vanuit de map waarin het projectbestand bestaat:

dotnet user-secrets clear

Alle gebruikersgeheimen voor de app zijn verwijderd uit het secrets.json-bestand:

{}

Als u dotnet user-secrets list uitvoert, wordt het volgende bericht weergegeven:

No secrets configured for this application.

Gebruikersgeheimen beheren met Visual Studio

Als u gebruikersgeheimen in Visual Studio wilt beheren, klikt u met de rechtermuisknop op het project in Solution Explorer en selecteert u Gebruikersgeheimen beheren:

Visual Studio met Gebruikersgeheimen beheren

Gebruikersgeheimen migreren van ASP.NET Framework naar ASP.NET Core

Zie dit GitHub-probleem.

Gebruikersgeheimen in niet-webtoepassingen

Projecten die gericht zijn op Microsoft.NET.Sdk.Web bevatten automatisch ondersteuning voor gebruikersgeheimen. Voor projecten gericht op Microsoft.NET.Sdk, zoals consoletoepassingen, installeer expliciet de configuratie-extensie en de NuGet-pakketten voor gebruikersgeheimen.

PowerShell gebruiken:

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

De .NET CLI gebruiken:

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

Zodra de pakketten zijn geïnstalleerd, het project initialiseren en geheimen instellen op dezelfde manier als voor een web-app. In het volgende voorbeeld ziet u een consoletoepassing die de waarde ophaalt van een geheim dat is ingesteld met de sleutel 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"]);
    }
}

Aanvullende informatiebronnen