通过 .NET Core 访问 AWS Secrets Manager





5.00/5 (5投票s)
本文将帮助您实现将敏感数据存储在亚马逊 Secrets Manager 中并在启动应用程序时访问该功能。
引言
我正在我的项目中使用 application.json 存储密钥。但是,当我看到 AWS Secrets Manager 时,它看起来很安全,并且易于在我的系统中实现。
- 这将有助于在安全位置存储密钥,如连接字符串路径。
- 这些值总是被加密的,因此未经授权无法访问它们
- 您无需在值被修改的情况下部署应用程序。
- 非常容易更改值。
- 实现简单且非常快速。
本文将帮助您实现一个基本原型,您可以在其中从 Secrets Manager 访问项目的密钥。代码将逐步向您解释我们能做什么以及如何做到这一点。
本文使用 .NET Core 2.2 来实现此功能。
安全密钥存储管理
- AWS Secrets Manager 使用您拥有并存储在 AWS Key Management Service (KMS) 中的加密密钥来静态加密密钥。
- 当您检索密钥时,Secrets Manager 会解密该密钥,并通过 TLS 将其安全地传输到您的本地环境。
- 默认情况下,Secrets Manager 不会将密钥写入或缓存到持久性存储中。您可以使用细粒度的 AWS Identity and Access Management (IAM) 策略来控制对密钥的访问。
审核和监控密钥使用情况
- 已更改或修改的密钥受版本控制。
- 您可以跟踪哪个密钥被更改以及何时被修改。
- 我们可以为密钥设置云观察日志记录,这将提供有关密钥版本控制的详细信息。
自动密钥轮换
- 使用 AWS Secrets Manager,您可以通过使用 Secrets Manager 控制台、AWS SDK 定期或按需轮换密钥
- 您还可以通过修改示例 Lambda 函数来扩展此功能以轮换其他密钥。例如,您可以轮换用于授权应用程序的 OAuth 刷新令牌或用于本地托管的 MySQL 数据库的密码。
- 所有这些都可以通过 AWS 提供的 Secrets Manager API 来完成。
Using the Code
我创建了一个微服务,它只做一件事,从 AWS 检索数据并将密钥以字符串格式提供。该服务包含从 Amazon Secrets manager 请求数据并以 json 格式返回的完整实现
项目先决条件
- Amazon Webservice 提供的
AWSSD.Core
- Amazon Seb Services 提供的
AWSSDK.SecretsManager
Microsoft.AspNetCore.App
Microsoft.NETCore.App
Swashbuckle.AspNetCore
(这是用于 swagger 的)
首先,对于我们的 Core API,我们需要通过 Rest 端点 API 输入。由于我们正在将其创建为 API,您可以发送详细信息和密钥。为了做到这一点,让我们创建一个模型,可以在其中使用它。
/// This is a class which will give us all the information for extracting the data
public class SecretsDetail
{
public string Region { get; set; } // The region you deployed your secrets
public string SecretName { get; set; } // The secret name to access the secret
public string AccessKeyID { get; set; } // access id created for the secret authorization
public string SecretKey { get; set; } // key for authorization
public string VersionStage { get; set; } // Which version you want to access
public string ServiceURL { get; set; } // the path of the endpoint
}
一旦我们的模型准备就绪,我们就可以在控制器中使用该模型,它将传递给 GetSecretManager
类。当我们拥有所有用于 AWS 通信的详细信息时,我们就可以构建对象了。在下面的代码块中,我们使用 AmazaonSecretsManagerConfig
构建 Secrets Manager 的端点信息。
AmazonSecretManagerClient
将接受参数,如 AccessID SecretKey
和 config
。如果您在网络中或在 EC2 实例上工作,则无需提供配置。您只需传递 secretName
和访问 ID 以及 secretKey
即可。但在亚马逊网络之外,您需要下面使用的所有详细信息
// Get the Secret name
string secretName = secretsDetail.SecretName;
//Assign the region.
string region = secretsDetail.Region;
string secret = "";
MemoryStream memoryStream = new MemoryStream();
AmazonSecretsManagerConfig amazonSecretsManagerConfig = new AmazonSecretsManagerConfig();
amazonSecretsManagerConfig.ServiceURL = secretsDetail.ServiceURL;
IAmazonSecretsManager client = new AmazonSecretsManagerClient
(secretsDetail.AccessKeyID, secretsDetail.SecretKey, amazonSecretsManagerConfig);
GetSecretValueRequest request = new GetSecretValueRequest();
request.SecretId = secretName;
request.VersionStage = secretsDetail.VersionStage == null ?
"AWSCURRENT" : secretsDetail.VersionStage; // VersionStage defaults to AWSCURRENT if unspecified.
GetSecretValueResponse response = null;
This code block will build the client get the response back.
AmazonSecretsManagerConfig
将获取端点信息。这将有助于从 SecretManagerClient
获取值。 AccessKeyID
和 SecretKey
将为您提供 Response
的详细信息。
以下代码将从内存流中提取数据,并为我们提供纯 string
,我们可以将其转换为 Json 格式。
try
{
response = client.GetSecretValueAsync(request).Result;
} catch (DecryptionFailureException)
{
// Secrets Manager can't decrypt the protected secret text using the provided KMS key.
// Deal with the exception here, and/or rethrow at your discretion
throw;
}
if (response.SecretString != null)
{
return secret = response.SecretString;
}
else
{
memoryStream = response.SecretBinary;
StreamReader reader = new StreamReader(memoryStream);
string decodedBinarySecret = System.Text.Encoding.UTF8.GetString
(Convert.FromBase64String(reader.ReadToEnd()));
return decodedBinarySecret;
}
Swagger 测试
结果
附带的源代码将提供有关其构建方式的所有详细信息。如果您需要更多说明,请随时写评论。
注释
- 代码已启动并运行。您只需要传递正确的值,它就会给出数据。
- 您可以使用配置好的 swagger 来测试代码。
- 如果您遇到任何挑战或任何错误,请在评论中提及。
历史
- 2019年3月11日:初始版本