Armazenamento seguro de segredos do aplicativo em desenvolvimento no ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão do .NET 10 deste artigo.

Por Rick Anderson e Kirk Larkin

Este artigo explica como gerenciar dados confidenciais para um aplicativo ASP.NET Core em um computador de desenvolvimento. Nunca armazene senhas ou outros dados confidenciais no código-fonte ou nos arquivos de configuração. Os segredos de produção não devem ser usados para desenvolvimento ou teste. Os segredos não devem ser implantados com o aplicativo. Os segredos de produção devem ser acessados por meios controlados, como o Azure Key Vault. Os segredos de teste e produção do Azure podem ser armazenados e protegidos com o provedor de configuração do Azure Key Vault.

Exibir ou baixar o código de exemplo (como baixar)

Para obter mais informações sobre autenticação para aplicativos de teste e produção implantados, consulte Fluxos de autenticação seguros.

Para usar segredos do usuário em um aplicativo de console .NET, consulte GitHub dotnet/entityframework.docs problema #3939.

Trabalhar com variáveis de ambiente

As variáveis de ambiente são usadas para evitar o armazenamento de segredos de aplicativo no código ou em arquivos de configuração locais. As variáveis de ambiente substituem os valores de configuração de todas as fontes de configuração especificadas anteriormente.

Considere um aplicativo Web ASP.NET Core no qual a segurança de Contas Individuais está habilitada. Uma cadeia de conexão de banco de dados padrão está incluída no arquivo appsettings.json do projeto com a chave DefaultConnection. A cadeia de conexão padrão é para LocalDB, que é executado no modo de usuário e não requer uma senha. Durante a implantação do aplicativo, você pode substituir o valor da DefaultConnection chave com o valor de uma variável de ambiente. A variável de ambiente pode armazenar a cadeia de conexão completa com credenciais confidenciais.

Warning

As variáveis de ambiente geralmente são armazenadas como texto sem criptografia. Se o computador ou o processo estiver comprometido, as variáveis de ambiente estarão acessíveis a partes não confiáveis. Medidas extras para impedir a divulgação de segredos do usuário podem ser necessárias.

O separador dois-pontos : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, Bash não oferece suporte ao caractere de dois-pontos (:) como separador. Todas as plataformas dão suporte à sintaxe de sublinhado duplo (__) e a substituem automaticamente por dois-pontos (:).

Usar a ferramenta Gerenciador de Segredos

O Gerenciador de Segredos é uma ferramenta que armazena dados confidenciais durante o desenvolvimento de aplicativos. Nesse contexto, um pedaço de dados confidenciais é um segredo do aplicativo.

  • Os segredos do aplicativo são armazenados em um local separado da árvore do projeto.
  • Eles são associados a um projeto específico ou compartilhados em vários projetos.
  • Eles não são verificados no controle do código-fonte.

Warning

O Gerenciador de Segredos não criptografa os segredos armazenados e não deve ser tratado como um repositório confiável. Serve apenas para fins de desenvolvimento. As chaves e os valores são armazenados em um arquivo de configuração JSON no diretório de perfil do usuário.

O Gerenciador de Segredos oculta os detalhes da implementação, como onde e como os valores são armazenados. Você pode usar a ferramenta sem saber esses detalhes de implementação. Os valores são armazenados em um arquivo JSON na pasta de perfil de usuário do computador local:

Caminho do sistema de arquivos:

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

No caminho do sistema de arquivos, substitua a parte <user_secrets_id> pelo valor UserSecretsId especificado no arquivo do projeto.

Não escreva código que dependa do local ou formato dos dados salvos com o Gerenciador de Segredos. Esses detalhes de implementação podem ser alterados. Por exemplo, os valores secretos não são criptografados.

Habilitar o armazenamento de segredos

O Gerenciador de Segredos opera em configurações específicas do projeto armazenadas em seu perfil de usuário.

Como usar a CLI

O Gerenciador de Segredos inclui um init comando. Para usar os segredos de usuário, execute o seguinte comando no diretório do projeto:

dotnet user-secrets init

Esse comando adiciona um UserSecretsId elemento dentro de um PropertyGroup arquivo de projeto. Por padrão, o texto interno de UserSecretsId é um GUID. O texto interno é arbitrário, mas é exclusivo para o projeto. O exemplo a seguir mostra um valor GUID de 0000a1a1-b2b2-c3c3-d4d4-eeeeee555555.

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

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

