0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Salesforce記録③:salesforceからAWSにアクセスする方法について(202406)

Last updated at Posted at 2024-08-07

AWS S3 にアクセスする際、異なる認証方法を選択できます。具体的なユースケースとセキュリティ要件に応じて、以下の2つの主要な方法があります。

1. AWS SDK と IAM ユーザー/ロールを使用したアクセス

AWS SDK と IAM ユーザーまたはロールを使用する方法は、一般的かつ安全な方法です。この方法では通常、アクセスキー(Access Key)とシークレットキー(Secret Key)が必要で、適切な権限を得るために IAM ロールを指定することもあります。

利点:

詳細な権限制御:IAM ポリシーを通じて、誰がどのリソースにアクセスできるか、どの操作を実行できるかを細かく制御できます。
高いセキュリティ:ロールや一時的なセキュリティ認証情報(例:STS)を使用してセキュリティを強化できます。
複雑な権限要件やマルチユーザー環境に適しています。
方法①

下記のやり方はこちら側が検証されていませんので。一旦記録します

public class AwsS3Access {
    private static final String ACCESS_KEY = 'YOUR_ACCESS_KEY';
    private static final String SECRET_KEY = 'YOUR_SECRET_KEY';
    private static final String REGION = 'YOUR_REGION';
    
    public void listS3Buckets() {
        String service = 's3';
        String host = 's3.' + REGION + '.amazonaws.com';
        String endpoint = 'https://' + host + '/';
        
        // Create date for headers and the credential string
        Datetime now = Datetime.now();
        String amzDate = now.formatGmt('yyyyMMdd\'T\'HHmmss\'Z\'');
        String dateStamp = now.formatGmt('yyyyMMdd'); // Date w/o time, used in credential scope

        // ************* TASK 1: CREATE A CANONICAL REQUEST *************
        String method = 'GET';
        String canonicalUri = '/';
        String canonicalQuerystring = '';
        String canonicalHeaders = 'host:' + host + '\n' + 'x-amz-date:' + amzDate + '\n';
        String signedHeaders = 'host;x-amz-date';
        String payloadHash = EncodingUtil.convertToHex(Crypto.generateDigest('SHA-256', Blob.valueOf('')));
        String canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\n' + signedHeaders + '\n' + payloadHash;

        // ************* TASK 2: CREATE THE STRING TO SIGN *************
        String algorithm = 'AWS4-HMAC-SHA256';
        String credentialScope = dateStamp + '/' + REGION + '/' + service + '/' + 'aws4_request';
        String stringToSign = algorithm + '\n' + amzDate + '\n' + credentialScope + '\n' + EncodingUtil.convertToHex(Crypto.generateDigest('SHA-256', Blob.valueOf(canonicalRequest)));

        // ************* TASK 3: CALCULATE THE SIGNATURE *************
        Blob signingKey = getSignatureKey(SECRET_KEY, dateStamp, REGION, service);
        String signature = EncodingUtil.convertToHex(Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), signingKey));

        // ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
        String authorizationHeader = algorithm + ' ' + 'Credential=' + ACCESS_KEY + '/' + credentialScope + ', ' + 'SignedHeaders=' + signedHeaders + ', ' + 'Signature=' + signature;

        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod(method);
        req.setHeader('x-amz-date', amzDate);
        req.setHeader('Authorization', authorizationHeader);

        Http http = new Http();
        HttpResponse res = http.send(req);

        if (res.getStatusCode() == 200) {
            System.debug('Response: ' + res.getBody());
        } else {
            System.debug('Error: ' + res.getStatus() + ' ' + res.getBody());
        }
    }

    private static Blob getSignatureKey(String key, String dateStamp, String regionName, String serviceName) {
        Blob kDate = Crypto.generateMac('HMACSHA256', Blob.valueOf(dateStamp), Blob.valueOf('AWS4' + key));
        Blob kRegion = Crypto.generateMac('HMACSHA256', Blob.valueOf(regionName), kDate);
        Blob kService = Crypto.generateMac('HMACSHA256', Blob.valueOf(serviceName), kRegion);
        Blob kSigning = Crypto.generateMac('HMACSHA256', Blob.valueOf('aws4_request'), kService);
        return kSigning;
    }
}


方法➁

指定ログイン情報を作成し、AWS S3 APIをアクセス
APEX側コードが減らす

//APEX
public class C_AWSS3Connecter {

    public static HTTPResponse fileUpload(String contentType,Blob dataBlob,String kmsKeyId,String filename){
        
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:AWSConnectTest/'  + fileName);
        req.setHeader('Content-Type',contentType);
        req.setBodyAsBlob(dataBlob);
        req.setMethod('PUT');
        Http http = new Http();
        HTTPResponse res = http.send(req);
        return res;
    }
}

AWSConnectTestは指定ログイン情報の名前
指定ログイン情報の作成は下記のblogを参照してください
https://qiita.com/shinsaka/items/a1e6dce886697f175af9

リンク

Salesforceヘルプ:指定ログイン情報と外部ログイン情報
https://help.salesforce.com/s/articleView?id=sf.nc_named_creds_and_ext_creds.htm&type=5
Amazon S3 APIリファレンス
https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html
従来機能で試した過去のポスト
https://qiita.com/shinsaka/items/f11cf54373c4fe49b0a9
Winter '23から変更になったということのようですね。
https://developer.salesforce.com/blogs/2022/10/announcing-the-next-generation-of-named-credentials

2. API Gateway *REST API を使用したアクセス

x-api-key を使用する方法は、通常 API Gateway を経由した REST API に対して使われます。API Gateway は S3 へのリクエストのフロントエンドとして機能し、x-api-key の設定を通じて認証を行うことで、アクセスを簡略化します。

利点:
簡単なアクセス制御:API Gateway はリクエストのフロントエンドとして機能し、x-api-key を設定することで簡単に認証を行えます。
管理が容易:API Gateway を利用した公開アクセスやサードパーティアプリケーションに適しています。
柔軟性:API Gateway は他の認証方法(例:Cognito ユーザープール)とも統合可能です。
方法①

ApexでURL、Headerを組み合わせて、requestする(検証済み、OK)

HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.example.com/your-endpoint');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setHeader('x-api-key', 'YOUR_API_KEY_HERE');

// リクエストボディを構築し、リクエストを送信

方法➁

指定ログイン情報を作成し、AWS APIをアクセス(検証されていない,できると思います)
image.png

image.png

image.png

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AWSMasterAPI/');
req.setMethod('GET');

Http http = new Http();
HttpResponse res = http.send(req);
System.debug(res.getBody());

最後の最後,1でも、2でも salesforceにRemote Siteの設定が必要です。

リモートサイトの設定
image.png

3. Amazon Cognito を使用したアクセス

これはしばらく紹介しない

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?