【发布时间】:2021-12-13 11:47:17
【问题描述】:
我正在尝试将数据从 SQL 发送到我的 kinesis 流,但我只能恢复错误。
{
"__type": "InvalidSignatureException",
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
}
我的密钥和秘密是正确的,因为我在 Postman 中进行了成功的测试。
这是我创建身份验证标头的函数...
ALTER FUNCTION [dbo].[CreateAuth]
(
@awsAccessKey NVARCHAR(MAX),
@awsSecretKey NVARCHAR(MAX),
@content NVARCHAR(MAX),
@dateTime Datetime
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @awsRegion NVARCHAR(MAX) = 'eu-west-2';
DECLARE @awsService NVARCHAR(MAX) = 'kinesis';
DECLARE @timeStamp NVARCHAR(16) = FORMAT(@dateTime, 'yyyyMMddTHHmmssZ');
DECLARE @scope NVARCHAR(MAX) = FORMAT(@dateTime, 'yyyyMMdd') + '/'+@awsRegion+'/'+@awsService+'/aws4_request'
DECLARE @x_amz_content_sha256 NVARCHAR(MAX);
DECLARE @hexbin VARBINARY(max) = HASHBYTES('SHA2_256 ',@content);
SET @x_amz_content_sha256 = LOWER(CONVERT([varchar](512), @hexbin,2))
-- CANONICAL REQUEST
DECLARE @CanonicalRequest NVARCHAR(MAX) = '';
-- HTTP verb
SET @CanonicalRequest += 'POST' + CHAR(13)
-- URL
SET @CanonicalRequest += 'kinesis.eu-west-2.amazonaws.com' + CHAR(13)
-- QUERYSTRING (must be sorted alphbetically)
SET @CanonicalRequest += '' + CHAR(13)
-- HEADERS (must be sorted alphbetically)
SET @CanonicalRequest += 'content-type:application/x-amz-json-1.1' + CHAR(13)
SET @CanonicalRequest += 'host:kinesis.eu-west-2.amazonaws.com' + CHAR(13)
SET @CanonicalRequest += 'x-amz-content-sha256:' + @x_amz_content_sha256 + CHAR(13)
SET @CanonicalRequest += 'x-amz-date:' + @timeStamp + CHAR(13)
SET @CanonicalRequest += 'x-amz-target:' + 'Kinesis_20131202.PutRecord' + CHAR(13)
-- SIGNED HEADERS
DECLARE @signedheaders NVARCHAR(MAX) = 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target'
SET @CanonicalRequest += @signedheaders + CHAR(13)
-- HASHED PAYLOAD
SET @CanonicalRequest += @x_amz_content_sha256
DECLARE @CanonicalRequestHexbin VARBINARY(max) = HASHBYTES('SHA2_256 ',@CanonicalRequest);
-- STRING TO SIGN
DECLARE @stringToSign NVARCHAR(MAX) = '';
SET @stringToSign += 'AWS4-HMAC-SHA256' + CHAR(13)
SET @stringToSign += @timeStamp + CHAR(13)
SET @stringToSign += @scope + CHAR(13)
SET @stringToSign += LOWER(CONVERT([varchar](512), @CanonicalRequestHexbin,2))
-- CALCULATE SIGNATURE
DECLARE @DateKey VARBINARY(64);
DECLARE @DateRegionKey VARBINARY(64);
DECLARE @DateRegionServiceKey VARBINARY(64);
DECLARE @SigningKey VARBINARY(64);
DECLARE @Signature VARBINARY(64);
SET @DateKey = dbo.HMAC('SHA2_256',CONVERT(VARBINARY(MAX), 'AWS4'+@awsSecretKey),CONVERT(VARBINARY(MAX),FORMAT(@dateTime, 'yyyyMMdd')))
SET @DateRegionKey = dbo.HMAC('SHA2_256', @DateKey, CONVERT(VARBINARY(MAX),@awsRegion))
SET @DateRegionServiceKey = dbo.HMAC('SHA2_256', @DateRegionKey, CONVERT(VARBINARY(MAX),@awsService))
SET @SigningKey = dbo.HMAC('SHA2_256', @DateRegionServiceKey, CONVERT(VARBINARY(MAX),'aws4_request'))
SET @Signature = dbo.HMAC('SHA2_256',@SigningKey,CONVERT(VARBINARY(MAX),@stringToSign));
--BUILD Authorization
DECLARE @AuthValue NVARCHAR(MAX) = '';
SET @AuthValue += 'AWS4-HMAC-SHA256 Credential=' + @awsAccessKey + '/'+ @scope
SET @AuthValue += ',SignedHeaders=' + @signedheaders
SET @AuthValue += ',Signature=' + LOWER(CONVERT([varchar](512), @Signature,2))
RETURN @AuthValue
这是对 kinesis 的调用
-- Open the connection.
EXEC @ret = sp_OACreate 'MSXML2.ServerXMLHTTP', @token OUT;
IF @ret <> 0 RAISERROR('Unable to open HTTP connection.', 10, 1);
-- Send the request.
EXEC @ret = sp_OAMethod @token, 'open', NULL, 'POST', @url, 'false';
SET @auth = dbo.CreateAuth('MYACCESSKEY','MYSECRETKEY',@postData, @datetime)
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'Authorization', @auth
PRINT @auth
PRINT ''
DECLARE @hexbin VARBINARY(max) = HASHBYTES('SHA2_256 ',@postData); --hash data
DECLARE @x_amz_content_sha256 NVARCHAR(MAX) = LOWER(CONVERT([varchar](512), @hexbin,2)) -- get hex of hashed data
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'content-type', @contentType;
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'host', 'kinesis.eu-west-2.amazonaws.com';
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-content-sha256', @x_amz_content_sha256;
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-date', @xAmzDate;
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-target', @xAmzTarget;
EXEC @ret = sp_OAMethod @token, 'send', NULL, @postData;
-- Handle the response.
EXEC @ret = sp_OAGetProperty @token, 'status', @status OUT;
EXEC @ret = sp_OAGetProperty @token, 'statusText', @statusText OUT;
EXEC @ret = sp_OAGetProperty @token, 'responseText', @responseText OUT;
-- Show the response.
PRINT 'Status: ' + @status + ' (' + @statusText + ')';
PRINT 'Response text: ' + @responseText;
-- Close the connection.
EXEC @ret = sp_OADestroy @token;
IF @ret <> 0 RAISERROR('Unable to close HTTP connection.', 10, 1);
我使用的 HMAC 函数就是这个...https://gist.github.com/rmalayter/3130462 我已经使用https://codebeautify.org/验证了使用 SHA2_256 和 HMAC 函数产生的结果是正确的
我很确定我所做的一切都是根据...https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html 和 https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
我不知道下一步该做什么。
【问题讨论】:
-
我会记录整个发布请求(假设您使用的库可以这样做)并将其与您通过 Postman 成功发送的请求进行比较。
-
dbo.CreateAuth函数有许多硬编码值,这些值可能与调用代码使用的变量不同,例如:content-type、host和x-amz-target。为什么这些值不作为参数传递给函数? -
另外,
dbo.CreateAuth函数似乎没有使用正确的CanonicalURI值。根据Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4) 页面,它应该是主机名之后的绝对URI 部分,直到?分隔查询字符串。 UDF 中的代码仅使用硬编码的主机名kinesis.eu-west-2.amazonaws.com。 -
感谢 cmets。我已按照建议删除了硬编码。
-
CanonicalRequest 现在看起来像 ` POST / content-type:application/x-amz-json-1.1 host:kinesis.eu-west-2.amazonaws.com x-amz-content-sha256:3d2457d22cb5bb26de14e45c97e2a22d49b68887cf6f1a2b2757f9d9a6 X-AMZ-DATE:20211214T094829Z X-AMZ-target:Kinesis_20131202.putRecord内容类型;主机; X-AMZ-Content-SHA256; X-AMZ-TATER-SHA256; X-AMZ-Target 3D2457D22CB5BB26DE14E45C97E2A22D49B6887CF6F1A2B2757F9D9A6A8E6C4`和我的StringTosign看起来像“AWS4 -HMAC-SHA256 20211214T094829Z 20211214/eu-west-2/kinesis/aws4_request 51debfe0372257843589cef3c6bcd278b4ffe695360063729848991474b3b29a`
标签: sql-server amazon-web-services amazon-kinesis