Stockage sécurisé des secrets d’application en développement dans ASP.NET CoreSafe storage of app secrets in development in ASP.NET Core

Par Rick Anderson, Kirk Larkin, Daniel Rothet Scott AddieBy Rick Anderson, Kirk Larkin, Daniel Roth, and Scott Addie

Afficher ou télécharger l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Ce document décrit les techniques de stockage et de récupération des données sensibles lors du développement d’une application ASP.NET Core sur un ordinateur de développement.This document explains techniques for storing and retrieving sensitive data during development of an ASP.NET Core app on a development machine. Ne stockez jamais de mots de passe ou d’autres données sensibles dans le code source.Never store passwords or other sensitive data in source code. Les secrets de production ne doivent pas être utilisés à des fins de développement ou de test.Production secrets shouldn't be used for development or test. Les secrets ne doivent pas être déployés avec l’application.Secrets shouldn't be deployed with the app. Au lieu de cela, les secrets doivent être mis à disposition dans l’environnement de production par un moyen contrôlé, comme les variables d’environnement, les Azure Key Vault, etc. Vous pouvez stocker et protéger les secrets de test et de production Azure à l’aide du fournisseur de configuration Azure Key Vault.Instead, secrets should be made available in the production environment through a controlled means like environment variables, Azure Key Vault, etc. You can store and protect Azure test and production secrets with the Azure Key Vault configuration provider.

Variables d'environnementEnvironment variables

Les variables d’environnement sont utilisées pour éviter le stockage des secrets d’application dans le code ou dans des fichiers de configuration locaux.Environment variables are used to avoid storage of app secrets in code or in local configuration files. Les variables d’environnement remplacent les valeurs de configuration pour toutes les sources de configuration spécifiées précédemment.Environment variables override configuration values for all previously specified configuration sources.

Prenons l’exemple d’une application Web ASP.NET Core dans laquelle la sécurité des comptes d’utilisateur individuels est activée.Consider an ASP.NET Core web app in which Individual User Accounts security is enabled. Une chaîne de connexion de base de données par défaut est incluse dans le fichier appsettings.js du projet avec la clé DefaultConnection .A default database connection string is included in the project's appsettings.json file with the key DefaultConnection. La chaîne de connexion par défaut est pour la base de données locale, qui s’exécute en mode utilisateur et ne nécessite pas de mot de passe.The default connection string is for LocalDB, which runs in user mode and doesn't require a password. Pendant le déploiement de l’application, la DefaultConnection valeur de clé peut être remplacée par la valeur d’une variable d’environnement.During app deployment, the DefaultConnection key value can be overridden with an environment variable's value. La variable d’environnement peut stocker la chaîne de connexion complète avec des informations d’identification sensibles.The environment variable may store the complete connection string with sensitive credentials.

Avertissement

Les variables d’environnement sont généralement stockées en texte brut et non chiffré.Environment variables are generally stored in plain, unencrypted text. Si l’ordinateur ou le processus est compromis, les variables d’environnement sont accessibles aux parties non fiables.If the machine or process is compromised, environment variables can be accessed by untrusted parties. Des mesures supplémentaires pour empêcher la divulgation de secrets d’utilisateur peuvent être nécessaires.Additional measures to prevent disclosure of user secrets may be required.

Le : séparateur ne fonctionne pas avec les clés hiérarchiques de variable d’environnement sur toutes les plateformes.The : separator doesn't work with environment variable hierarchical keys on all platforms. __, le double trait de soulignement, est :__, the double underscore, is:

  • Pris en charge par toutes les plateformes.Supported by all platforms. Par exemple, le : séparateur n’est pas pris en charge par bash, mais __ est.For example, the : separator is not supported by Bash, but __ is.
  • Automatiquement remplacé par un :Automatically replaced by a :

Gestionnaire de secretSecret Manager

L’outil secret Manager stocke les données sensibles pendant le développement d’un projet ASP.NET Core.The Secret Manager tool stores sensitive data during the development of an ASP.NET Core project. Dans ce contexte, un élément de données sensibles est un secret d’application.In this context, a piece of sensitive data is an app secret. Les secrets de l’application sont stockés dans un emplacement distinct de l’arborescence du projet.App secrets are stored in a separate location from the project tree. Les secrets de l’application sont associés à un projet spécifique ou partagés entre plusieurs projets.The app secrets are associated with a specific project or shared across several projects. Les secrets de l’application ne sont pas archivés dans le contrôle de code source.The app secrets aren't checked into source control.