</Project>

Usar o Visual Studio

No Visual Studio, clique com o botão direito do mouse no projeto no Gerenciador de Soluções e selecione Gerenciar Segredos de Usuário no menu de contexto. Esse gesto adiciona um elemento UserSecretsId, preenchido com um GUID, ao arquivo de projeto.

Se 'GenerateAssemblyInfo' estiver definido como 'false'

Se a geração de atributos de informações do assembly (GenerateAssemblyInfo) estiver desabilitada (definida como false), adicione manualmente o UserSecretsIdAttribute ao arquivo AssemblyInfo.cs. Por exemplo:

[assembly: UserSecretsId("your_user_secrets_id")]

Quando você adiciona manualmente o UserSecretsId atributo ao arquivo AssemblyInfo.cs , o UserSecretsId valor deve corresponder ao valor no arquivo de projeto.

Definir um segredo

Defina um segredo de aplicativo que consiste em uma chave e seu valor. O segredo está associado ao valor do projeto UserSecretsId. Por exemplo, execute o seguinte comando no diretório em que o arquivo de projeto está:

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

Neste exemplo, os dois-pontos indicam que Movies é um literal de objeto com a propriedade ServiceApiKey.

Você também pode usar o Gerenciador de Segredos de outros diretórios. Inclua a opção --project para fornecer o caminho do sistema de arquivos no qual o arquivo de projeto existe. Por exemplo:

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

Nivelamento da estrutura JSON no Visual Studio

O gesto Visual Studio Manage User Secrets abre um arquivo secrets.json no editor de texto. Substitua o conteúdo do arquivo secrets.json pelos pares chave-valor a serem armazenados. Por exemplo:

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

A estrutura JSON é achatada após modificações por meio do comando dotnet user-secrets remove ou dotnet user-secrets set. Por exemplo, executar dotnet user-secrets remove "Movies:ConnectionString" recolhe o objeto literal Movies. O arquivo modificado é semelhante ao seguinte JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Definir vários segredos

Um lote de segredos pode ser definido canalizando JSON para o comando set. No exemplo a seguir, o conteúdo do arquivo input.json é canalizado para o set comando.

Execute o comando a seguir:

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

Acessar um segredo

Para acessar um segredo, conclua as seguintes etapas:

  1. Registre a fonte de configuração de segredos do usuário.

  2. Leia o segredo por meio da API de Configuração.

Registrar a fonte de configuração de segredos do usuário

O provedor de configuração de segredos do usuário registra a fonte de configuração apropriada com a API de Configuração do .NET.

Os aplicativos Web do ASP.NET Core criados com o comando dotnet new ou o Visual Studio geram o seguinte código:

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

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

app.Run();

O método WebApplication.CreateBuilder inicializa uma nova instância da WebApplicationBuilder classe com padrões pré-configurados. O WebApplicationBuilder inicializado (builder) fornece configuração padrão e chama o método AddUserSecrets quando a propriedade EnvironmentName é Development.

Ler o segredo por meio da API de Configuração

Os exemplos a seguir demonstram como ler a Movies:ServiceApiKey chave:

arquivo Program.cs

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

var app = builder.Build();

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

app.Run();

Razor Modelo de página do 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
    }
}

Para obter mais informações, consulte Configuração no ASP.NET Core.

Mapear segredos para um POCO

Mapear um objeto literal inteiro para um POCO (uma classe .NET simples com propriedades) é útil para agregar propriedades relacionadas.

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Para mapear os segredos anteriores para um POCO, use o recurso de associação de grafo de objeto da API de Configuração do .NET. O código a seguir se associa a um POCO personalizado MovieSettings e acessa o valor da propriedade ServiceApiKey:

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

Os segredos Movies:ConnectionString e Movies:ServiceApiKey são mapeados para as respectivas propriedades em MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Use a substituição de strings com segredos

Armazenar senhas em texto sem formatação não é seguro. Nunca armazene segredos em um arquivo de configuração, como appsettings.json, que pode ser verificado em um repositório de código-fonte.

Por exemplo, uma cadeia de conexão de banco de dados armazenada em um arquivo appsettings.json não deve incluir uma senha. Em vez disso, armazene a senha como um segredo e inclua a senha na cadeia de conexão em runtime. Por exemplo:

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

