Как создать предварительно подписанный URL-адрес AWS S3, используя подпись версии 4 - PullRequest
0 голосов
/ 25 января 2019

Я создаю предварительно подписанный URL-адрес в классе контроллера API C # .NET Core 2.0, используя AWSSDK.S3 (3.3.31.11). Полученный URL-адрес предназначен для использования клиентским приложением Angular для загрузки файла в корзину S3, зашифрованного с использованием SSE-KMS. Хотя S3Client сообщает, что SignatureMethod - это «HmacSHA256», а SignatureVersion - «4», при попытке загрузить файл с использованием предварительно подписанного URL-адреса появляется сообщение об ошибке «Запросы, указывающие шифрование на стороне сервера с помощью управляемых ключей AWS KMS, требуют подписи AWS». Версия 4. "

S3Client внедряется как зависимость от класса контроллера. Создание экземпляра объекта управляется платформой .NET Core DI с использованием параметров конфигурации в файле config.json:

{
    ...
    "AWS": {
        "Profile": "default",
        "Region": "us-east-1"
    }
    ...
}

Я тестирую предварительно подписанный URL с помощью curl:

curl -H "Content-Type: application/pdf" -H "x-amz-server-side-encryption: aws:kms" -H "x-amz-server-side-encryption-aws-kms-key-id: {kms-key-id}" -k -T "filename.pdf" "https://mybucketname.s3.amazonaws.com/filename.pdf?AWSAccessKeyId={keyid}&Expires={expires}&x-amz-security-token={token}&Signature={signature}"

Я обнаружил, что если я не включаю заголовок «Content-Type», я получаю код ошибки «SignatureDoesNotMatch», а не ошибку «InvalidArgument».

Этот процесс ранее работал при использовании шифрования AES-256 по умолчанию для корзины S3, только при преобразовании в SSE-KMS я столкнулся с этой проблемой.

// Controller Class
private readonly IAmazonS3 _s3Client;

public MyController(IAmazonS3 s3Client)
{
    _s3Client = s3Client;
}

[HttpPost]
public async Task<IActionResult> GetPreSignedUrl([FromBody] FileInfoDto fileInfo)
{
    ...
    GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
    {
        BucketName = bucketName, 
        Key = fileInfo.name, 
        Verb = HttpVerb.PUT,
        ContentType = fileInfo.contentType, 
        Expires = DateTime.Now.AddMinutes(5),
        ServerSideEncryptionKeyManagementServiceKeyId = keyId, 
        ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
    };

    try
    {
        url = _s3Client.GetPreSignedURL(request);
    }
    ...
}

// Startup Class
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddDefaultAWSOptions(_config.GetAWSOptions());
    services.AddAWSService<IAmazonS3>();
    ...
}

При загрузке файла с использованием curl и предварительно подписанного URL-адреса, созданного методом контроллера, я получаю код ошибки ответа «InvalidArgument» и сообщение «Запросы, указывающие шифрование на стороне сервера с помощью управляемых ключей AWS KMS, требуют подписи AWS Версия 4. " Однако S3Client сообщает, что SignatureVersion имеет значение «4».

Что я должен делать по-другому, чтобы сгенерировать предварительно подписанный URL-адрес с использованием подписи версии 4?

1 Ответ

0 голосов
/ 27 января 2019

Несмотря на то, что s3Client сообщает о версии подписи как «4», следующая строка, добавленная к методу ConfigureServices, решает проблему и приводит к созданию предварительно подписанного URL-адреса, соответствующего версии подписи 4:

AWSConfigsS3.UseSignatureVersion4 = true;

Сгенерированный предварительно подписанный URL-адрес выглядит следующим образом:

https://mybucketname.s3.amazonaws.com/filename.pdf?X-Amz-Expires=1800&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={credential}/20190127/us-east-1/s3/aws4_request&X-Amz-Date={date}&X-Amz-SignedHeaders=content-type;host;x-amz-server-side-encryption&X-Amz-Signature={signature}
...