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

Por Rick Anderson e Kirk Larkin

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

este documento 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. Os segredos de produção não devem ser usados para desenvolvimento ou teste. Os segredos não devem ser implantados com o aplicativo. Em vez disso, os segredos de produção devem ser acessados por meio de um meio controlado, como variáveis de ambiente ou Azure Key Vault. Você pode armazenar e proteger os segredos de teste e produção do Azure com o provedor de configuração do Azure Key Vault.

Variáveis de ambiente

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

considere um aplicativo web ASP.NET Core no qual a segurança das contas de usuário individuais está habilitada. Uma cadeia de conexão de banco de dados padrão é incluída no arquivo do projeto appsettings.json 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 DefaultConnection valor da chave pode ser substituído por um valor de variável de ambiente. A variável de ambiente pode armazenar a cadeia de conexão completa com credenciais confidenciais.

Aviso

Variáveis de ambiente geralmente são armazenadas em texto simples 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. Outras medidas para evitar a divulgação de segredos do usuário podem ser necessárias.

O : separador não funciona com chaves hierárquicas de variável de ambiente em todas as plataformas. __, o sublinhado duplo, é:

  • Com suporte em todas as plataformas. Por exemplo, o : separador não é suportado pelo Bash,mas __ é.
  • Substituído automaticamente por um :

Gerenciador de segredo

a ferramenta gerenciador de segredo armazena dados confidenciais durante o desenvolvimento de um projeto ASP.NET Core. Nesse contexto, um elemento de 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 entre vários projetos. Os segredos do aplicativo não são verificados no controle do código-fonte.

Aviso

A ferramenta Gerenciador de segredo não criptografa os segredos armazenados e não deve ser tratada como um repositório confiável. É 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 segredo

A ferramenta Gerenciador de segredo oculta os detalhes da implementação, como onde e como os valores são armazenados. Você pode usar a ferramenta sem conhecer 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 UserSecretsId valor especificado no arquivo de projeto.

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

Habilitar o armazenamento secreto

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

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

dotnet user-secrets init

O comando anterior adiciona um UserSecretsId elemento 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>

em Visual Studio, clique com o botão direito do mouse no projeto em Gerenciador de Soluções e selecione gerenciar segredos do usuário no menu de contexto. Esse gesto adiciona um UserSecretsId elemento, populado 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 é associado ao valor do projeto UserSecretsId . Por exemplo, execute o seguinte comando do diretório no qual o arquivo de projeto existe:

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

No exemplo anterior, os dois pontos indica que Movies é um literal de objeto com uma ServiceApiKey propriedade.

A ferramenta Gerenciador de segredo também pode ser usada em outros diretórios. Use a --project opção 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 de estrutura JSON em Visual Studio

o gesto de gerenciar segredos de usuário do Visual Studio abre um arquivo segredos. json no editor de texto. Substitua o conteúdo de Secrets. JSON pelos pares de 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 via dotnet user-secrets remove ou dotnet user-secrets set . Por exemplo, dotnet user-secrets remove "Movies:ConnectionString" a execução recolhe o Movies literal do objeto. O arquivo modificado é semelhante ao JSON a seguir:

{
  "Movies:ServiceApiKey": "12345"
}

Definir vários segredos

Um lote de segredos pode ser definido por meio de tubulação JSON para o set comando. No exemplo a seguir, o conteúdo do arquivo Input. JSON é canalizado para o set comando.

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çãodo .net.

ASP.NET Core aplicativos web criados com dotnet novo ou Visual Studio gerar o seguinte código:

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

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

app.Run();

O WebApplication. Createbuildr Inicializa uma nova instância da WebApplicationBuilder classe com padrões pré-configurados. O Initialized WebApplicationBuilder ( builder ) fornece a configuração padrão e chama AddUserSecrets quando o EnvironmentName é Development :

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

Considere os seguintes exemplos de leitura da 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 de páginas:

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

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

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Para mapear os segredos anteriores para um POCO, use o recurso Associação de gráfico de objetos da API de configuração do .net. O código a seguir é associado a um MovieSettings poco personalizado e acessa o ServiceApiKey valor da propriedade:

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

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

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

    public string ServiceApiKey { get; set; }
}

Substituição de cadeia de caracteres com segredos

O armazenamento de senhas em texto sem formatação não é seguro. Por exemplo, uma cadeia de conexão de banco de dados armazenada em appsettings.json pode incluir uma senha para o usuário especificado:

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

Uma abordagem mais segura é armazenar a senha como um segredo. Por exemplo:

dotnet user-secrets set "DbPassword" "pass123"

Remova o Password par chave-valor da cadeia de conexão no appsettings.json . Por exemplo:

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

O valor do segredo pode ser definido na propriedade de um SqlConnectionStringBuilder objeto Password para concluir a 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();

Listar os segredos

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando do diretório no qual o arquivo de projeto existe:

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 de chave denota a hierarquia de objeto dentro de segredos. JSON.

Remover um único segredo

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando do diretório no qual o arquivo de projeto existe:

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list exibe a seguinte mensagem:

Movies:ServiceApiKey = 12345

Remover todos os segredos

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando do diretório no qual o arquivo de projeto existe:

dotnet user-secrets clear

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

{}

dotnet user-secrets listA execução exibe a seguinte mensagem:

No secrets configured for this application.