Substitua o marcador <secret value> no exemplo pela senha. Defina o valor do segredo na propriedade de SqlConnectionStringBuilder um Password objeto para incluí-lo como o valor da senha na cadeia de conexão:

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

Lista os segredos

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets list

O seguinte resultado é exibido:

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

No exemplo, os dois-pontos (:) nos nomes das chaves denotam a hierarquia de objetos dentro do arquivo secrets.json.

Remover um único segredo

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets remove "Movies:ConnectionString"

O arquivo secrets.json do aplicativo é modificado para remover o par chave-valor associado à Movies:ConnectionString chave:

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

O dotnet user-secrets list comando exibe a seguinte mensagem:

Movies:ServiceApiKey = 12345

Remover todos os segredos

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets clear

Todos os segredos do usuário para o aplicativo são excluídos do arquivo secrets.json :

{}

A execução do dotnet user-secrets list comando exibe a seguinte mensagem:

No secrets configured for this application.

Gerenciar segredos do usuário com o Visual Studio

Para gerenciar segredos do usuário no Visual Studio, clique com o botão direito do mouse no projeto no Gerenciador de Soluções e selecione Manage User Secrets:

Screenshot mostra como selecionar a opção Gerenciar Segredos do Usuário em Visual Studio.

Migrar segredos do usuário do ASP.NET Framework para o ASP.NET Core

Você pode migrar seus segredos de usuário armazenados do ASP.NET Framework para ASP.NET Core. Para obter mais informações, consulte GitHub dotnet/aspnetcore.docs problema nº 27611 - A documentação do User Secrets não menciona a incompatibilidade com AssemblyInfo.cs.

Trabalhar com segredos do usuário em aplicativos não Web

Os projetos que têm como destino Microsoft.NET.Sdk.Web incluem automaticamente o suporte a segredos de usuário. Para projetos que têm como destino Microsoft.NET.Sdk, como aplicativos de console, instale explicitamente a extensão de configuração e os pacotes NuGet de segredos de usuário.

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

Depois de instalar os pacotes, inicialize o projeto e defina segredos da mesma maneira que para um aplicativo Web. O exemplo a seguir mostra um aplicativo de console que recupera o valor de um conjunto de segredos com a AppSecret chave:

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

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

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

Por Rick Anderson, Kirk Larkin, Daniel Roth e Scott Addie

Exibir ou baixar código de exemplo (como baixar)

Este artigo explica como gerenciar dados confidenciais para um aplicativo ASP.NET Core em um computador de desenvolvimento. Nunca armazene senhas ou outros dados confidenciais no código-fonte ou nos arquivos de configuração. Os segredos de produção não devem ser usados para desenvolvimento ou teste. Os segredos não devem ser implantados com o aplicativo. Os segredos de produção devem ser acessados por meios controlados, como o Azure Key Vault. Os segredos de teste e produção do Azure podem ser armazenados e protegidos com o provedor de configuração do Azure Key Vault.

Para obter mais informações sobre autenticação para ambientes de teste e produção, consulte Fluxos de autenticação seguros.

Variáveis de ambiente

As variáveis de ambiente são usadas para evitar o armazenamento de segredos de aplicativo no código ou em arquivos de configuração locais. As variáveis de ambiente substituem os valores de configuração de todas as fontes de configuração especificadas anteriormente.

Considere um aplicativo Web ASP.NET Core no qual a segurança de Contas de Usuário Individuais está habilitada. Uma cadeia de conexão de banco de dados padrão é incluída no arquivo appsettings.json do projeto com a chave DefaultConnection. A cadeia de conexão padrão é para LocalDB, que é executado no modo de usuário e não requer uma senha. Durante a implantação do aplicativo, o valor da chave DefaultConnection pode ser substituído pelo valor de uma variável de ambiente. A variável de ambiente pode armazenar a cadeia de conexão completa com credenciais confidenciais.

Warning

Geralmente, as variáveis de ambiente são armazenadas em texto sem formatação e não criptografado. Se o computador ou o processo estiver comprometido, as variáveis de ambiente poderão ser acessadas por partes não confiáveis. Medidas adicionais para evitar a divulgação de segredos do usuário podem ser necessárias.

