前言

在应用程序开发的过程中,有的时候需要在代码中保存一些机密的信息,比如微信appkey, 连接字符串,加密密钥,字符串,或者是用户名密码等。通常的做法是保存到一个配置文件中,例如 appsettings.json, 以之前文章"Blazor组件自做五: 使用JS隔离封装Google地图" 为例 ,其中有一段代码

@inject IConfiguration config

[Parameter]
public string? Key { get; set; } key = Key ?? config["GoogleKey"];

意思是在 IConfiguration 服务获取 "GoogleKey" , 默认在 appsettings.json 文件配置. 问题就来了,如果我们在工程的 appsettings.json 文件明文保存 GoogleKey , 多人开发或者开源同步到Github/码云上,那肯定是极其不安全的.

严重建议勿在源代码中存储密码或其他敏感数据。 也不要将生产机密用于开发或测试。 机密不随应用一起部署。

用户机密介绍

使用用户机密的场景:

需要保存一些和第三方网站对接的密钥,比如和 微信,微博站点使用的 appkey
给每个开发人员配置不用的用户名密码来访问一些资源
开发人员在开发过程中使用各自本机的数据库,如何配置数据库地址、账号和密码
假设说最后一项,每个开发要使用自己本机的数据库,你可能会说让每个人修改自己的appsettings.config,在提交代码的时候不提交就行了。那么如果在appsettings.config添加其他配置项的时候,显然不提交appsettings.config文件不合理的。

现在,ASP.NET Core 提供了一种很优雅简洁的方式 User Secrets 用来帮助我们解决这个事情。

机密管理器

机密管理器工具存储 ASP.NET Core 项目开发期间的敏感数据。 在此上下文中,一段敏感数据是应用机密。 应用机密存储在与项目树不同的位置。 应用机密与特定项目关联,或者跨多个项目共享。 应用机密不会签入到源代码管理中。

机密管理器工具的工作原理

机密管理器工具会隐藏实现详细信息,例如值的存储位置和存储方法。 可在不知道这些实现详细信息的情况下使用该工具。 这些值存储在本地计算机的用户配置文件文件夹中的 JSON 文件中:

Windows文件系统路径:

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

Linux/macOS 文件系统路径:

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

在上述文件路径中,将 <user_secrets_id> 替换为在项目文件中指定的 UserSecretsId 值。

不要编写依赖于使用机密管理器工具保存的数据的位置或格式的代码。 这些实现详细信息可能有变。 例如,机密值不会加密,但将来可能会加密。

启用机密存储

在 Visual Studio 2022 中,在解决方案资源管理器中右键单击该项目,然后从上下文菜单中选择“管理用户机密”。

该操作会将 UserSecretsId 元素添加到项目文件的 PropertyGroup 中。 默认情况下,UserSecretsId 的内部文本是 GUID。 内部文本是任意的,但对于项目来说是唯一的。

<PropertyGroup>
<UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

在应用程序中使用用户机密

要在应用程序中访问配置的用户机密,你需要保证project.json文件中存在依赖项:

Microsoft.Extensions.Configuration.UserSecrets 并且builder.AddUserSecrets()。

然后在Startup.cs文件中通过 Configuration 对象访问

var builder = WebApplication.CreateBuilder(args);
var movieApiKey = builder.Configuration["ApiKey"];

实际操作

1. 新建工程n01UserSecrets. 将项目添加到解决方案中

dotnet new blazorserver -o n01UserSecrets
dotnet sln add n01UserSecrets/n01UserSecrets.csproj

2. 在解决方案资源管理器中右键单击n01UserSecrets项目,然后从上下文菜单中选择“管理用户机密”。

打开的文件内容替换为

{
"ApiKey": "12345"
}

3. Program.cs 文件使用

var movieApiKey = builder.Configuration["ApiKey"];
Console.WriteLine(movieApiKey);

4. Razor 页面使用

Key is @apiKey

@code{
[Inject] IConfiguration? config { get; set; } string? apiKey { get => config!["ApiKey"]; }
}

5. 不同项目共享机密存储文件

以控制台为例

dotnet new console -o n01UserSecretsConsole
dotnet sln add n01UserSecretsConsole/n01UserSecretsConsole.csproj

5.1. 在解决方案资源管理器中右键单击n01UserSecretsConsole项目,然后从上下文菜单中选择“管理用户机密”。

5.2. 双击项目n01UserSecrets,打开项目配置,找到UserSecretsId一行,整行复制

<UserSecretsId>979b4b67-add4-46bb-80c6-49dab268ca91</UserSecretsId>

5.3. 在解决方案资源管理器中右键单击n01UserSecretsConsole项目,然后从上下文菜单中选择“管理用户机密”。

5.4. 双击项目n01UserSecretsConsole,找到UserSecretsId一行,替换为复制的内容

<UserSecretsId>979b4b67-add4-46bb-80c6-49dab268ca91</UserSecretsId>

5.5. Program.cs 文件测试效果

using Microsoft.Extensions.Configuration;
IConfiguration? Config; Config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
var apiKey = Config["ApiKey"];
Console.WriteLine(apiKey);

.NET CLI

  • 启用机密存储
dotnet user-secrets init
  • 设置机密
dotnet user-secrets set "Movies:ServiceApiKey" "12345"

在上述示例中,冒号表示 Movies 是具有 ServiceApiKey 属性的对象文字。

  • 列出机密
dotnet user-secrets list
  • 删除单个机密
dotnet user-secrets remove "Movies:ConnectionString"
  • 删除所有机密
dotnet user-secrets clear

优先级

