.NET Core程序中使用User Secrets存储敏感数据

前言

在开发中经常会用到一些敏感数据比如AppSecret或数据库连接字符串无论是硬编码还是写在配置文件中最终都要push到svn或git上。对于开源项目这些敏感数据就无隐私可言了对于私有项目一旦源代码管理服务器被黑这些敏感数据也将暴露无遗。所以最佳实践就是不要将敏感数据写到源代码中。

以往我们常常将数据库连接字符串写在web.config中.NET Core中写在appsettings.json中开发环境下如果一个开发者修改了连接字符串为了不影响其他开发者每次提交代码的时候就应该忽略该配置文件如果还添加了其他配置必须提交的话要么先撤销连接字符串的修改再提交要么直接提交会影响其他开发人员。很多时候我们就是直接提交了大不了其他开发者pull下来代码再修改一下。但是最佳实践就是不要写在配置文件中。

注意上面提到的问题都是在开发环境下。

Secret Manager

.NET Core中为我们提供了叫Secret Manager的工具可以实现上文中的最佳实践再次强调一次Secret Manager只适用于开发环境中。

下面说一下Secret Manager它帮我们抽象了一些细节比如数据存储在哪以及如何存储的问题。简单来说它帮助我们将数据以明文的形式存在了本地的一个json文件中。系统不同存储的位置也不一样。

Windows

%APPDATA%\microsoft\UserSecrets\<userSecretsId>\secrets.json

Linux

~/.microsoft/usersecrets/<userSecretsId>/secrets.json

Mac

~/.microsoft/usersecrets/<userSecretsId>/secrets.json

userSecretsId是在.csproj文件中指定的会在下文讲到。

安装、使用

配置User Secrets及访问需要用到两个包分别为

Microsoft.Extensions.SecretManager.Tools
Microsoft.Extensions.Configuration.UserSecrets

简单说一下两者的作用第一个是工具包可以使用dotnet user-secrets命令将数据存储到json文件中第二个包可以通过.NET Core的配置系统访问存储在json文件中的数据。

dotnet user-secrets -h

这个命令可以查看Secret Manager的用法。

它有4个命令

命令 描述 语法
clear 删除程序中所有的secrets dotnet user-secrets clear
list 列举程序中所有的secrets dotnet user-secrets list
remove 删除指定的secret dotnet user-secrets remove NameOfSecret
set 设置secret dotnet user-secrets set NameOfSecret ValueOfSecret

以Mac上举例上面的命令都是操作~/.microsoft/usersecrets/\/secrets.json这个文件userSecretsId指定了是哪个项目的secrets。

userSecretsId在.csproj文件中指定。

<PropertyGroup>
  <UserSecretsId>userSecretsId的值</UserSecretsId>
</PropertyGroup>

在mac或linux上userSecretsId的值可以通过uuidgen生成。

在Microsoft.Extensions.Configuration.UserSecrets包扩展了ConfigurationBuilder包含一个AddUserSecrets的扩展方法。如果想通过Configuration访问User Secrets只需要在调用build.AddUserSecrets()即可。

if (env.IsDevelopment())
{
    // 搜索包含类型Startup的程序集添加User Secrets的配置源Startup也可以换成其他程序集中的其他类型
    builder.AddUserSecrets<Startup>();
}

或干脆直接指定userSecretsId

if(env.IsDevelopment())
{
    builder.AddUserSecrets("UserSecretsId");
}

然后就可以通过Configuration["NameOfSecret"]访问到User Secret了。

项目实践

下面通过一个控制台程序演示。

  1. mkdir user-secrets && cd user-secrets # 新建一个目录
  2. dotnet new console # 创建一个控制台应用
  3. dotnet restore # 还原包
  4. dotnet add package Microsoft.Extensions.Configuration.UserSecrets -v 1.1.2 # 安装包
  5. code . # 使用Visual Studio Code打开
  6. 在user-secrets.csproj中添加UserSecretsId
    <PropertyGroup>
    <UserSecretsId>3BF2D901-89B9-437D-8856-CCA63D4606F7</UserSecretsId>
    </PropertyGroup>

    以及SecretManager工具包

    <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.1" />
    </ItemGroup>
  7. dotnet user-secrets set AppKey 12345 # 添加名为AppKey的Secret
  8. 为了判断是在开发环境中需要添加环境变量因此需要再安装一个包
    dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables -v 1.1.2
  9. 打开Program.cs加入以下代码
    class Program
    {
        public static IConfigurationRoot Configuration { get; set; }
        static void Main(string[] args)
        {
             var builder = new ConfigurationBuilder()
            .AddEnvironmentVariables();
    
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            if (environment == "Development")
            {
                builder.AddUserSecrets<Program>();
            }
            Configuration = builder.Build();
    
            Console.WriteLine(Configuration["AppKey"]);
        }
    }
  10. 运行
    ASPNETCORE_ENVIRONMENT=Development dotnet run

    export ASPNETCORE_ENVIRONMENT=Development
    dotnet run

