0

我正在尝试从 Salesforce 访问 S3 存储桶/对象详细信息。我浏览了 AWS 文档并尝试生成 V4 签名。似乎我缺少一些参数,因此出现以下错误:

我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。

下面是代码片段:

public class AWSIntegrationS31{   

private String accessKeyID = 'SampleAccessKey';
private String secretAccessKey = 'SECRET Key';
private String region = 'ap-south-1'; 
private String service = 's3';
String host = 's3.ap-south-1.amazonaws.com';
private String httpMethodName;
private String endpoint = 'https://s3.ap-south-1.amazonaws.com'; //test123sfdc1.s3.ap-south-1.amazonaws.com
String content_type = 'application/json'; //'application/x-amz-json-1.0';    

private String currentDate;             
String expires = '86400'; //24 hrs
String signed_headers;
String S3_signed_headers;
String range = 'bytes=0-9';

String TimeStamp;
String t;    
String request_parameters;
String canonical_headers;
String amz_date;
String date_stamp;

public AWSIntegrationS31(){       
    Datetime now = Datetime.now();
    TimeStamp =  now.formatGmt('yyyyMMdd')+'T'+now.formatGmt('HHmmss')+'Z';
    t = EncodingUtil.urlEncode(TimeStamp, 'UTF-8');
    currentDate = now.formatGmt('yyyyMMdd');               
    amz_date = TimeStamp;
    date_stamp = currentDate;

    request_parameters =  '';
}

public HttpResponse connectAWS(){

    // ******************************* 1. Cannoncial Request *******************************

    /* Step 1.1 Start with the HTTP request method (GET, PUT, POST, etc.), followed by a newline character. */                
    httpMethodName = 'GET';

    /* Step 1.2 Add the canonical URI parameter, followed by a newline character. */        
    String canonical_uri = '/';

    /* Step 1.3 Add the canonical query string, followed by a newline character. */
    String canonical_querystring = request_parameters;

    String x_amz_content_sha256= 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';

    /* Step 1.4 Add the canonical headers, followed by a newline character. */        
    canonical_headers = 'host:' + host + '\n' + 'x-amz-content-sha256:' + x_amz_content_sha256 + '\n' + 'x-amz-date:' + amz_date  + '\n';         

    /* Step 1.5 Add the signed headers, followed by a newline character. */
    signed_headers = 'host;x-amz-content-sha256;x-amz-date'; //;x-amz-target';               
    //signed_headers = 'host;x-amz-content-sha256;x-amz-date';               

    /* Step 1.6 Create payload hash. */
    String payload_hash = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'; //'UNSIGNED-PAYLOAD'; // //EncodingUtil.convertToHex(Crypto.generateDigest('SHA256', Blob.valueOf(''))).toLowerCase(); 

    System.debug('payload_hash....'+payload_hash);

    /* Step 1.7: Combine elements to create canonical request. */
    String canonical_request = httpMethodName + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash;       
    System.debug('canonical_request...'+canonical_request);

    // ******************************* 2. Create string to Sign  *******************************

    String algorithm = 'AWS4-HMAC-SHA256';
    String credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request';

    String hashRequest = EncodingUtil.convertToHex(Crypto.generateDigest('SHA256', Blob.valueOf(canonical_request))).toLowerCase(); 
    System.debug('hashRequest...'+hashRequest);
    String string_to_sign = algorithm + '\n' +  amz_date + '\n' +  credential_scope + '\n' +  hashRequest;

    System.debug('Request Parameter....'+request_parameters);
    System.debug('StringTosign....'+string_to_sign);

    // ******************************* 3. Calculate Signature  *******************************

    /* Step 3.1. Generate signing key */
    Blob signatureKey  = Crypto.generateMac('hmacSHA256', Blob.valueOf('aws4_request'),
        Crypto.generateMac('hmacSHA256', Blob.valueOf(service),
            Crypto.generateMac('hmacSHA256', Blob.valueOf(region),
                Crypto.generateMac('hmacSHA256', Blob.valueOf(date_stamp), Blob.valueOf('AWS4'+secretAccessKey))
            )
        )
    );

    System.debug('signatureKey..'+signatureKey);
    System.debug('signatureKey..2...'+EncodingUtil.base64Encode(signatureKey));

    Blob mac = Crypto.generateMac('hmacSHA256', Blob.valueof(string_to_sign),signatureKey); 
    System.debug('mac...'+mac);

    /*Step 3.2. Encode signature (byte[]) to Hex */        
    String macUrl = EncodingUtil.convertToHex(mac);        
    System.debug('macURL...1...'+EncodingUtil.convertToHex(mac));

    // ******************************* 4. Add Signing Information to the Request  *******************************

    String authorization_header = algorithm + ' ' + 'Credential=' + accessKeyID + '/' + credential_scope + ',' +  'SignedHeaders=' + signed_headers + ',' + 'Signature=' + macUrl;
    System.debug('authorization_header ..'+authorization_header );

    // ******************************* 5. Send Request to S3 *******************************  

    HttpRequest request = new HttpRequest();     
    request.setMethod('GET');
    request.setEndpoint(endpoint); 
    //request.setBody(request_parameters);
    request.setHeader('Content-Type',content_type);
    request.setHeader('X-Amz-Date',amz_date);
    request.setHeader('x-amz-content-sha256', 'UNSIGNED-PAYLOAD');

    request.setHeader('Authorization', authorization_header);
    Http http = new Http(); 
    HttpResponse res = http.send(request);
    System.debug(res);
    System.debug(res.getBody());
    return res;

}

}

4

0 回答 0