Stockage sécurisé des secrets d’application en développement dans ASP.NET Core

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version ASP.NET Core 8.0 de cet article.

Par Rick Anderson et Kirk Larkin

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Ce document explique comment gérer les données sensibles pour une application ASP.NET Core sur une machine de développement. Ne stockez jamais de mots de passe ou d'autres données sensibles dans le code source. Les secrets de production ne doivent pas être utilisés pour le développement ou les tests. Les secrets ne doivent pas être déployés avec l'application. Au lieu de cela, les secrets de production doivent être accessibles via des moyens contrôlés comme les variables d'environnement ou Azure Key Vault. Vous pouvez stocker et protéger les secrets de test et de production Azure avec le fournisseur de configuration Azure Key Vault.

Pour utiliser des secrets d'utilisateur dans une application de console .NET, consultez ce problème GitHub.

Variables d'environnement

Les variables d'environnement sont utilisées pour éviter le stockage des secrets d'application dans le code ou dans les fichiers de configuration locaux. Les variables d'environnement remplacent les valeurs de configuration pour toutes les sources de configuration précédemment spécifiées.

Considérez une application Web ASP.NET Core dans laquelle la sécurité des comptes d'utilisateurs individuels est activée. Une chaîne de connexions aux bases de données par défaut est incluse dans le fichier du projet appsettings.json avec la clé DefaultConnection. La chaîne de connexion par défaut est pour Base de données locale, qui s'exécute en mode utilisateur et ne nécessite pas de mot de passe. Lors du déploiement de l'application, la valeur de la clé DefaultConnection peut être remplacée par la valeur d'une variable d'environnement. La variable d'environnement peut stocker la chaîne de connexion complète avec des informations d'identification sensibles.

Avertissement

Les variables d'environnement sont généralement stockées en texte brut non crypté. Si la machine ou le processus est compromis, les variables d'environnement peuvent être consultées par des parties non fiables. Des mesures supplémentaires pour empêcher la divulgation de secrets d'utilisateur peuvent être nécessaires.

Le séparateur : ne fonctionne pas avec les clés hiérarchiques des variables d’environnement sur toutes les plateformes. Le double trait de soulignement __ est :

  • Pris en charge par toutes les plateformes. Par exemple, le séparateur : n’est pas pris en charge par Bash, mais __ est pris en charge.
  • Remplacé automatiquement par :

Gestionnaire secret

L’outil Secret Manager stocke les données sensibles pendant le développement des applications. Dans ce contexte, une donnée sensible est un secret d'application. Les secrets d'application sont stockés dans un emplacement distinct de l'arborescence du projet. Les secrets d'application sont associés à un projet spécifique ou partagés entre plusieurs projets. Les secrets de l'application ne sont pas vérifiés dans le contrôle de code source.

Avertissement

L'outil Secret Manager ne crypte pas les secrets stockés et ne doit pas être traité comme un magasin de confiance. C'est uniquement à des fins de développement. Les clés et les valeurs sont stockées dans un fichier de configuration JSON dans le répertoire du profil utilisateur.

Fonctionnement de l'outil Secret Manager

L'outil Secret Manager masque les détails de mise en œuvre, tels que l'emplacement et la manière dont les valeurs sont stockées. Vous pouvez utiliser l'outil sans connaître ces détails de mise en œuvre. Les valeurs sont stockées dans un fichier JSON dans le dossier de profil utilisateur de la machine locale :

Chemin du système de fichiers :

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

Dans les chemins de fichier précédents, remplacez <user_secrets_id> par la valeur spécifiée UserSecretsId dans le fichier de projet.

N'écrivez pas de code qui dépend de l'emplacement ou du format des données enregistrées avec l'outil Secret Manager. Ces détails de mise en œuvre peuvent changer. Par exemple, les valeurs secrètes ne sont pas chiffrées, mais pourraient l'être dans le futur.

Activer le stockage secret

L'outil Secret Manager fonctionne sur les paramètres de configuration spécifiques au projet stockés dans votre profil utilisateur.

L'outil Secret Manager comprend une commande init. Pour utiliser les secrets utilisateur, exécutez la commande suivante dans le répertoire du projet :

dotnet user-secrets init

