如何使用 .net Core 设置 AWS 凭证

Posted

技术标签:

【中文标题】如何使用 .net Core 设置 AWS 凭证【英文标题】:How to set AWS credentials with .net Core 【发布时间】:2018-06-03 16:02:25 【问题描述】:

我必须调试有关 .net Core 和 AWS 的现有项目。 我们的项目在我们的 AWS 实例上运行良好,但我们无法在本地运行该项目。

首先我们收到了 AmazonServiceException: Unable to find credentials,但现在我们收到了消息:AmazonClientException: No RegionEndpoint or ServiceURL configured。我觉得这样更好。

我们的配置: 在我们的应用程序中,我们有 3 个 appsettings.env.EnvironmentName.json(开发、本地和生产)。我们知道默认情况下 VS 使用开发文件。 在我们的开发 appsettings 文件中,我们没有 AWS 对象,但在本地 appsettings 文件中,我们只有:

"AWS": 
      "Region": "ap-southeast-2"

我们没有任何 web.config 或其他 json 配置文件。

我们尝试将凭证文件创建为:

[name of my IAM profile]
aws_access_key_id=accesskey
aws_secret_access_key=secretkey
region=ap-southeast-2

但我们没有找到如何使用它。

我们也尝试使用 dotnet core run 命令运行项目,并指定一些环境变量为:

export AWS_Region=ap-southeast-2
export AWS_ACCESS_KEY_ID=id
export AWS_SECRET_ACCESS_KEY=secret
export AWS_SESSION_TOKEN=token
export 
AWS_CREDENTIAL_FILE=/Users/user/Developer/exemple/nameproject/G$

但同样的错误。

Program.cs 文件:

var host = new WebHostBuilder()
    .UseKestrel(options => options.AddServerHeader = false)
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup<Startup>()
    .UseUrls("http://*:9000")
    .CaptureStartupErrors(true)
    .Build();

host.Run();

启动文件(第一个函数):

public Startup(IHostingEnvironment env) 
        // Configuration override https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile($"appsettings.env.EnvironmentName.json", false, true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();

        // Shared startup configurator
        CommonStartup = new CommonStartup(env, Configuration);
    

这是我们的问题: 我们项目的凭据在哪里或如何配置?

提前感谢您的回答。

【问题讨论】:

AWS SDK 会自动尝试查找 Access/Secret 密钥,因此将它们包含在您的 app.config 中就足够了。 app.config 中的密钥需要为“AWSAccessKey”和“AWSSecretKey” 感谢您的回答拉杰什。问题是这个项目中除了 3 个 appsettings.env.EnvironmentName.json 之外没有 appconfig。你能给我一个这个文件的例子吗?并且默认项目使用开发配置文件,我如何告诉它使用本地版本的appsettings?提前感谢您的回答。 当您使用配置构建器时,只需将它们添加到您的 json 中,它们就会流过。 我试图在我的 appsettings 文件中添加它:“AWS”:“AccessKeyId”:“myaccesskey”,“SecretAccessKey”:“mysecretkey”,“Region”:“ap-southeast-2”但是我收到了消息:donet 意外退出(我在 mac 上)... 【参考方案1】:

在 AWS 中,您可以创建一个 IAM 角色并将其配置为只能访问它需要的资源(S3 读/写、SES 等)。然后,您可以将此角色附加到 EC2 实例。

如果您使用的是 AWS 开发工具包,请使用以下内容:

services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService<IAmazonS3>();

它会自动为您处理权限。

对于本地开发,您可能希望使用凭证文件。在您的 appsettings.Local.json 中,您将有一个类似于此的设置:

"AWS": 
  "Profile": "myprofilename",
  "Region": "eu-west-1",
  "ProfilesLocation": "C:\\Credentials.txt"

您可能希望将凭据文件存储在项目之外,以免意外将其签入源代码管理。

Credentials.txt 看起来像:

[myprofilename]
aws_access_key_id=MY_ACCESS_KEY
aws_secret_access_key=MY_ACCESS_SECRET

设置环境

您可能希望服务器上的代码对于每个环境都相同 - 它使部署和其他任务变得更加容易。您可以通过使用 Parameter Store 存储每个 AWS 环境的所有配置来实现这一点。

我的方法是在 EC2 实例上使用“tag”来指定环境名称。然后我使用标签从 Parameter Store 获取正确的配置。

在您的情况下,标签可以是 environment=developmentenvironment=production

存储中的参数名称/键应与您要覆盖的 JSON appsettings 文件中的属性名称匹配。

它们看起来类似于:

