【问题标题】:How to specify AWS credentials in C# .NET core console program如何在 C# .NET 核心控制台程序中指定 AWS 凭证
【发布时间】:2021-11-26 23:58:54
【问题描述】:

我正在尝试测试 .NET 核心控制台程序以将消息发布到 SNS。由于我在尝试让它在 Lambda 中工作时遇到问题,我想在非 Lambda 环境中尝试它。在 Lambda 中,角色涵盖了安全性,但在控制台程序中,我认为我必须以某种方式指定我的访问密钥和秘密。

我已经阅读了这个页面:http://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#net-dg-config-creds-sdk-store,但仍然很困惑。

我在本地开发计算机上运行,​​而不是 EC2 实例。无意将其投入生产,只是尝试测试一些代码。

我使用的是 Visual Studio 2015,.NET Core 1.0。我使用 Nuget 获得以下信息: "AWSSDK.Extensions.NETCore.Setup": "3.3.3", "AWSSDK.SimpleNotificationService": "3.3.0.23",

根据对How to set credentials on AWS SDK on NET Core? 的回答,我创建了 /user/.aws/credentials 文件(假设凭据是文件名而不是目录名)。

但该问题/答案并未说明如何实际使用此文件。我正在运行的代码如下。

    public static void Main(string[] args)
    {
        Console.WriteLine("Started");
        //var awsCredentials = new Amazon.Runtime.AWSCredentials()
        var client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient(Amazon.RegionEndpoint.EUWest2);
        //var client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient(awsCredentials, Amazon.RegionEndpoint.EUWest2);
        //Amazon.SimpleNotificationService.Model.PublishResponse publishResp = null;
        SendMessage(client).Wait();
        Console.WriteLine("Completed call to SendMessage: Press enter to end:");
        Console.ReadLine(); 
    }

我在新客户端上遇到的错误是:

An unhandled exception of type 'Amazon.Runtime.AmazonServiceException' occurred in AWSSDK.Core.dll

Additional information: Unable to find credentials

我看到有一种方法可以将 AWSCredentials 对象传递给该构造函数,但我不明白如何构建它。 Amazon.Runtime.AWSCredentials 是一个抽象类,所以我不能在“新”语句中使用它。

【问题讨论】:

  • 致downvoter:请提供一种方法来改善OP的问题,而不是downvoting和什么都不说
  • 默认情况下,Amazon SDK 将使用标准位置作为凭证(如果已设置)。设置默认凭证的最简单方法是安装 AWS CLI。从命令提示符尝试此命令:“aws sns list-topics”。如果失败,请安装 AWS 命令​​行界面 aws.amazon.com/cli 并设置您的凭证。
  • @Dan Pantry。我同意。我们应该互相帮助改进问题和答案,不仅针对当前线程,而且针对已建立的知识库。然后,我们还可以对属于 downvote 的 cmets 进行投票。
  • 我以前用过amazon-cli。因此,如果我从那里运行 .NET 控制台程序,那么它会“继承”这些凭据吗?我只是想在 Visual Studio 中运行。

标签: c# amazon-web-services aws-sdk


【解决方案1】:

根据 Dan Pantry 的回答,这是一个简单的简短回答,代码突出显示(注意第二行中的区域枚举):

var awsCredentials = new Amazon.Runtime.BasicAWSCredentials("myaccesskey", "mysecretkey"); 
var client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationSer‌​viceClient(
                              awsCreden‌​tials, Amazon.RegionEndpoint.EUWest2);

如果可能,请使用角色,但以上在需要时可以使用。那么问题是在哪里存储访问密钥/秘密密钥;可能是环境变量、配置文件、提示用户或任何常见的嫌疑人。

AWS-CLI 和 Python 使用此处的凭证:c:\Users\username\.aws\credentials,因此 C# 可以只读取该文件,以免将代码放入 C# 程序本身。但是运行该程序的每个用户/开发人员都需要在那里设置他们的凭据。

现在也有在本地机器上运行 Lambda 的概念,但是我还没试过: https://dzone.com/articles/run-aws-lambda-functions-locally-on-windows-machin#:~:text=Step%201%3A%20Download%20SAM%20local,version%20with%20the%20command%20below.&text=Step%203%3A%20Write%20your%20lambda,yaml%20on%20the%20root%20level。 所以关键是,如果你要做 Lambda,但你需要先在本地测试,这可能值得一试。