Avertissement

L’outil Gestionnaire de secret ne chiffre pas les secrets stockés et ne doit pas être traité comme un magasin approuvé.The Secret Manager tool doesn't encrypt the stored secrets and shouldn't be treated as a trusted store. À des fins de développement uniquement.It's for development purposes only. Les clés et les valeurs sont stockées dans un fichier de configuration JSON dans le répertoire du profil utilisateur.The keys and values are stored in a JSON configuration file in the user profile directory.

Fonctionnement de l’outil secret ManagerHow the Secret Manager tool works

L’outil Gestionnaire de secret résume les détails de l’implémentation, tels que l’emplacement et la manière dont les valeurs sont stockées.The Secret Manager tool abstracts away the implementation details, such as where and how the values are stored. Vous pouvez utiliser l’outil sans connaître ces détails d’implémentation.You can use the tool without knowing these implementation details. Les valeurs sont stockées dans un fichier de configuration JSON dans un dossier de profil utilisateur protégé du système sur l’ordinateur local :The values are stored in a JSON configuration file in a system-protected user profile folder on the local machine:

Chemin d’accès au système de fichiers :File system path:

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

Dans les chemins d’accès de fichier précédents, remplacez <user_secrets_id> par la UserSecretsId valeur spécifiée dans le fichier . csproj .In the preceding file paths, replace <user_secrets_id> with the UserSecretsId value specified in the .csproj file.

N’écrivez pas de code dépendant de l’emplacement ou du format des données enregistrées avec l’outil secret Manager.Don't write code that depends on the location or format of data saved with the Secret Manager tool. Ces détails d’implémentation peuvent changer.These implementation details may change. Par exemple, les valeurs secrètes ne sont pas chiffrées, mais peuvent être dans le futur.For example, the secret values aren't encrypted, but could be in the future.

Activer le stockage secretEnable secret storage

L’outil Gestionnaire de secret fonctionne sur les paramètres de configuration spécifiques au projet stockés dans votre profil utilisateur.The Secret Manager tool operates on project-specific configuration settings stored in your user profile.

L’outil Gestionnaire de secret comprend une init commande dans kit SDK .net Core 3.0.100 ou version ultérieure.The Secret Manager tool includes an init command in .NET Core SDK 3.0.100 or later. Pour utiliser des secrets d’utilisateur, exécutez la commande suivante dans le répertoire du projet :To use user secrets, run the following command in the project directory:

dotnet user-secrets init

La commande précédente ajoute un UserSecretsId élément dans un PropertyGroup du fichier . csproj .The preceding command adds a UserSecretsId element within a PropertyGroup of the .csproj file. Par défaut, le texte interne de UserSecretsId est un GUID.By default, the inner text of UserSecretsId is a GUID. Le texte interne est arbitraire, mais il est unique pour le projet.The inner text is arbitrary, but is unique to the project.

<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 Explorateur de solutions, puis sélectionnez gérer les secrets d’utilisateur dans le menu contextuel.In Visual Studio, right-click the project in Solution Explorer, and select Manage User Secrets from the context menu. Ce geste ajoute un UserSecretsId élément, rempli avec un GUID, au fichier . csproj .This gesture adds a UserSecretsId element, populated with a GUID, to the .csproj file.

Définir une clé secrèteSet a secret

Définissez un secret d’application comprenant une clé et sa valeur.Define an app secret consisting of a key and its value. Le secret est associé à la valeur du projet UserSecretsId .The secret is associated with the project's UserSecretsId value. Par exemple, exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :For example, run the following command from the directory in which the .csproj file exists:

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

Dans l’exemple précédent, le signe deux-points indique qu' Movies il s’agit d’un littéral d’objet avec une ServiceApiKey propriété.In the preceding example, the colon denotes that Movies is an object literal with a ServiceApiKey property.