/开发/连接字符串/数据库 /development/MySettingGroup/MySetting /生产/连接字符串/数据库 /production/MySettingGroup/MySetting

我已经向 github 添加了一些代码来检查标签和参数等 - 如果它在本地运行,它默认为“LocalDevelopment”的环境名称(这是我使用的约定 - 所以你需要将其更改为“ Local") 并加载正确的 appsettings 文件。

https://github.com/secretorange/aws-aspnetcore-environment-startup

您需要在项目中使用的文件在这里:

https://github.com/secretorange/aws-aspnetcore-environment-startup/tree/master/AWSBoot/Boot

使用BootHelper,您的启动代码将如下所示:

public static IWebHost BuildWebHost()

    // ===================================
    // Get the boot config from the server
    // ===================================
    var bootConfig = Task.Run(() => BootHelper.GetConfig()).Result;

    var webHost = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((context, config) =>
        
            // !!! IMPORTANT !!!
            // Set the environment from boot config
            context.HostingEnvironment.EnvironmentName = bootConfig.Environment;

            config.AddJsonFile("appsettings.json", optional: true)
                    .AddJsonFile($"appsettings.context.HostingEnvironment.EnvironmentName.json", optional: true);

            // !!! IMPORTANT !!!
            // If there are any parameters from the server
            // then we'll use them to override anything in the JSON files
            config.AddInMemoryCollection(bootConfig.Parameters);
        )
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    return webHost;

AWS 中的 IAM 角色需要附加策略以授予对标签和参数等的访问权限。它们看起来类似于:


  "Version": "2012-10-17",
  "Statement": [
      
          "Sid": "VisualEditor0",
          "Effect": "Allow",
          "Action": [
              "ec2:DescribeInstances",
              "tag:GetResources",
              "tag:GetTagValues",
              "tag:GetTagKeys"
          ],
          "Resource": "*"
      
  ]




  "Version": "2012-10-17",
  "Statement": [
      
          "Sid": "VisualEditor0",
          "Effect": "Allow",
          "Action": "ssm:GetParametersByPath",
          "Resource": [
              "arn:aws:ssm:YOUR_ARN_HERE:parameter/development",
              "arn:aws:ssm:YOUR_ARN_HERE:parameter/development/*"
          ]
      
  ]

设置起来似乎有点麻烦 - 但一旦它开始运行,这意味着您可以轻松地将所有秘密置于源代码控制之外,并且只需创建一个新环境(例如 Staging)就可以创建一个新环境标签和参数。无需更改代码。

如果你愿意,你可以在appsettings.Production.json 中保留一些配置——这只是意味着如果你想创建一个新环境,你需要创建一个新的 JSON 文件并部署新代码等。这可能有点如果所有环境信息都在 AWS(即 Parameter Store)中,则更清晰。

【讨论】:

【参考方案2】:

我找到了一种使用 appsettings.json 文件中的 only 值配置 AWS 凭证的方法。我将在下面详细说明,以防它可能对某人有所帮助。小心!这不是 AWS 推荐的方式,我只是在这个特定的用例中需要它。

在此示例中,我需要 AWS 凭证(访问密钥 ID 和访问密钥)以及区域,以及我需要的 SQS 队列客户端的一些其他配置。 该应用程序是一个 .Net 5 Worker 服务(它具有开箱即用的依赖注入和配置文件设置,与 ASP.Net Core Web 应用程序相同)。

这里是 appsettings.json 文件:


  "AwsSqsConfiguration": 
    "AWSAccessKey": "ACCESSKEYID",
    "AWSSecretKey": "SECRETKEY",
    "AWSRegion": "us-west-2",
    "AWSQueueUrl": "https://sqs.us-east-1.amazonaws.com/rest-of-queue-url",
    "AWSQueueServiceUrl": "http://sqs.us-east-1.amazonaws.com"
  ,
  "Logging": 
    "LogLevel": 
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    
  

这是配置部分“AwsSqsConfiguration”的相应 C# 9 记录:

public record AwsSqsConfiguration (
        string AWSAccessKey = null,
        string AWSSecretKey = null,
        string AWSRegion = null,
        string AWSQueueUrl = null,
        string AWSQueueServiceUrl = null);

这是 Program.cs 类(类似于 ASP.Net Core Web 应用程序的 Startup.cs 类)。注意使用 Amazon.Runtime.BasicAWSCredentials 来传递 Access Key 和 Secret Key:

using Amazon.Extensions.NETCore.Setup;
using Amazon.SQS;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PlatformDeploymentService.Core.Factories;
using PlatformDeploymentService.Core.Interfaces;
using PlatformDeploymentService.Core.Models.Configuration;
using PlatformDeploymentService.Core.Services;

namespace PlatformDeploymentService.WorkerService

    public class Program
    
        public static void Main(string[] args)
        
            CreateHostBuilder(args).Build().Run();
        

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, configuration) => 
                    configuration.Sources.Clear();
                    IHostEnvironment env = hostingContext.HostingEnvironment;
                    configuration
                        .SetBasePath(env.ContentRootPath)
                        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.env.EnvironmentName.json", true, true)
                        .AddEnvironmentVariables();
                )
                .ConfigureServices((hostContext, services) =>
                
                    services.AddHostedService<Worker>();

                    var awsSqsConfiguration = new AwsSqsConfiguration();
                    hostContext.Configuration.GetSection(nameof(AwsSqsConfiguration)).Bind(awsSqsConfiguration);
                    AWSOptions awsOptions = new AWSOptions
                    
                        Credentials = new Amazon.Runtime.BasicAWSCredentials(awsSqsConfiguration.AWSAccessKey, awsSqsConfiguration.AWSSecretKey),
                        Region = Amazon.RegionEndpoint.GetBySystemName(awsSqsConfiguration.AWSRegion)
                    ;
                    services.AddDefaultAWSOptions(awsOptions);
                    services.AddSingleton<IAmazonSQS>(sp => new AmazonSQSClient(awsOptions.Credentials, new AmazonSQSConfig  ServiceURL = awsSqsConfiguration.AWSQueueServiceUrl ));
                );
    