ASP.NET Core类似这里就不再演示了。

时间: 2024-09-29 22:57:22

.NET Core程序中使用User Secrets存储敏感数据的相关文章

在.net core程序中使用EntityFrameok(非EF Core)

最近用NoSQL较多写,用传统的EF到不多,但在一些.net core小程序中也小试牛刀过,不过当时用的是微软为.net core量身定制的Entity Framework Core,只是一些比较常规的增删改查,没有怎么深入使用,感觉差别不大.虽然知道EF Core是重新设计的,但觉得EF Core和EF在轻度使用上差别不大. 这两天打算计划重构一个老项目,想将其迁移到.net core上去.简单的试了一下,大部分的功能移植比较顺利,但却发现EF迁移到EF Core不是那么容易的事情,模型的关系

在.NET Core程序中设置全局异常处理

以前我们想设置全局异常处理只需要这样的代码: 1 AppDomain currentDomain = AppDomain.CurrentDomain; 2 currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyExceptionHandler); 但是在.NET Core中并没有AppDomain的相关实现,至少在.NET Core最新的发布版本里没有. 以前我和网友@SillyPGM的讨论,然后我们查看

.net core程序强制以管理员权限启动

当我们编写windows程序的时候,很多时候需要程序默认以管理员权限运行,以前在.net 程序中直接新建一个app.manifest,设置 ????<requestedExecutionLevel?level="requireAdministrator"?uiAccess="false"?/> 即可 今天用.net core程序写了一个注册表的程序时发现,在.net core程序中按照上面设置却是不生效的,网上一些说法是.net core是跨平台的,不支

ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

一.创建项目 本篇文章介绍如何将一个ASP.NET Core Web程序部署到Windows系统上.这里以ASP.NET Core WebApi为例进行讲解.首先创建一个ASP.NET Core WebApi项目,使用默认的Values控制器,这里使用Visual Studio 2019创建一个ASP.NET Core 3.1d的WebApi项目. 创建新项目的时候选项ASP.NET Core Web应用程序,如下图所示: 配置新项目界面界面设置项目名称和位置,如下图所示: 选择.Net Cor

在.NET Core控制台应用程序中使用强类型配置

想象一下,你写一个控制台应用程序,你想要从配置文件中以强类型方式读取配置. .NET Core 可以帮助我们解决. 通常我会在ASP.NET Core MVC中演示,但简单起见,只在控制台应用程序中演示. 让我们创建两个配置类,用于保存应用程序和模块名称. public class MySettings { public string ApplicationName { get; set; } } public class MyModuleSettings { public string Mod

Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)

本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket.关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料,例如参考 SignalR 的官方教程:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-2.1 我们先看一下完成本教程内容后,在小程序内实现的 WebSocket 效果: 私有及群发消息

.net core控制台程序中使用原生依赖注入

原文:.net core控制台程序中使用原生依赖注入 如果要在程序中使用DbContext,则需要先在Nuget中安装Microsoft.EntityFrameworkCore.SqlServer using ConsoleApp1.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; using Console

ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

.NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对Redis和SQL Server的原生支持.除了这个独立的缓存系统之外,ASP.NET Core还借助一个中间件实现了“响应缓存”,它会按照HTTP缓存规范对整个响应实施缓存.不过按照惯例,在对缓存进行系统介绍之前,我们还是先通过一些简单的实例演示感知一下如果在一个ASP.NET Core应用中如何

多线程程序中操作的原子性

[转]http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/ 多线程程序中操作的原子性 0. 背景 原子操作就 是不可再分的操作.在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头.本文主要讨论了三 个问题:1. 多线程程序中对变量的读写操作是否是原子的?2. 多线程程序中对Bit field(位域)的读写操作是否是线程安全