L’outil Gestionnaire de secret peut également être utilisé à partir d’autres annuaires.The Secret Manager tool can be used from other directories too. Utilisez l' --project option pour fournir le chemin d’accès au système de fichiers où se trouve le fichier . csproj .Use the --project option to supply the file system path at which the .csproj file exists. Par exemple :For example:

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

Aplatissement de la structure JSON dans Visual StudioJSON structure flattening in Visual Studio

Le geste gérer les secrets de l’utilisateur de Visual Studio ouvre un secrets.jssur le fichier dans l’éditeur de texte.Visual Studio's Manage User Secrets gesture opens a secrets.json file in the text editor. Remplacez le contenu de secrets.js par les paires clé-valeur à stocker.Replace the contents of secrets.json with the key-value pairs to be stored. Par exemple :For example:

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

La structure JSON est aplatie après des modifications via dotnet user-secrets remove ou dotnet user-secrets set .The JSON structure is flattened after modifications via dotnet user-secrets remove or dotnet user-secrets set. Par exemple, l’exécution de dotnet user-secrets remove "Movies:ConnectionString" réduit le Movies littéral d’objet.For example, running dotnet user-secrets remove "Movies:ConnectionString" collapses the Movies object literal. Le fichier modifié ressemble à ce qui suit :The modified file resembles the following:

{
  "Movies:ServiceApiKey": "12345"
}

Définir plusieurs secretsSet multiple secrets

Un lot de secrets peut être défini par la canalisation JSON à la set commande.A batch of secrets can be set by piping JSON to the set command. Dans l’exemple suivant, le input.js le contenu du fichier est dirigé vers la set commande.In the following example, the input.json file's contents are piped to the set command.

Ouvrez une interface de commande, puis exécutez la commande suivante :Open a command shell, and execute the following command:

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

Accéder à une clé secrèteAccess a secret

L' API de Configuration ASP.net Core permet d’accéder aux secrets du gestionnaire de secret.The ASP.NET Core Configuration API provides access to Secret Manager secrets.

La source de configuration des secrets de l’utilisateur est automatiquement ajoutée en mode de développement lorsque le projet appelle CreateDefaultBuilder pour initialiser une nouvelle instance de l’hôte avec des valeurs par défaut préconfigurées.The user secrets configuration source is automatically added in development mode when the project calls CreateDefaultBuilder to initialize a new instance of the host with preconfigured defaults. CreateDefaultBuilder appelle AddUserSecrets lorsque EnvironmentName est Development :CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development:

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

Quand CreateDefaultBuilder n’est pas appelé, ajoutez explicitement la source de configuration des secrets de l’utilisateur en appelant AddUserSecrets .When CreateDefaultBuilder isn't called, add the user secrets configuration source explicitly by calling AddUserSecrets. Appelez AddUserSecrets uniquement lorsque l’application s’exécute dans l’environnement de développement, comme illustré dans l’exemple suivant :Call AddUserSecrets only when the app runs in the Development environment, as shown in the following example:

var host = new HostBuilder()
    .ConfigureAppConfiguration((hostContext, builder) =>
    {
        // Add other providers for JSON, etc.

        if (hostContext.HostingEnvironment.IsDevelopment())
        {
            builder.AddUserSecrets<Program>();
        }
    })
    .Build();

Les secrets de l’utilisateur peuvent être récupérés via l' Configuration API :User secrets can be retrieved via the Configuration API:

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

Mapper les secrets à un POCOMap secrets to a POCO

Le mappage d’un littéral d’objet entier à un POCO (une classe .NET simple avec des propriétés) est utile pour l’agrégation des propriétés associées.Mapping an entire object literal to a POCO (a simple .NET class with properties) is useful for aggregating related properties.

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Pour mapper les secrets précédents à un POCO, utilisez la Configuration fonctionnalité de liaison de graphique d’objets de l’API.To map the preceding secrets to a POCO, use the Configuration API's object graph binding feature. Le code suivant est lié à un MovieSettings poco personnalisé et accède à la ServiceApiKey valeur de la propriété :The following code binds to a custom MovieSettings POCO and accesses the ServiceApiKey property value:

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

Les Movies:ConnectionString Movies:ServiceApiKey secrets et sont mappés aux propriétés respectives dans MovieSettings :The Movies:ConnectionString and Movies:ServiceApiKey secrets are mapped to the respective properties in MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Remplacement de chaîne par des secretsString replacement with secrets