La commande précédente ajoute un élément UserSecretsId dans un PropertyGroup du fichier projet. Par défaut, le texte interne de UserSecretsId est un GUID. Le texte intérieur est arbitraire, mais unique au projet.

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

Dans Visual Studio, cliquez avec le bouton droit sur le projet dans l'Explorateur de solutions et sélectionnez Gérer les secrets utilisateur dans le menu contextuel. Ce geste ajoute un élément UserSecretsId, rempli d'un GUID, au fichier de projet.

Définir un secret

Définissez un secret d'application composé d'une clé et de sa valeur. Le secret est associé à la valeur UserSecretsId du projet. Par exemple, exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

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

Dans l'exemple précédent, les deux-points indiquent que Movies s'agit d'un objet littéral avec une propriété ServiceApiKey.

L'outil Secret Manager peut également être utilisé à partir d'autres répertoires. Utilisez l'option --project pour fournir le chemin du système de fichiers dans lequel le fichier de projet existe. Par exemple :

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

l'aplatissement de la structure JSON dans Visual Studio

Le geste Visual Studio Manage User Secrets ouvre un fichier secrets.json dans l'éditeur de texte. Remplacez le contenu de secrets.json par les paires clé-valeur à stocker. Par exemple :

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

La structure JSON est mise à plat après modifications via dotnet user-secrets remove ou dotnet user-secrets set. Par exemple, l'exécution de dotnet user-secrets remove "Movies:ConnectionString" réduit le littéral d'objet Movies. Le fichier modifié ressemble au suivant JSON :

{
  "Movies:ServiceApiKey": "12345"
}

Définir plusieurs secrets

Un lot de secrets peut être défini en passant JSON à la commande set. Dans l'exemple suivant, le contenu du fichier input.json est redirigé vers la commande set.

Ouvrez un shell de commande et exécutez la commande suivante :

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

Accéder à un secret

Pour accéder à un secret, procédez comme suit :

  1. Enregistrer la source de configuration des secrets d'utilisateur
  2. Lire le secret via l'API de configuration

Enregistrer la source de configuration des secrets d'utilisateur

Le fournisseur de configuration des secrets utilisateur enregistre la source de configuration appropriée avec l'API de configuration .NET.

Les applications web ASP.NET Core créées avec dotnet new ou Visual Studio génèrent le code suivant :

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

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

app.Run();

WebApplication.CreateBuilder initialise une nouvelle instance de la classe WebApplicationBuilder avec les valeurs par défaut préconfigurées. Le initialisé WebApplicationBuilder (builder) fournit la configuration par défaut et appelle AddUserSecrets lorsque le EnvironmentName est Development :

Lire le secret via l'API de configuration

Considérez les exemples suivants de lecture de la clé Movies:ServiceApiKey :

Fichier programme.cs :

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

var app = builder.Build();

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

app.Run();

Razor Modèle de pages :

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

Pour plus d’informations, consultez Configuration dans ASP.NET Core.

Cartographier les secrets d'un POCO

Le mappage d'un littéral d'objet entier à un POCO (une classe .NET simple avec des propriétés) est utile pour agréger les propriétés associées.

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Pour mapper les secrets précédents à un POCO, utilisez la fonctionnalité de liaison de graphe d'objet de l'API de configuration .NET. Le code suivant se lie à un POCO personnalisé MovieSettings et accède à la valeur de la propriété ServiceApiKey :

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

Les secrets Movies:ConnectionString et Movies:ServiceApiKey sont mappés aux propriétés respectives dans MovieSettings :

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

    public string ServiceApiKey { get; set; }
}

Remplacement de chaîne avec des secrets

Le stockage des mots de passe en texte brut n'est pas sécurisé. Par exemple, une chaîne de connexions aux bases de données stockée dans appsettings.json peut inclure un mot de passe pour l'utilisateur spécifié :

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

Une approche plus sécurisée consiste à stocker le mot de passe en tant que secret. Par exemple :

dotnet user-secrets set "DbPassword" "pass123"

Supprimez la paire clé-valeur Password de la chaîne de connexion dans appsettings.json. Par exemple :

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