【讨论】:

  • 我遇到了类似的问题,即我的凭据没有从 .net 核心中的 appsettings 中获取。我正在使用 dynamo db 进行访问。我在stackoverflow.com/questions/53176420/…创建了我的帖子,你能检查我如何在那里设置它。
  • 这确实不是正确的答案,将凭据显式传递给 SDK 不是推荐的方式,并且仅提供了覆盖。您真正想要做的是让凭据提供程序加载凭据,这意味着它们首先需要注册。
  • 欢迎您提出更好的答案。另请注意,我说我在 TEST 环境(我的家用计算机)中运行 .NET 控制台程序,而不是在 Lambda 下运行...
  • 谢谢尼尔(仍然是一个有用的答案)BasicAWSCredentials 确实应该突出显示 - 但不是亚马逊。显然是因为有(过度设计?)用他们的 SDK 保存信用的方式。我正在使用 .Net Core,将值存储在一个秘密文件中。然后这些值被注入到设置中,然后由创建客户端的函数使用。我不需要神奇的 SDK 凭据开销
  • 我只是在想,AWS-CLI 和 Python 使用来自这里的凭证:c:\Users\username\.aws\credentials,所以 C# 可以只读取该文件,以免放置代码在 C# 程序本身中。但我回答的重点是显示语法,而不是存储代码的方式和位置。
【解决方案2】:

您需要构造它的一个子类,而不是抽象类。你可以看看类层次结构here

对于后代,选项是:

  • AnonymousAWSCredentials - 以匿名用户身份进行身份验证。
  • BasicAWSCredentials - 您直接向类构造函数提供您的凭据。
  • EnvironmentAWSCredentials - 从正在运行的可执行文件的环境变量中提取凭据。
  • InstanceProfileAWSCredentials - 从运行可执行文件的 EC2 实例的实例配置文件中提取凭证。这显然只适用于 EC2。
  • SessionAWSCredentials - 类似于 BasicAWSCredentials,但使用 AWS STS 中的临时会话令牌使用 AWS 会话。
  • RefreshingSessionAWSCredentials - 类似于 SessionAWSCredentials,但会在 STS 令牌过期时刷新。

请注意,在没有凭据对象的情况下,默认策略涉及检查环境变量,然后是实例配置文件。

如果您想让程序从~/.aws/credentials 提取凭据,您需要做一些跑腿工作。曾经有一个 StoredProfileAWSCredentials 类,但似乎已被删除 - 您可以通过查看 this github 问题找到更多信息。实际上,这仅在开发中有用,因为您不会在生产中使用 ~/.aws/credentials,但可能会使用实例配置文件 - 我建议在测试或开发环境中使用默认策略并使用 Environment AWS 凭证。

我在工作中采用这种方法,因为我们使用命令行工具从 AWS STS 中获取有限时间令牌,并将它们插入当前 shell 以供下一小时使用。

编辑:看来您正在使用 AWS Lambda。它们基于分配给它们的角色对 AWS 资源进行联合访问,因此这应该使用 aws-sdk 库中使用实例配置文件的默认凭证策略来工作。所以这只是开发/测试真正需要的,在这种情况下,我再次建议只使用环境变量。

【讨论】:

  • 不,问题不在于 Lambda。我说我正在使用 Lambda 并且遇到了问题,并希望在控制台 .NET 核心程序中执行相同的功能。我正在尝试隔离我收到的 async/MoveNext 错误是否与 Lambda 相关。所以我会尝试你提供的课程之一。
  • 这行得通。让我了解了我在那里尝试测试的凭据问题: var awsCredentials = new Amazon.Runtime.BasicAWSCredentials("myaccesskey", "mysecretkey"); var client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient(awsCredentials, Amazon.RegionEndpoint.EUWest2);
  • 啊,好吧,我错了。对不起,我看到代码示例并运行它!
  • 更新:今天(2020,AWSSDK.Core,Version=3.3.0.0)环境变量凭证类显然是EnvironmentVariablesAWSCredentials
【解决方案3】:

这是一个非常老的问题,现有的答案有效,但我真的不喜欢将我的访问密钥 ID 和密钥值直接硬编码到源代码中,即使对于 throw-我在本地机器上做的项目。一方面,我将来可能会撤销这些密钥,因此我想利用 .aws\credentials 文件中的凭据。