以及该 Program.cs 类中使用的 Nuget 包的包引用:

<ItemGroup>
    <PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.3.101" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
  </ItemGroup>

然后,只要您需要 SQS 客户端对消息进行排队或其他任何事情,您就会在构造函数中收到一个 IAmazonSQS 实例,以便依赖注入可以注入它。

参考资料:

https://www.stevejgordon.co.uk/credential-loading-and-the-aws-sdk-for-dotnet-deep-dive https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/creds-assign.html

【讨论】:

我忘了提到还使用了 Nuget 包 AWSSDK.SQS(撰写本文时为 3.5.1.3 版)来引用 IAmazonSQS 和 AmazonSQSClient、AmazonSQSConfig 等。【参考方案3】:

我的目标是 .net Core 2.0 而不是 1.1,并且还在 VS 中添加环境变量(ASPNETCORE_ENVIRONMENT、AWS_SECRET_ACCESS_KEY、AWS_ACCESS_KEY_ID、AWS_DEFAULT_REGION),它可以工作!

感谢您对 Rajesh 的帮助。

但如果有人知道它现在为什么起作用,请提前在此处写下您的答案。

【讨论】:

请问您是如何添加这些环境变量的? 您可以通过多种方式进行操作。 Visual Studio 在调试下的属性中有一个位置,您可以在其中设置要提取的环境变量。确保您在正确的项目下。另一种方法是将它们添加到系统的环境变量中以运行。如果您使用 docker 或非 Windows 环境并且仍希望它在 CI (Jenkins) 上运行,这是一个不错的选择【参考方案4】:

这是我写的关于使用 AWSSDK.Extensions.NETCore.Setup 为 .NET Core 配置 AWS 凭证的博客文章

https://aws.amazon.com/blogs/developer/configuring-aws-sdk-with-net-core/

【讨论】:

但是这是什么? "Profile": "local-test-profile", 。如何在windows电脑上设置local-test-profile @norm 不是将凭据存储在文件中,而是直接从 appsettings 中读取。 与 .NET Framework 不同,没有全局单例来获取为您的应用程序创建的配置对象。 AWSSDK.Extensions.NETCore.Setup 的目的是弥合 .NET Core 配置系统与 AWS 开发工具包之间的差距,该开发工具包不能依赖配置包或拥有配置对象的句柄。 @NormJohanson 在生产中做什么?环境变量是前进的方向吗?【参考方案5】:

对我来说,缺少环境变量。刚刚添加它,它工作正常。

【讨论】:

以上是关于如何使用 .net Core 设置 AWS 凭证的主要内容,如果未能解决你的问题,请参考以下文章

如何从 CloudFoundry 向 AWS-sdk 提供凭证

AWS S3 - 如何为 Android 获取正确的凭证?

提供商链未获取 AWS 凭证文件

如何为 AWS RDS 凭证创建配置文件并将其导入我的 AWS Lambda API?

将 AWS 凭证传递给 PigStorage 函数

如何在 AWS CLI 中覆盖环境变量并使用 AWS 凭证文件?