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

时间:2017-12-21 02:36:06

标签: .net amazon-web-services .net-core aws-sdk asp.net-core-webapi

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

首先我们得到了AmazonServiceException:无法找到凭据,但现在我们收到消息:AmazonClientException:没有配置RegionEndpoint或ServiceURL。我觉得它更好。

我们的配置: 在我们的应用程序中,我们有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);
    }

以下是我们的问题: 在哪里或如何配置我们项目的凭证?

提前感谢您的回答。

4 个答案:

答案 0 :(得分:4)

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

在此示例中,我需要 AWS 凭证(访问密钥 ID 和访问密钥)和区域,以及我需要的 SQS 队列客户端的一些其他配置。 该应用程序是一个 .Net 5 Worker Service(它具有开箱即用的依赖项注入和配置文件设置,与 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 来传递访问密钥和秘密密钥:

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 实例,以便依赖注入可以注入它。

参考文献:

答案 1 :(得分:2)

以下是我撰写的关于使用AWSSDK.Extensions.NETCore.Setup

为.NET Core配置AWS凭据的博客文章

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

答案 2 :(得分:2)

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

如果您使用的是AWS SDK,请使用以下内容:

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

设置环境

您可能希望服务器上的代码对于每个环境都是相同的 - 它使部署和其他任务变得更加容易。您可以使用参数存储来存储每个AWS环境的所有配置。

我的方法是使用&#34; 标记&#34;在EC2实例上指定环境名称。然后我使用标签从参数存储中获得正确的配置。

在您的情况下,代码可以是environment=developmentenvironment=production

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

它们看起来类似于:

/development/ConnectionStrings/Database
/development/MySettingGroup/MySetting
/production/ConnectionStrings/Database
/production/MySettingGroup/MySetting

我已经向github添加了一些代码来检查标签和参数等 - 如果它在本地运行,则默认为环境名称&#34; LocalDevelopment&#34; (这是我使用的惯例 - 因此您需要将其更改为&#34; Local&#34;)并加载正确的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/*"
          ]
      }
  ]
}

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

如果您愿意,可以在appsettings.Production.json中保留一些配置 - 这只是意味着如果您想创建一个新环境,您需要创建一个新的JSON文件并部署新代码等。如果所有环境信息都在AWS(即参数存储)中,它可能会更清洁。

答案 3 :(得分:0)

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

谢谢你的帮助Rajesh。

但如果有人知道它为什么现在有用,请提前感谢你在这里写下你的答案。