O separador dois-pontos : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, Bash não oferece suporte ao caractere de dois-pontos (:) como separador. Todas as plataformas dão suporte à sintaxe de sublinhado duplo (__) e a substituem automaticamente por dois-pontos (:).

Gerenciador de Segredos

A ferramenta Gerenciador Secreto armazena dados confidenciais durante o desenvolvimento do aplicativo. Nesse contexto, uma parte dos dados confidenciais é um segredo do aplicativo. Os segredos do aplicativo são armazenados em um local separado da árvore do projeto. Os segredos do aplicativo são associados a um projeto específico ou compartilhados em vários projetos. Os segredos do aplicativo não são verificados no controle do código-fonte.

Warning

A ferramenta Gerenciador de Segredos não criptografa os segredos armazenados e não deve ser tratada como um repositório confiável. Serve apenas para fins de desenvolvimento. As chaves e os valores são armazenados em um arquivo de configuração JSON no diretório de perfil do usuário.

Como funciona a ferramenta Gerenciador de Segredos

A ferramenta Gerenciador de Segredos oculta os detalhes da implementação, como onde e como os valores são armazenados. Você pode usar a ferramenta sem saber esses detalhes de implementação. Os valores são armazenados em um arquivo JSON na pasta de perfil de usuário do computador local:

Caminho do sistema de arquivos:

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

Nos caminhos de arquivo anteriores, substitua <user_secrets_id> pelo valor UserSecretsId especificado no arquivo de projeto.

Não escreva códigos que dependam do local ou do formato dos dados salvos com a ferramenta Gerenciador de Segredos. Esses detalhes de implementação podem ser alterados. Por exemplo, os valores secretos não são criptografados, mas poderão ser no futuro.

Habilitar o armazenamento de segredos

A ferramenta Gerenciador de Segredos opera com definições de configuração específicas do projeto armazenadas em seu perfil de usuário.

A ferramenta Gerenciador de Segredos inclui um comando init no SDK do .NET Core 3.0.100 ou posterior. Para usar os segredos de usuário, execute o seguinte comando no diretório do projeto:

dotnet user-secrets init

O comando anterior adiciona um elemento UserSecretsId dentro de um PropertyGroup do arquivo de projeto. Por padrão, o texto interno de UserSecretsId é um GUID. O texto interno é arbitrário, mas é exclusivo para o projeto.

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

No Visual Studio, clique com o botão direito do mouse no projeto no Gerenciador de Soluções e selecione Gerenciar Segredos de Usuário no menu de contexto. Esse gesto adiciona um elemento UserSecretsId, preenchido com um GUID, ao arquivo de projeto.

Definir um segredo

Defina um segredo de aplicativo que consiste em uma chave e seu valor. O segredo está associado ao valor do projeto UserSecretsId. Por exemplo, execute o seguinte comando no diretório em que o arquivo de projeto está:

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

No exemplo anterior, o sinal de dois-pontos indica que Movies é um objeto literal com a propriedade ServiceApiKey.

A ferramenta Gerenciador de Segredos também pode ser usada a partir de outros diretórios. Use a opção --project para fornecer o caminho do sistema de arquivos no qual o arquivo de projeto existe. Por exemplo:

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

Nivelamento da estrutura JSON no Visual Studio

O gesto Gerenciar Segredos do Usuário do Visual Studio abre um arquivo secrets.json no editor de texto. Substitua o conteúdo de secrets.json pelos pares chave-valor a serem armazenados. Por exemplo:

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

A estrutura JSON é nivelada após modificações por meio de dotnet user-secrets remove ou dotnet user-secrets set. Por exemplo, executar dotnet user-secrets remove "Movies:ConnectionString" recolhe o objeto literal Movies. O arquivo modificado é semelhante ao seguinte JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Definir vários segredos

Um lote de segredos pode ser definido canalizando JSON para o comando set. No exemplo a seguir, o conteúdo do arquivo input.json é canalizado para o comando set.

Abra um shell de comando e execute o seguinte comando:

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

Acessar um segredo

Para acessar um segredo, conclua as seguintes etapas:

  1. Registrar a fonte de configuração de segredos do usuário
  2. Ler o segredo por meio da API de Configuração

Registrar a fonte de configuração de segredos do usuário

O provedor de configuração de segredos do usuário registra a fonte de configuração apropriada com a API de Configuração do .NET.