注意:如果你的appsetting.json文件中有和secrets.json文件中相同节点(冲突)的配置项,那么就会被secrets.json中的设置项给覆盖掉,因为 builder.AddUserSecrets()晚于 AddJsonFile("appsettings.json")注册, 那么我们可以利用这个特性来在每个开发人员的机器上重新设置数据库连接字符串了。

总结

以上,或许可以感受到微软在 ASP.NET Core 中对于开发人员还是非常贴心的,很多小细节都考虑到了,因此在我们构建应用程序的过程中,可以多使用这些小功能(特性)来让我们的代码更加的优雅~

参考资料

项目源码

Github | Gitee

关联项目

FreeSql QQ群:4336577(已满)、8578575(已满)、52508226(在线)

BA & Blazor QQ群:795206915、675147445

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow(包含链接: https://github.com/densen2014 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

AlexChow

今日头条 | 博客园 | 知乎 | Gitee | GitHub

Blazor 在开发环境保存机密(User Secrets)的更多相关文章

  1. ASP.NET Core 优雅的在开发环境保存机密(User Secrets)

    前言 在应用程序开发的过程中,有的时候需要在代码中保存一些机密的信息,比如加密密钥,字符串,或者是用户名密码等.通常的做法是保存到一个配置文件中,在以前我们会把他保存到web.config中,但是在A ...

  2. ubuntu中使用机密数据Secrets

    目录 AptNetCore使用Secrets管理私密数据 前言 使用 设置UserSecretsId 设置机密 代码中访问机密 脚注 AptNetCore使用Secrets管理私密数据 前言 在项目中 ...

  3. Blazor+Dapr+K8s微服务之开发环境调试

    1         安装Dapr开发调试环境 1.1         Dapr 完整安装模式不支持开发调试 在上一篇随笔<Blazor+Dapr+K8s微服务之服务调用>中,我们通过为每个 ...

  4. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  5. 在Ubuntu下搭建ASP.NET 5开发环境

    在Ubuntu下搭建ASP.NET 5开发环境 0x00 写在前面的废话 年底这段时间实在太忙了,各种事情都凑在这个时候,没时间去学习自己感兴趣的东西,所以博客也好就没写了.最近工作上有个小功能要做成 ...

  6. 自定义搭建PHP开发环境

    学习了一段时间php了,因为之前是刚接触php,所以用的是集成安装包(wamp).现在想进一步了解apache.mysql.php之间的关系以及提升自己所以进行自定义搭建PHP开发环境.废话不多说,请 ...

  7. 打造TypeScript的Visual Studio Code开发环境

    打造TypeScript的Visual Studio Code开发环境 本文转自:https://zhuanlan.zhihu.com/p/21611724 作者: 2gua TypeScript是由 ...

  8. PHP开发环境的配置

    PHP的开发环境主要包括:安装和配置Apache服务器.PHP引擎以及MySQL数据库服务器,另外选用Dreamweaver作为PHP的开发工具. 1.安装和测试Apache 首先下载Apache:官 ...

  9. 【工匠大道】Mac下Java开发环境配置简述

    本文地址 原文地址 分享提纲: 1. 下载JDK1.7 2. 配置java_home 3 .安装tomcat 4 .安装eclipse或者myeclipse 5.  mysql安装 破解版下载请参考M ...

随机推荐

  1. 远程控制Windows2003下安装Pcanywhere导致Awgina.dll出错的解决办法

    远程控制的时候出现的问题引用 症状启动计算机时,"欢迎使用 Windows"登录屏幕不出现.您还可能会看到与下面的某条信息类似的错误信息: ? 一个最近安装的程序使欢迎屏幕和快速用 ...

  2. DAViCal 跨站请求伪造漏洞

    受影响系统:DAViCal DAViCal <= 1.1.8描述:CVE(CAN) ID: CVE-2019-18346 DAViCal是一款日历共享服务器. DAViCal 1.1.8及之前版 ...

  3. Spring MVC 04-- 接收前端参数json格式的方式

    /** * 第一种:以RequestParam接收 * 前端传来的是json数据不多时:{"id":1},可以直接用@RequestParam来获取值 * * @param id ...

  4. K8S原来如此简单(七)存储

    emptyDir临时卷 有些应用程序需要额外的存储,但并不关心数据在重启后仍然可用. 例如,缓存服务经常受限于内存大小,将不常用的数据转移到比内存慢.但对总体性能的影响很小的存储中. 再例如,有些应用 ...

  5. JavaScript 事件循环(1) —— 从 setTimeout 说起

    转变认知 setTimeout 可能是很多前端工程师爱用的方法,它可以使得一段代码延迟执行,例如: setTimeout(() => console.log('A'), 1000); // 在1 ...

  6. 一图学Python

    网上有这样一张图片,信息量很大,通常会被配上标题"一张图让你学会Python": 这张图流传甚广,但我没有找到明确的出处,图片上附带了 UliPad 的作者 Limodou 的信息 ...

  7. jvm-learning-概述

    JVM整体结构: java代码的执行流程 JVM的架构模型 public class StackStruTest { public static void main(String[] args) { ...

  8. Oracle入门基础(六)一一子查询

    SQL> --查询工资比SCOTT高的员工信息 SQL> --1. SCOTT的工资 SQL> select sal from emp where ename='SCOTT'; SA ...

  9. java-設計模式-單例模式

    單例模式 一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点. 一个类只有一个实例,且该类能自行创建这个实例的一种模式. 簡單的對比就是: 例如,Windows 中 ...

  10. 解释 AOP 模块?

    AOP 模块用于发给我们的 Spring 应用做面向切面的开发, 很多支持由 AOP 联 盟提供,这样就确保了 Spring 和其他 AOP 框架的共通性.这个模块将元数据编 程引入 Spring.