雑記
 

AWSの共有認証情報ファイルの読み書き

最終更新日 2020/3/15 (公開日 2020/3/14)

この記事が対象とする製品・バージョン (バージョンの確認方法)

  Azure × 対象外です。
  AWS 対象です。
  Visual Studio × 対象外です。

目次

1.概要

AWSの共有認証情報ファイル(例 C:\Users\ユーザー名\.aws\credentials)をVB/C#のプログラムで読み書きする例を紹介します。

最後にこのファイルの認証情報を使ってS3バケットを列挙する例も紹介します。

 

ローカルでAWSにアクセスするプログラムを動作させる場合、共有認証情報ファイルに記載された認証情報を使用するのが一般的です。

このファイルは拡張子はありませんがテキストファイルです。メモ帳などで開けます。(形式はおそらく20世紀末に広く使われたini形式です。)

このファイルは単に「認証情報ファイル」とも呼ばれます。

共有認証情報ファイルにはアクセスキーなど複数の認証情報が保持され、VBやC#だけでなく、AWS CLIやJavaなどのプログラムからもAWSにアクセスする際には共通で利用されます。

認証情報は「プロファイル」という単位でまとまっており、プロファイルには名前がついています。プログラムからアクセスするときはこの名前を使用します。

この記事では.NETで共有認証情報ファイルにアクセスする方法を説明します。

この記事の内容はVisual Studio 2019 + VB/C# + .NET Framework 4.8で確認しています。

 

2.共有認証情報ファイルのアクセス例

2−1.前提

NuGet で AWSSDK.Core をインストールします。

VBの場合、プログラム冒頭に次のImports文が必要です。 Imports Amazon.Runtime.CredentialManagement

C#の場合、プログラム冒頭に次のusing文が必要です。 using Amazon.Runtime.CredentialManagement;

 

2−2.ファイルの場所の確認

ファイルの場所がわからなくてもAPI経由で読み書きできますが、実物を確認したい場合などもあるかもしれませんので紹介します。

なお、認証情報が1つも登録されていない場合は、このパスが示す場所には実物としてのファイルは存在しませんが正常です。

VB

Dim credentilasFile As New SharedCredentialsFile
Dim filePath As String = credentilasFile.FilePath

MsgBox(filePath)

C#

var credentilasFile = new SharedCredentialsFile();
string filePath = credentilasFile.FilePath;

//出力 デバッグに表示
System.Diagnostics.Debug.WriteLine(filePath);

 

2−3.プロファイルの列挙

この例では名前とリージョンだけを表示していますが、情報としてはすべて持っています。

VB

Dim credentilasFile As New SharedCredentialsFile
Dim profiles As List(Of CredentialProfile) = credentilasFile.ListProfiles

'表示(参考に各プロファイルの名前とリージョンを表示)
MsgBox(String.Join(vbNewLine, From p In profiles Select p.Name, p.Region))

C#

var credentilasFile = new SharedCredentialsFile();
List<CredentialProfile> profiles = credentilasFile.ListProfiles();

//出力 デバッグにプロファイルを列挙(参考に各プロファイルの名前とリージョンを表示)
profiles.ForEach(p => System.Diagnostics.Debug.WriteLine(p.Name + ", " + p.Region));

 

プロファイル名だけを列挙する ListProfileNames メソッドもあります。

(が、上記のListProfilesメソッドで名前も取得できるのであまり使い道はないように思います。)

VB

Dim credentilasFile As New SharedCredentialsFile
Dim profileNames As List(Of String) = credentilasFile.ListProfileNames

'表示
MsgBox(String.Join(vbNewLine, profileNames))

C#

var credentilasFile = new SharedCredentialsFile();
List<string> profileNames = credentilasFile.ListProfileNames();

//出力 デバッグにプロファイル名を列挙
profileNames.ForEach(name => System.Diagnostics.Debug.WriteLine(name));

 

2−4.プロファイルの取得

VB

Dim credentilasFile As New SharedCredentialsFile
Dim profile As CredentialProfile = Nothing

If credentilasFile.TryGetProfile("SampleProfile", profile) = False Then
    MsgBox("プロファイル名 SampleProfile の取得に失敗しました。")
    Return
End If

'成功時、例としてアクセスキーIDがあれば表示
MsgBox(profile.Options.AccessKey)

C#

var credentilasFile = new SharedCredentialsFile();
CredentialProfile profile = null;

if (credentilasFile.TryGetProfile("SampleProfile", out profile) == false)
{
    System.Diagnostics.Debug.WriteLine("プロファイル名 SampleProfile の取得に失敗しました。");
    return;
}

//成功時、例としてアクセスキーIDがあれば表示
System.Diagnostics.Debug.WriteLine(profile.Options.AccessKey);

 

2−5.プロファイルの新規登録

下記の例では SampleProfile という プロファイル名でアクセスキーIDとシークレットキーとリージョンを新しく登録します。

VB

Dim credentilasFile As New SharedCredentialsFile

Dim credOption As New CredentialProfileOptions
'アクセスキーID
credOption.AccessKey = "AKIAIOSFODNN7EXAMPLE"
'シークレットアクセスキー
credOption.SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