Le stockage des mots de passe en texte brut n’est pas sécurisé.Storing passwords in plain text is insecure. Par exemple, une chaîne de connexion de base de données stockée dans appsettings.jssur peut inclure un mot de passe pour l’utilisateur spécifié :For example, a database connection string stored in appsettings.json may include a password for the specified user:

{
  "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.A more secure approach is to store the password as a secret. Par exemple :For example:

dotnet user-secrets set "DbPassword" "pass123"

Supprimez la Password paire clé-valeur de la chaîne de connexion dans appsettings.jssur.Remove the Password key-value pair from the connection string in appsettings.json. Par exemple :For example:

{
  "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é d’un objet Password pour terminer la chaîne de connexion :The secret's value can be set on a SqlConnectionStringBuilder object's Password property to complete the connection string:

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

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Répertorier les secretsList the secrets

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets list

Vous obtenez la sortie suivante :The following output appears:

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

Dans l’exemple précédent, un signe deux-points dans les noms de clé désigne la hiérarchie d’objets dans secrets.jssur.In the preceding example, a colon in the key names denotes the object hierarchy within secrets.json.

Supprimer une seule clé secrèteRemove a single secret

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets remove "Movies:ConnectionString"

L'secrets.jsde l’application * sur* le fichier a été modifiée pour supprimer la paire clé-valeur associée à la MoviesConnectionString clé :The app's secrets.json file was modified to remove the key-value pair associated with the MoviesConnectionString key:

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

dotnet user-secrets list affiche le message suivant :dotnet user-secrets list displays the following message:

Movies:ServiceApiKey = 12345

Supprimer tous les secretsRemove all secrets

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets clear

Tous les secrets d’utilisateur de l’application ont été supprimés de l' secrets.jssur le fichier :All user secrets for the app have been deleted from the secrets.json file:

{}

dotnet user-secrets listL’exécution affiche le message suivant :Running dotnet user-secrets list displays the following message:

No secrets configured for this application.

Ressources complémentairesAdditional resources

Par Rick Anderson, Daniel Rothet Scott AddieBy Rick Anderson, Daniel Roth, and Scott Addie

Afficher ou télécharger l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Ce document décrit les techniques de stockage et de récupération des données sensibles lors du développement d’une application ASP.NET Core sur un ordinateur de développement.This document explains techniques for storing and retrieving sensitive data during development of an ASP.NET Core app on a development machine. Ne stockez jamais de mots de passe ou d’autres données sensibles dans le code source.Never store passwords or other sensitive data in source code. Les secrets de production ne doivent pas être utilisés à des fins de développement ou de test.Production secrets shouldn't be used for development or test. Les secrets ne doivent pas être déployés avec l’application.Secrets shouldn't be deployed with the app. Au lieu de cela, les secrets doivent être mis à disposition dans l’environnement de production par un moyen contrôlé, comme les variables d’environnement, les Azure Key Vault, etc. Vous pouvez stocker et protéger les secrets de test et de production Azure à l’aide du fournisseur de configuration Azure Key Vault.Instead, secrets should be made available in the production environment through a controlled means like environment variables, Azure Key Vault, etc. You can store and protect Azure test and production secrets with the Azure Key Vault configuration provider.

Variables d'environnementEnvironment variables

Les variables d’environnement sont utilisées pour éviter le stockage des secrets d’application dans le code ou dans des fichiers de configuration locaux.Environment variables are used to avoid storage of app secrets in code or in local configuration files. Les variables d’environnement remplacent les valeurs de configuration pour toutes les sources de configuration spécifiées précédemment.Environment variables override configuration values for all previously specified configuration sources.

Prenons l’exemple d’une application Web ASP.NET Core dans laquelle la sécurité des comptes d’utilisateur individuels est activée.Consider an ASP.NET Core web app in which Individual User Accounts security is enabled. Une chaîne de connexion de base de données par défaut est incluse dans le fichier appsettings.js du projet avec la clé DefaultConnection .A default database connection string is included in the project's appsettings.json file with the key DefaultConnection. La chaîne de connexion par défaut est pour la base de données locale, qui s’exécute en mode utilisateur et ne nécessite pas de mot de passe.The default connection string is for LocalDB, which runs in user mode and doesn't require a password. Pendant le déploiement de l’application, la DefaultConnection valeur de clé peut être remplacée par la valeur d’une variable d’environnement.During app deployment, the DefaultConnection key value can be overridden with an environment variable's value. La variable d’environnement peut stocker la chaîne de connexion complète avec des informations d’identification sensibles.The environment variable may store the complete connection string with sensitive credentials.

Avertissement

Les variables d’environnement sont généralement stockées en texte brut et non chiffré.Environment variables are generally stored in plain, unencrypted text. Si l’ordinateur ou le processus est compromis, les variables d’environnement sont accessibles aux parties non fiables.If the machine or process is compromised, environment variables can be accessed by untrusted parties. Des mesures supplémentaires pour empêcher la divulgation de secrets d’utilisateur peuvent être nécessaires.Additional measures to prevent disclosure of user secrets may be required.

Le : séparateur ne fonctionne pas avec les clés hiérarchiques de variable d’environnement sur toutes les plateformes.The : separator doesn't work with environment variable hierarchical keys on all platforms. __, le double trait de soulignement, est :__, the double underscore, is:

  • Pris en charge par toutes les plateformes.Supported by all platforms. Par exemple, le : séparateur n’est pas pris en charge par bash, mais __ est.For example, the : separator is not supported by Bash, but __ is.
  • Automatiquement remplacé par un :Automatically replaced by a :

Gestionnaire de secretSecret Manager

L’outil secret Manager stocke les données sensibles pendant le développement d’un projet ASP.NET Core.The Secret Manager tool stores sensitive data during the development of an ASP.NET Core project. Dans ce contexte, un élément de données sensibles est un secret d’application.In this context, a piece of sensitive data is an app secret. Les secrets de l’application sont stockés dans un emplacement distinct de l’arborescence du projet.App secrets are stored in a separate location from the project tree. Les secrets de l’application sont associés à un projet spécifique ou partagés entre plusieurs projets.The app secrets are associated with a specific project or shared across several projects. Les secrets de l’application ne sont pas archivés dans le contrôle de code source.The app secrets aren't checked into source control.

Avertissement

L’outil Gestionnaire de secret ne chiffre pas les secrets stockés et ne doit pas être traité comme un magasin approuvé.The Secret Manager tool doesn't encrypt the stored secrets and shouldn't be treated as a trusted store. À des fins de développement uniquement.It's for development purposes only. Les clés et les valeurs sont stockées dans un fichier de configuration JSON dans le répertoire du profil utilisateur.The keys and values are stored in a JSON configuration file in the user profile directory.

Fonctionnement de l’outil secret ManagerHow the Secret Manager tool works

L’outil Gestionnaire de secret résume les détails de l’implémentation, tels que l’emplacement et la manière dont les valeurs sont stockées.The Secret Manager tool abstracts away the implementation details, such as where and how the values are stored. Vous pouvez utiliser l’outil sans connaître ces détails d’implémentation.You can use the tool without knowing these implementation details. Les valeurs sont stockées dans un fichier de configuration JSON dans un dossier de profil utilisateur protégé du système sur l’ordinateur local :The values are stored in a JSON configuration file in a system-protected user profile folder on the local machine:

Chemin d’accès au système de fichiers :File system path:

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

Dans les chemins d’accès de fichier précédents, remplacez <user_secrets_id> par la UserSecretsId valeur spécifiée dans le fichier . csproj .In the preceding file paths, replace <user_secrets_id> with the UserSecretsId value specified in the .csproj file.

N’écrivez pas de code dépendant de l’emplacement ou du format des données enregistrées avec l’outil secret Manager.Don't write code that depends on the location or format of data saved with the Secret Manager tool. Ces détails d’implémentation peuvent changer.These implementation details may change. Par exemple, les valeurs secrètes ne sont pas chiffrées, mais peuvent être dans le futur.For example, the secret values aren't encrypted, but could be in the future.

Activer le stockage secretEnable secret storage

L’outil Gestionnaire de secret fonctionne sur les paramètres de configuration spécifiques au projet stockés dans votre profil utilisateur.The Secret Manager tool operates on project-specific configuration settings stored in your user profile.

Pour utiliser des secrets d’utilisateur, définissez un UserSecretsId élément dans un PropertyGroup du fichier . csproj .To use user secrets, define a UserSecretsId element within a PropertyGroup of the .csproj file. Le texte interne de UserSecretsId est arbitraire, mais il est unique pour le projet.The inner text of UserSecretsId is arbitrary, but is unique to the project. Les développeurs génèrent généralement un GUID pour le UserSecretsId .Developers typically generate a GUID for the UserSecretsId.

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

Conseil

Dans Visual Studio, cliquez avec le bouton droit sur le projet dans Explorateur de solutions, puis sélectionnez gérer les secrets d’utilisateur dans le menu contextuel.In Visual Studio, right-click the project in Solution Explorer, and select Manage User Secrets from the context menu. Ce geste ajoute un UserSecretsId élément, rempli avec un GUID, au fichier . csproj .This gesture adds a UserSecretsId element, populated with a GUID, to the .csproj file.

Définir une clé secrèteSet a secret

Définissez un secret d’application comprenant une clé et sa valeur.Define an app secret consisting of a key and its value. Le secret est associé à la valeur du projet UserSecretsId .The secret is associated with the project's UserSecretsId value. Par exemple, exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :For example, run the following command from the directory in which the .csproj file exists:

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

Dans l’exemple précédent, le signe deux-points indique qu' Movies il s’agit d’un littéral d’objet avec une ServiceApiKey propriété.In the preceding example, the colon denotes that Movies is an object literal with a ServiceApiKey property.

L’outil Gestionnaire de secret peut également être utilisé à partir d’autres annuaires.The Secret Manager tool can be used from other directories too. Utilisez l' --project option pour fournir le chemin d’accès au système de fichiers où se trouve le fichier . csproj .Use the --project option to supply the file system path at which the .csproj file exists. Par exemple :For example:

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

Aplatissement de la structure JSON dans Visual StudioJSON structure flattening in Visual Studio

Le geste gérer les secrets de l’utilisateur de Visual Studio ouvre un secrets.jssur le fichier dans l’éditeur de texte.Visual Studio's Manage User Secrets gesture opens a secrets.json file in the text editor. Remplacez le contenu de secrets.js par les paires clé-valeur à stocker.Replace the contents of secrets.json with the key-value pairs to be stored. Par exemple :For example:

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

La structure JSON est aplatie après des modifications via dotnet user-secrets remove ou dotnet user-secrets set .The JSON structure is flattened after modifications via dotnet user-secrets remove or dotnet user-secrets set. Par exemple, l’exécution de dotnet user-secrets remove "Movies:ConnectionString" réduit le Movies littéral d’objet.For example, running dotnet user-secrets remove "Movies:ConnectionString" collapses the Movies object literal. Le fichier modifié ressemble à ce qui suit :The modified file resembles the following:

{
  "Movies:ServiceApiKey": "12345"
}

Définir plusieurs secretsSet multiple secrets

Un lot de secrets peut être défini par la canalisation JSON à la set commande.A batch of secrets can be set by piping JSON to the set command. Dans l’exemple suivant, le input.js le contenu du fichier est dirigé vers la set commande.In the following example, the input.json file's contents are piped to the set command.

Ouvrez une interface de commande, puis exécutez la commande suivante :Open a command shell, and execute the following command:

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

Accéder à une clé secrèteAccess a secret

L' API de Configuration ASP.net Core permet d’accéder aux secrets du gestionnaire de secret.The ASP.NET Core Configuration API provides access to Secret Manager secrets.

Si votre projet cible .NET Framework, installez le Microsoft.Extensions.Configfiguration. Package NuGet UserSecrets.If your project targets .NET Framework, install the Microsoft.Extensions.Configuration.UserSecrets NuGet package.

Dans ASP.NET Core 2,0 ou version ultérieure, la source de configuration des secrets de l’utilisateur est automatiquement ajoutée en mode de développement lorsque le projet appelle CreateDefaultBuilder pour initialiser une nouvelle instance de l’hôte avec des valeurs par défaut préconfigurées.In ASP.NET Core 2.0 or later, the user secrets configuration source is automatically added in development mode when the project calls CreateDefaultBuilder to initialize a new instance of the host with preconfigured defaults. CreateDefaultBuilder appelle AddUserSecrets lorsque EnvironmentName est Development :CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

Quand CreateDefaultBuilder n’est pas appelé, ajoutez explicitement la source de configuration des secrets de l’utilisateur en appelant AddUserSecrets dans le Startup constructeur.When CreateDefaultBuilder isn't called, add the user secrets configuration source explicitly by calling AddUserSecrets in the Startup constructor. Appelez AddUserSecrets uniquement lorsque l’application s’exécute dans l’environnement de développement, comme illustré dans l’exemple suivant :Call AddUserSecrets only when the app runs in the Development environment, as shown in the following example:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", 
                     optional: false, 
                     reloadOnChange: true)
        .AddEnvironmentVariables();

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets<Startup>();
    }

    Configuration = builder.Build();
}