Gerenciar segredos do usuário com o Visual Studio

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

Visual Studio mostrando os segredos do usuário de gerenciamento

Recursos adicionais

Por Rick Anderson, Kirk Larkin, Daniel Rothe Scott Addie

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

este documento 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. Os segredos de produção não devem ser usados para desenvolvimento ou teste. Os segredos não devem ser implantados com o aplicativo. Em vez disso, os segredos de produção devem ser acessados por meio de um meio controlado, como variáveis de ambiente ou Azure Key Vault. Você pode armazenar e proteger os segredos de teste e produção do Azure com o provedor de configuração do Azure Key Vault.

Variáveis de ambiente

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

considere um aplicativo web ASP.NET Core no qual a segurança das contas de usuário individuais está habilitada. Uma cadeia de conexão de banco de dados padrão é incluída no arquivo do projeto appsettings.json 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 DefaultConnection valor da chave pode ser substituído por um valor de variável de ambiente. A variável de ambiente pode armazenar a cadeia de conexão completa com credenciais confidenciais.

Aviso

Variáveis de ambiente geralmente são armazenadas em texto simples 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. Outras medidas para evitar a divulgação de segredos do usuário podem ser necessárias.

O : separador não funciona com chaves hierárquicas de variável de ambiente em todas as plataformas. __, o sublinhado duplo, é:

  • Com suporte em todas as plataformas. Por exemplo, o : separador não é suportado pelo Bash,mas __ é.
  • Substituído automaticamente por um :

Gerenciador de segredo

a ferramenta gerenciador de segredo armazena dados confidenciais durante o desenvolvimento de um projeto ASP.NET Core. Nesse contexto, um elemento de 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 entre vários projetos. Os segredos do aplicativo não são verificados no controle do código-fonte.

Aviso

A ferramenta Gerenciador de segredo não criptografa os segredos armazenados e não deve ser tratada como um repositório confiável. É 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 segredo

A ferramenta Gerenciador de segredo oculta os detalhes da implementação, como onde e como os valores são armazenados. Você pode usar a ferramenta sem conhecer 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 UserSecretsId valor especificado no arquivo de projeto.

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

Habilitar o armazenamento secreto

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

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

dotnet user-secrets init

O comando anterior adiciona um UserSecretsId elemento 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>

em Visual Studio, clique com o botão direito do mouse no projeto em Gerenciador de Soluções e selecione gerenciar segredos do usuário no menu de contexto. Esse gesto adiciona um UserSecretsId elemento, populado 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 é associado ao valor do projeto UserSecretsId . Por exemplo, execute o seguinte comando do diretório no qual o arquivo de projeto existe:

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

No exemplo anterior, os dois pontos indica que Movies é um literal de objeto com uma ServiceApiKey propriedade.

A ferramenta Gerenciador de segredo também pode ser usada em outros diretórios. Use a --project opção 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 de estrutura JSON em Visual Studio

o gesto de gerenciar segredos de usuário do Visual Studio abre um arquivo segredos. json no editor de texto. Substitua o conteúdo de Secrets. JSON pelos pares de 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 via dotnet user-secrets remove ou dotnet user-secrets set . Por exemplo, dotnet user-secrets remove "Movies:ConnectionString" a execução recolhe o Movies literal do objeto. O arquivo modificado é semelhante ao JSON a seguir:

{
  "Movies:ServiceApiKey": "12345"
}

Definir vários segredos

Um lote de segredos pode ser definido por meio de tubulação JSON para o set comando. No exemplo a seguir, o conteúdo do arquivo Input. JSON é canalizado para o set comando.

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çãodo .net.

A fonte de configuração 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 ambiente de desenvolvimento, 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 Movies:ServiceApiKey chave:

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

Razor Modelo de página páginas:

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 de acesso na configuração de inicialização e acesso em Razor Páginas.

Mapear segredos para um POCO

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

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

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 vincula a um MovieSettings POCO personalizado e acessa o ServiceApiKey valor da propriedade:

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

Os Movies:ConnectionString segredos e são Movies:ServiceApiKey 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

O armazenamento de senhas em texto sem-texto não é seguro. Por exemplo, uma cadeia de conexão de banco de dados armazenada no appsettings.json pode incluir uma senha para o usuário especificado:

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

Uma abordagem mais segura é armazenar a senha como um segredo. Por exemplo:

dotnet user-secrets set "DbPassword" "pass123"

Remova o Password par chave-valor da cadeia de conexão em appsettings.json . Por exemplo:

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

O valor do segredo pode ser definido na propriedade de um objeto para concluir a SqlConnectionStringBuilder Password cadeia de conexão:

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

Listar os segredos

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando no diretório no qual o arquivo de projeto existe:

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 de chave denota a hierarquia de objetos em secrets.json.

Remover um único segredo

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando no diretório no qual o arquivo de projeto existe:

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list exibe a seguinte mensagem:

Movies:ServiceApiKey = 12345

Remover todos os segredos

Suponha que o arquivo secrets.jsaplicativo contém os dois segredos a seguir:

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

Execute o seguinte comando no diretório no qual o arquivo de projeto existe:

dotnet user-secrets clear

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

{}

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

No secrets configured for this application.

Gerenciar segredos do usuário com Visual Studio

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

Visual Studio mostrando Gerenciar Segredos do Usuário

Recursos adicionais