La valeur du secret peut être définie sur la SqlConnectionStringBuilder propriété Password d'un objet pour compléter la chaîne de connexion :

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

Lister les secrets

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets list

Vous obtenez la sortie suivante :

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

Dans l'exemple précédent, deux-points dans les noms de clé indiquent la hiérarchie d'objets dans secrets.json.

Supprimer un seul secret

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets remove "Movies:ConnectionString"

Le fichier de l'application secrets.json a été modifié pour supprimer la paire clé-valeur associée à la clé Movies:ConnectionString :

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

dotnet user-secrets list affiche le message suivant :

Movies:ServiceApiKey = 12345

Supprimer tous les secrets

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets clear

Tous les secrets d'utilisateur de l'application ont été supprimés du fichier secrets.json :

{}

L'exécution dotnet user-secrets list affiche le message suivant :

No secrets configured for this application.

Gérer les secrets des utilisateurs avec Visual Studio

Pour gérer les secrets d'utilisateur dans Visual Studio, cliquez avec le bouton droit sur le projet dans l'explorateur de solutions et sélectionnez Gérer les secrets d'utilisateur :

Visual Studio showing Manage User Secrets

Migration des secrets utilisateur d'ASP.NET Framework vers ASP.NET Core

Consultez ce problème GitHub.

Secrets utilisateur dans les applications non-web

Les projets qui ciblent Microsoft.NET.Sdk.Web incluent automatiquement la prise en charge des secrets utilisateur. Pour les projets qui ciblent Microsoft.NET.Sdk, tels que les applications console, installez explicitement les packages NuGet de l’extension de configuration et des secrets utilisateur.

À l’aide de PowerShell :

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

Utilisation de l’interface CLI .NET :

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

Une fois que les packages sont installés, initialisez le projet et définissez les secrets de la même façon que pour une application web. L’exemple suivant montre une application console qui récupère la valeur d’un secret qui a été défini avec la clé « 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"]);
    }
}

Ressources supplémentaires

Par Rick Anderson, Kirk Larkin, Daniel Roth et Scott Addie

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Ce document explique comment gérer les données sensibles pour une application ASP.NET Core sur une machine de développement. Ne stockez jamais de mots de passe ou d'autres données sensibles dans le code source. Les secrets de production ne doivent pas être utilisés pour le développement ou les tests. Les secrets ne doivent pas être déployés avec l'application. Au lieu de cela, les secrets de production doivent être accessibles via des moyens contrôlés comme les variables d'environnement ou Azure Key Vault. Vous pouvez stocker et protéger les secrets de test et de production Azure avec le fournisseur de configuration Azure Key Vault.

Variables d'environnement

Les variables d'environnement sont utilisées pour éviter le stockage des secrets d'application dans le code ou dans les fichiers de configuration locaux. Les variables d'environnement remplacent les valeurs de configuration pour toutes les sources de configuration précédemment spécifiées.

Considérez une application Web ASP.NET Core dans laquelle la sécurité des comptes d'utilisateurs individuels est activée. Une chaîne de connexions aux bases de données par défaut est incluse dans le fichier du projet appsettings.json avec la clé DefaultConnection. La chaîne de connexion par défaut est pour Base de données locale, qui s'exécute en mode utilisateur et ne nécessite pas de mot de passe. Lors du déploiement de l'application, la valeur de la clé DefaultConnection peut être remplacée par la valeur d'une variable d'environnement. La variable d'environnement peut stocker la chaîne de connexion complète avec des informations d'identification sensibles.

Avertissement

Les variables d'environnement sont généralement stockées en texte brut non crypté. Si la machine ou le processus est compromis, les variables d'environnement peuvent être consultées par des parties non fiables. Des mesures supplémentaires pour empêcher la divulgation de secrets d'utilisateur peuvent être nécessaires.

Le séparateur : ne fonctionne pas avec les clés hiérarchiques des variables d’environnement sur toutes les plateformes. Le double trait de soulignement __ est :

  • Pris en charge par toutes les plateformes. Par exemple, le séparateur : n’est pas pris en charge par Bash, mais __ est pris en charge.
  • Remplacé automatiquement par :

Gestionnaire secret