A fonte de configuração de segredos do usuário é adicionada automaticamente no modo de Desenvolvimento quando o projeto chama CreateDefaultBuilder. CreateDefaultBuilder chama AddUserSecrets quando o EnvironmentName é Development:

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

Quando CreateDefaultBuilder não for chamado, adicione a fonte de configuração de segredos do usuário explicitamente chamando AddUserSecrets em ConfigureAppConfiguration. Chame AddUserSecrets somente quando o aplicativo for executado no Development ambiente, conforme mostrado no exemplo a seguir:

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

Ler o segredo por meio da API de Configuração

Se a fonte de configuração de segredos do usuário estiver registrada, a API de Configuração do .NET poderá ler os segredos. A injeção de construtor pode ser usada para obter acesso à API de Configuração do .NET. Considere os seguintes exemplos de leitura da chave Movies:ServiceApiKey:

Classe de inicialização:

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

Modelo de página do Pages:Razor

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

Para obter mais informações, confira Configuração de acesso na Inicialização e Configuração de acesso nas Razor Páginas.

Mapear segredos para um POCO

Mapear um objeto literal inteiro para um POCO (uma classe .NET simples com propriedades) é útil para agregar propriedades relacionadas.

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Para mapear os segredos anteriores para um POCO, use o recurso de associação de grafo de objeto da API de Configuração do .NET. O código a seguir se associa a um POCO personalizado MovieSettings e acessa o valor da propriedade ServiceApiKey:

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

Os segredos Movies:ConnectionString e Movies:ServiceApiKey são mapeados para as respectivas propriedades em MovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Substituição de cadeia de caracteres por segredos

Armazenar senhas em texto sem formatação não é seguro. Nunca armazene segredos em um arquivo de configuração, como appsettings.jsono , que pode ser verificado em um repositório de código-fonte.

Por exemplo, uma cadeia de conexão de banco de dados armazenada em appsettings.json não deve incluir uma senha. Em vez disso, armazene a senha como um segredo e inclua a senha na cadeia de conexão em runtime. Por exemplo:

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

Substitua o placeholder <secret value> no exemplo anterior pelo valor da senha. Defina o valor do segredo na propriedade de SqlConnectionStringBuilder um Password objeto para incluí-lo como o valor da senha na cadeia de conexão:

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

Lista os segredos

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets list

O seguinte resultado é exibido:

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

No exemplo anterior, dois-pontos nos nomes das chaves denotam a hierarquia de objetos dentro de secrets.json.

Remover um único segredo

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets remove "Movies:ConnectionString"

O arquivo do aplicativo secrets.json foi modificado para remover o par chave-valor associado à chave MoviesConnectionString:

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

dotnet user-secrets list exibe a seguinte mensagem:

Movies:ServiceApiKey = 12345

Remover todos os segredos

Suponha que o arquivo desecrets.json do aplicativo contenha os dois segredos a seguir:

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

Execute o seguinte comando no diretório em que o arquivo de projeto está:

dotnet user-secrets clear

Todos os segredos do usuário para o aplicativo foram excluídos do arquivo secrets.json:

{}

Executar dotnet user-secrets list exibe a seguinte mensagem de aviso:

No secrets configured for this application.

Gerenciar segredos do usuário com o Visual Studio

Para gerenciar segredos de usuário no Visual Studio, clique com o botão direito do mouse no projeto no gerenciador de soluções e selecione Gerenciar Segredos de Usuário:

 Visual Studio mostrando Gerenciar Segredos de Usuário

Migrando segredos do usuário do ASP.NET Framework para o ASP.NET Core

Consulte este problema do GitHub.

Segredos do usuário em aplicativos não Web

Os projetos que têm como destino Microsoft.NET.Sdk.Web incluem automaticamente o suporte a segredos de usuário. Para projetos que têm como destino Microsoft.NET.Sdk, como aplicativos de console, instale explicitamente a extensão de configuração e os pacotes NuGet de segredos de usuário.

Usando o PowerShell:

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

Usando a CLI do .NET:

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

Depois que os pacotes forem instalados, inicialize o projeto e defina segredos da mesma maneira que para um aplicativo Web. O exemplo a seguir mostra um aplicativo de console que recupera o valor de um segredo que foi definido com a chave "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"]);
    }
}

Recursos adicionais