Les secrets de l’utilisateur peuvent être récupérés via l' Configuration API :User secrets can be retrieved via the Configuration API:

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

Mapper les secrets à un POCOMap secrets to a POCO

Le mappage d’un littéral d’objet entier à un POCO (une classe .NET simple avec des propriétés) est utile pour l’agrégation des propriétés associées.Mapping an entire object literal to a POCO (a simple .NET class with properties) is useful for aggregating related properties.

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Pour mapper les secrets précédents à un POCO, utilisez la Configuration fonctionnalité de liaison de graphique d’objets de l’API.To map the preceding secrets to a POCO, use the Configuration API's object graph binding feature. Le code suivant est lié à un MovieSettings poco personnalisé et accède à la ServiceApiKey valeur de la propriété :The following code binds to a custom MovieSettings POCO and accesses the ServiceApiKey property value:

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

Les Movies:ConnectionString Movies:ServiceApiKey secrets et sont mappés aux propriétés respectives dans MovieSettings :The Movies:ConnectionString and Movies:ServiceApiKey secrets are mapped to the respective properties in MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Remplacement de chaîne par des secretsString replacement with secrets

Le stockage des mots de passe en texte brut n’est pas sécurisé.Storing passwords in plain text is insecure. Par exemple, une chaîne de connexion de base de données stockée dans appsettings.jssur peut inclure un mot de passe pour l’utilisateur spécifié :For example, a database connection string stored in appsettings.json may include a password for the specified user:

{
  "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.A more secure approach is to store the password as a secret. Par exemple :For example:

dotnet user-secrets set "DbPassword" "pass123"

Supprimez la Password paire clé-valeur de la chaîne de connexion dans appsettings.jssur.Remove the Password key-value pair from the connection string in appsettings.json. Par exemple :For example:

{
  "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é d’un objet Password pour terminer la chaîne de connexion :The secret's value can be set on a SqlConnectionStringBuilder object's Password property to complete the connection string:

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

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Répertorier les secretsList the secrets

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets list

Vous obtenez la sortie suivante :The following output appears:

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

Dans l’exemple précédent, un signe deux-points dans les noms de clé désigne la hiérarchie d’objets dans secrets.jssur.In the preceding example, a colon in the key names denotes the object hierarchy within secrets.json.

Supprimer une seule clé secrèteRemove a single secret

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets remove "Movies:ConnectionString"

L'secrets.jsde l’application * sur* le fichier a été modifiée pour supprimer la paire clé-valeur associée à la MoviesConnectionString clé :The app's secrets.json file was modified to remove the key-value pair associated with the MoviesConnectionString key:

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

dotnet user-secrets listL’exécution affiche le message suivant :Running dotnet user-secrets list displays the following message:

Movies:ServiceApiKey = 12345

Supprimer tous les secretsRemove all secrets

Supposons que le fichier secrets. JSON de l’application contient les deux secrets suivants :Assume the app's secrets.json file contains the following two secrets:

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

Exécutez la commande suivante à partir du répertoire dans lequel se trouve le fichier . csproj :Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets clear

Tous les secrets d’utilisateur de l’application ont été supprimés de l' secrets.jssur le fichier :All user secrets for the app have been deleted from the secrets.json file:

{}

dotnet user-secrets listL’exécution affiche le message suivant :Running dotnet user-secrets list displays the following message:

No secrets configured for this application.

Ressources complémentairesAdditional resources