L’outil Secret Manager stocke les données sensibles pendant le développement des applications. Dans ce contexte, une donnée sensible est un secret d'application. Les secrets d'application sont stockés dans un emplacement distinct de l'arborescence du projet. Les secrets d'application sont associés à un projet spécifique ou partagés entre plusieurs projets. Les secrets de l'application ne sont pas vérifiés dans le contrôle de code source.

Avertissement

L'outil Secret Manager ne crypte pas les secrets stockés et ne doit pas être traité comme un magasin de confiance. C'est uniquement à des fins de développement. Les clés et les valeurs sont stockées dans un fichier de configuration JSON dans le répertoire du profil utilisateur.

Fonctionnement de l'outil Secret Manager

L'outil Secret Manager masque les détails de mise en œuvre, tels que l'emplacement et la manière dont les valeurs sont stockées. Vous pouvez utiliser l'outil sans connaître ces détails de mise en œuvre. Les valeurs sont stockées dans un fichier JSON dans le dossier de profil utilisateur de la machine locale :

Chemin du système de fichiers :

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

Dans les chemins de fichier précédents, remplacez <user_secrets_id> par la valeur spécifiée UserSecretsId dans le fichier de projet.

N'écrivez pas de code qui dépend de l'emplacement ou du format des données enregistrées avec l'outil Secret Manager. Ces détails de mise en œuvre peuvent changer. Par exemple, les valeurs secrètes ne sont pas chiffrées, mais pourraient l'être dans le futur.

Activer le stockage secret

L'outil Secret Manager fonctionne sur les paramètres de configuration spécifiques au projet stockés dans votre profil utilisateur.

L'outil Secret Manager inclut une commande init dans .NET Core SDK 3.0.100 ou version ultérieure. Pour utiliser les secrets utilisateur, exécutez la commande suivante dans le répertoire du projet :

dotnet user-secrets init

La commande précédente ajoute un élément UserSecretsId dans un PropertyGroup du fichier projet. Par défaut, le texte interne de UserSecretsId est un GUID. Le texte intérieur est arbitraire, mais unique au projet.

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

Dans Visual Studio, cliquez avec le bouton droit sur le projet dans l'Explorateur de solutions et sélectionnez Gérer les secrets utilisateur dans le menu contextuel. Ce geste ajoute un élément UserSecretsId, rempli d'un GUID, au fichier de projet.

Définir un secret

Définissez un secret d'application composé d'une clé et de sa valeur. Le secret est associé à la valeur UserSecretsId du projet. Par exemple, exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

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

Dans l'exemple précédent, les deux-points indiquent que Movies s'agit d'un objet littéral avec une propriété ServiceApiKey.

L'outil Secret Manager peut également être utilisé à partir d'autres répertoires. Utilisez l'option --project pour fournir le chemin du système de fichiers dans lequel le fichier de projet existe. Par exemple :

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

l'aplatissement de la structure JSON dans Visual Studio

Le geste Visual Studio Manage User Secrets ouvre un fichier secrets.json dans l'éditeur de texte. Remplacez le contenu de secrets.json par les paires clé-valeur à stocker. Par exemple :

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

La structure JSON est mise à plat après modifications via dotnet user-secrets remove ou dotnet user-secrets set. Par exemple, l'exécution de dotnet user-secrets remove "Movies:ConnectionString" réduit le littéral d'objet Movies. Le fichier modifié ressemble au suivant JSON :

{
  "Movies:ServiceApiKey": "12345"
}

Définir plusieurs secrets

Un lot de secrets peut être défini en passant JSON à la commande set. Dans l'exemple suivant, le contenu du fichier input.json est redirigé vers la commande set.

Ouvrez un shell de commande et exécutez la commande suivante :

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

Accéder à un secret

Pour accéder à un secret, procédez comme suit :

  1. Enregistrer la source de configuration des secrets d'utilisateur
  2. Lire le secret via l'API de configuration

Enregistrer la source de configuration des secrets d'utilisateur

Le fournisseur de configuration des secrets utilisateur enregistre la source de configuration appropriée avec l'API de configuration .NET.

La source de configuration des secrets utilisateur est automatiquement ajoutée en mode Développement lorsque le projet appelle CreateDefaultBuilder. CreateDefaultBuilder appelle AddUserSecrets quand EnvironmentName est Development :

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

