0
点赞
收藏
分享

微信扫一扫

ASP.NET Core中使用AWS Secrets Manager

夕颜合欢落 2022-03-16 阅读 90
aws云计算

在Public Cloud中运行 ASP.NET Core 应用的一个重要方面是如何保护应用所需的机密(如连接字符串和 API 密钥等等)。在这篇文章中,我将介绍一个开源包来连接AWS的密钥管理。

保护 ASP.NET 核心应用中的敏感信息

包括连接字符串、API 密钥和证书等内容。根据经验,切勿将这些值写入 appsettings.json 文件或签入到源代码管理存储库的任何文件中。理想情况下,它们应存储在源代码之外

为了本地开发,User Secrets(Safe storage of app secrets in development in ASP.NET Core | Microsoft Docs是存储敏感值的首选方法。此工具管理在项目的工作目录 (在用户配置文件目录中).这适用于本地开发,但重要的是要注意用户机密不会加密机密,它只是将它们移动到不太可能意外暴露的位置。

默认情况下,如果您使用的是默认构建器,则用户机密将添加到 ASP.NET 核心配置中:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args) // Adds User Secrets to configuration
        .UseStartup<Startup>();

User Secrets仅用于开发时存储敏感配置,那么在生产环境中呢?

很大程度上取决于运行环境。环境变量也可行,不过也优缺点。

也可以CI/CD的时候,将配置信息写到Docker镜像中,但也不是最好的方式。

更好的方法,也是Microsoft提倡的方式(Azure Key Vault configuration provider in ASP.NET Core | Microsoft Docs)用于将敏感信息存储在专用的"敏感信息库"(如 Azure的Key Vault服务)中。在运行时,应用会从 Azure Key Vault服务请求对机密的访问权限。

将密钥添加到 AWS 密钥管理器

与大多数 AWS 功能一样,有几种方法可以将密钥添加到 AWS Secrets Manager。我这里就简单使用Portal添加,过程省略(比如secret name叫mySecret)。

{
  "A:B": "A-B-Value"
}

 使用 ASP.NET 核心从 AWS 密钥管理器加载密钥

现在我们已经存储了一个秘密,我们现在准备在ASP.NET Core应用程序中加载他。这个使用了一个名为Kralizek.Extensions.Configuration.AWSSecretsManager的nuget包。也是开源项目:https://github.com/Kralizek/AWSSecretsManagerConfigurationExtensions

使用将包添加到项目中:

dotnet add package Kralizek.Extensions.Configuration.AWSSecretsManager

然后在程序启动的时候加载:

public class Program
{
    public static void Main(string[] args) => BuildWebHost(args).Run();

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>  
            {
                var configuration = config.Build(); 
                var accessKey = configuration.GetValue<string>("AWS:Credentials:AccessKey");
                var secretKey = configuration.GetValue<string>("AWS:Credentials:SecretKey");
                var region = configuration.GetValue<string>("AWS:Region");
                var secretName = configuration.GetValue<string>("AWS:SecretName");
                var credentials = new BasicAWSCredentials(accessKey, secretKey);
                config.AddSecretsManager(credentials,
                RegionEndpoint.GetBySystemName(region),
                options =>
                {
                     //因为使用accessKey和secretKey可能会拿到不需要的配置。所以可以用secretName作为前缀来过滤一下。
                     // 格式为:secretename:configRootKey:configChildKey
                     options.SecretFilter = entry => entry.Name.Contains(secretName);
                     // 这里把"secretname:"前缀去掉,代码里就统一了。
                     options.KeyGenerator = (secret, name) => name.Replace($"{secretName}:", string.Empty);
                            });
            })
            .UseStartup<Startup>()
            .Build();

            // 使用的时候即可通过Configuration["A:B"]获取到
}

在本地开发时不要添加密钥

首先,我不想在本地开发应用程序时使用AWS SecretsManager - .NET User Secrets是解决这个问题的更好解决方案。当本地开发数据库在本地处理应用程序时,

在本地开发时忽略 AWS Secrets Manager.我们可以有条件地检查我们是否在环境中,并且仅在适当的情况下调用:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>  
        {
            // 开发环境不加载
            if(!hostingContext.HostingEnvironment.IsDevelopment())
            {
                config.AddSecretsManager();
            }
        })
        .UseStartup<Startup>()
        .Build();

就是这样 -现在可以将密钥安全地存储在密钥管理器中,根据运行应用程序的 AWS IAM 角色在运行时加载密钥!可以根据实际情况调整加载配置的代码。

举报

相关推荐

0 条评论