Dim newProfile As New CredentialProfile("SampleProfile", credOption)
'リージョン
newProfile.Region = Amazon.RegionEndpoint.APNortheast1

credentilasFile.RegisterProfile(newProfile)

C#

var credentilasFile = new SharedCredentialsFile();

var credOption = new CredentialProfileOptions();
//アクセスキーID
credOption.AccessKey = "AKIAIOSFODNN7EXAMPLE";
//シークレットアクセスキー
credOption.SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";

var newProfile = new CredentialProfile("SampleProfile", credOption);
//リージョン
newProfile.Region = Amazon.RegionEndpoint.APNortheast1;

credentilasFile.RegisterProfile(newProfile);

 

これを実行すると、共有認証情報ファイルには下記のような情報が書き込まれます。共有認証情報ファイルが存在していなかった場合は自動的に作成されます。

[SampleProfile]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region=ap-northeast-1

 

2−6.プロファイルのコピー・名前変更・削除

上記の例同様に SharedCredentialsFile クラスの下記メソッドで行えます。

コピー CopyProfile

名前変更 RenameProfile

削除 UnregisterProfile

 

3.認証情報を使ってAWSにアクセスする例

例として、共有認証情報ファイルの TestProfile1 という認証情報を使用して S3 バケットを列挙するプログラムを紹介します。

前提としてNuGetで AWSSDK.S3 をインストールする必要があります。

VB

Dim credentilasFile As New SharedCredentialsFile

Dim profile As CredentialProfile = Nothing
If credentilasFile.TryGetProfile("TestProfile1", profile) = False Then
    MsgBox("プロファイル名は存在しません。")
    Return
End If

Dim awsCredentials As Amazon.Runtime.AWSCredentials = Nothing
If AWSCredentialsFactory.TryGetAWSCredentials(profile, credentilasFile, awsCredentials) = False Then
    MsgBox("認証情報の生成に失敗しました。")
    Return
End If

Using client As New Amazon.S3.AmazonS3Client(awsCredentials, profile.Region)
    Dim response = client.ListBuckets()

    '例として全バケット名をカンマで区切って表示します。
    MsgBox(String.Join(", ", From bucket In response.Buckets Select bucket.BucketName))
End Using

C# 

var credentilasFile = new SharedCredentialsFile();

CredentialProfile profile = null;
if (credentilasFile.TryGetProfile("TestProfile1", out profile) == false)
{
    System.Diagnostics.Debug.WriteLine("プロファイル名は存在しません。");
    return;
}

Amazon.Runtime.AWSCredentials awsCredentials = null;
if (AWSCredentialsFactory.TryGetAWSCredentials(profile, credentilasFile, out awsCredentials) == false)
{
    System.Diagnostics.Debug.WriteLine("認証情報の生成に失敗しました。");
    return;
}

using (var client = new Amazon.S3.AmazonS3Client(awsCredentials, profile.Region))
{
    var response = client.ListBuckets();
    //例として全バケット名を表示します。
    response.Buckets.ForEach(bucket => System.Diagnostics.Debug.WriteLine(bucket.BucketName));
}

 

4.ASP.NET Core向けの認証機能の利用

AWSSDKでは上記のほかに AWSOptions というクラスが提供されており、これを使って同じことを実現することもできます。

NuGetで AWSSDK.Extensions.NETCore.Setup をインストールするとこの機能が使えます。

たとえば、AWSOptionsで TestProfile1 プロファイルの認証情報を使って S3 バケットを列挙する例を紹介します。

※VBの場合Imports、C#の場合、UsingでAmazon.Extensions.NETCore.Setup を指定することが前提です。(といってもC#の例は割愛させていただきます。)

VB

Dim options As New AWSOptions
options.Profile = "TestProfile1"
options.Region = Amazon.RegionEndpoint.APNortheast1

Using client = options.CreateServiceClient(Of Amazon.S3.IAmazonS3)()
    Dim response = client.ListBuckets()

    '例として全バケット名をカンマで区切って表示します。
    MsgBox(String.Join(", ", From bucket In response.Buckets Select bucket.BucketName))
End Using

プログラムの行数が少なくなるのは良いのですが、リージョンエンドポイントを別途指定する必要があり、この例では東京リージョン(APNortheast1)がハードコードになってしまっています。

ひょっとするとプロファイルに記載したリージョン情報を使用する方法があるのかもしれませんが、私にはわかりませんでした。

 

この機能はASP.NET Coreを使用しているときには強力なパワーを発揮するはずです。というのもASP.NET Coreの構成プロバイダーと親和性の高い仕組みになっており、設定ファイルにプロファイル情報を記載しておけば、環境によって認証情報を自動的に切り替えられるようになるようだからです。

私は試しておらず、断定的なことが言える状況ではありませんが、ASP.NET Coreの構成プロバイダーと連携する説明が下記URLにあります。

.NET Core を使用した AWS SDK for .NET の設定

https://docs.aws.amazon.com/ja_jp/sdk-for-net/v3/developer-guide/net-dg-config-netcore.html

 

5.参考

AWS 認証情報の設定

https://docs.aws.amazon.com/ja_jp/sdk-for-net/v3/developer-guide/net-dg-config-creds.html

より詳しい説明があります。