Lorsque CreateDefaultBuilder n'est pas appelé, ajoutez explicitement la source de configuration des secrets d'utilisateur AddUserSecrets en appelant ConfigureAppConfiguration. Appelez AddUserSecrets uniquement lorsque l'application s'exécute dans l'environnement de développement, comme illustré dans l'exemple suivant :

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

Lire le secret via l'API de configuration

Si la source de configuration des secrets utilisateur est enregistrée, l'API de configuration .NET peut lire les secrets. L'injection de constructeur peut être utilisée pour accéder à l'API de configuration .NET. Considérez les exemples suivants de lecture de la clé Movies:ServiceApiKey :

Classe de démarrage :

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 Modèle de pages :

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

Pour plus d'informations, consultez Configuration de l'accès dans Démarrage et Configuration de l'accès dans Razor Pages.

Cartographier les secrets d'un POCO

Le mappage d'un littéral d'objet entier à un POCO (une classe .NET simple avec des propriétés) est utile pour agréger les propriétés associées.

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Pour mapper les secrets précédents à un POCO, utilisez la fonctionnalité de liaison de graphe d'objet de l'API de configuration .NET. Le code suivant se lie à un POCO personnalisé MovieSettings et accède à la valeur de la propriété ServiceApiKey :

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

Les secrets Movies:ConnectionString et Movies:ServiceApiKey sont mappés aux propriétés respectives dans MovieSettings :

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

    public string ServiceApiKey { get; set; }
}

Remplacement de chaîne avec des secrets

Le stockage des mots de passe en texte brut n'est pas sécurisé. Par exemple, une chaîne de connexions aux bases de données stockée dans appsettings.json peut inclure un mot de passe pour l'utilisateur spécifié :

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

Une approche plus sécurisée consiste à stocker le mot de passe en tant que secret. Par exemple :

dotnet user-secrets set "DbPassword" "pass123"

Supprimez la paire clé-valeur Password de la chaîne de connexion dans appsettings.json. Par exemple :

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

La valeur du secret peut être définie sur la SqlConnectionStringBuilder propriété Password d'un objet pour compléter la chaîne de connexion :

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

Lister les secrets

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets list

Vous obtenez la sortie suivante :

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

Dans l'exemple précédent, deux-points dans les noms de clé indiquent la hiérarchie d'objets dans secrets.json.

Supprimer un seul secret

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets remove "Movies:ConnectionString"

Le fichier de l'application secrets.json a été modifié pour supprimer la paire clé-valeur associée à la clé MoviesConnectionString :

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

dotnet user-secrets list affiche le message suivant :

Movies:ServiceApiKey = 12345

Supprimer tous les secrets

Supposons que le fichier de l'application secrets.json contienne les deux secrets suivants :

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier projet :

dotnet user-secrets clear

Tous les secrets d'utilisateur de l'application ont été supprimés du fichier secrets.json :

{}

L'exécution dotnet user-secrets list affiche le message suivant :

No secrets configured for this application.

Gérer les secrets des utilisateurs avec Visual Studio

Pour gérer les secrets d'utilisateur dans Visual Studio, cliquez avec le bouton droit sur le projet dans l'explorateur de solutions et sélectionnez Gérer les secrets d'utilisateur :

Visual Studio showing Manage User Secrets

Migration des secrets utilisateur d'ASP.NET Framework vers ASP.NET Core

Consultez ce problème GitHub.

Secrets utilisateur dans les applications non-web

Les projets qui ciblent Microsoft.NET.Sdk.Web incluent automatiquement la prise en charge des secrets utilisateur. Pour les projets qui ciblent Microsoft.NET.Sdk, tels que les applications console, installez explicitement les packages NuGet de l’extension de configuration et des secrets utilisateur.

À l’aide de PowerShell :

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

Utilisation de l’interface CLI .NET :

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

Une fois que les packages sont installés, initialisez le projet et définissez les secrets de la même façon que pour une application web. L’exemple suivant montre une application console qui récupère la valeur d’un secret qui a été défini avec la clé « 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"]);
    }
}

Ressources supplémentaires