要为我的 .NET 核心应用程序(包括控制台应用程序等)执行此操作,我首先添加两个 NuGet 包:

  • Microsoft.Extensions.Configuration.Json
  • AWSSDK.Extensions.NETCore.Setup

然后,我在我的项目中添加了一个 applications.json 文件,其中包含以下内容(注意 - 您需要右键单击该文件,并将“复制到输出”设置为“如果较新则复制”或“始终” ):

{
  "AWS": {
    "Profile": "default",
    "ProfilesLocation": "C:\\Users\\my-user-profile-folder\\.aws\\credentials",
    "Region": "us-west-2"
  }
}

最后,我使用以下内容创建 AWS 开发工具包客户端的实例:

var builder = new ConfigurationBuilder().AddJsonFile("appsettings.Development.json", optional: false, reloadOnChange: true);
var options = builder.Build().GetAWSOptions();
var s3client = options.CreateServiceClient<IAmazonS3>();

这样,如果我更新我的凭据文件,我很好。或者,如果我的代码被压缩并通过电子邮件发送给朋友或同事,我不会不小心将我的凭据也发送给他们。

另一种方法可以做到这一点,而无需添加 NuGet 包,许多人可能更喜欢这种方式。您可以像这样使用新的 SharedCredentialsFile 类和 AWSCredentialsFactory(在此处使用“默认”配置文件,并假设您的凭据文件位于默认位置,与其他方法相同):

var sharedFile = new SharedCredentialsFile();
sharedFile.TryGetProfile("default", out var profile);
AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedFile, out var credentials);

var s3Client = new AmazonS3Client(credentials);

注意 - 我没有检查这两个 Try* 方法是否在这里成功,您可能应该这样做。使用这些类的详细信息在这里:https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#how-to-create-an-amazons3client-using-the-sharedcredentialsfile-class

【讨论】:

  • 谢谢。不过,我有一个问题,关于配置文件位置,如果它托管在云中会怎样。我的意思是这会改变什么吗?
  • 如果您的代码在 AWS 中运行,开发工具包将从运行代码的 EC2 实例、容器或 Lambda 函数上的 IAM 角色获取临时凭证(假设您使用的是 IAM 角色)。而且您应该 - 不要将您的密钥放在代码执行环境中的文件上,这本质上不太安全。
  • 只是给像我这样最终来到这里的人。来自 AWS 文档:“SDK 存储配置文件特定于特定主机上的特定用户。因此,您不能在生产应用程序中使用 SDK 存储配置文件。有关更多信息,请参阅docs.aws.amazon.com/sdk-for-net/v3/developer-guide/…
  • 当然,但最初提出的问题是在非 lambda 环境中测试 .NET Core 控制台应用程序,这可能意味着在用户的本地开发机器上进行测试。对于部署在 AWS 或由 AWS Systems Manager(依赖于代理)管理的本地 VM 实例的生产应用程序,您将使用附加到代码执行环境(EC2、ECS/Fargate 容器、Lambda、CodeBuild 容器等)的 IAM 配置文件)。
【解决方案4】:

对于那些纠结于个人资料名称的人,您可以在这里找到它。

你的~/.aws/credentials的内容:

[YOUR_PROFILE_NAME]
aws_access_key_id = ***
aws_secret_access_key = ***
aws_security_token = ***
aws_session_expiration = ***
aws_session_token = ***

那么在您的应用程序中,您可以像这样访问凭据:

var chain = new CredentialProfileStoreChain();
var result = chain.TryGetAWSCredentials("YOUR_PROFILE_NAME", out var credentials);

资源:

【讨论】:

  • 一旦您有两个客户端,并且为这两个客户端使用同一台计算机,这一点至关重要。所以最好从一开始就使用配置文件。
【解决方案5】:

在将您的凭据保存在共享的“凭据”文件中的同时,您可以在创建 CredentialProfileStoreChain 时重新定义 ProfilesLocation

//define your file location here:
var chain = new CredentialProfileStoreChain(@"C:\aws\credentials");
// input the name of your credentials here:
if (chain.TryGetAWSCredentials("nameofprofile", out AWSCredentials awsCredentials))
{
    //executes if the credentials were found and inserted into awsCredentials
}
else
{
    // executes if the credentials were not found
}

取自这里:https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/creds-locate.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2023-01-31
    • 2020-07-31
    相关资源
    最近更新 更多