如何使用node.js解码和验证AWS SigV4请求的签名



我的设置

我有一个到api网关端点的请求,该端点使用AWS Sigv4 签名

请求的标题看起来像这个

{
"host": "localhost:3100",
"connection": "keep-alive",
"content-length": "78",
"sec-ch-ua": ""Google Chrome";v="87", " Not;A Brand";v="99", "Chromium";v="87"",
"sec-ch-ua-mobile": "?0",
"authorization": "AWS4-HMAC-SHA256 Credential=ASIA2DP7X6SIMAVM65UJ/20201223/ap-southeast-1/execute-api/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=edc00f240870f9f1e0e8fc66f1ef98c3dac4bfbc1f1a8ab36dacc4b68b32b2a3",
"content-type": "application/json",
"accept": "*/*",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
"x-amz-security-token": "IQoJb3JpZ2luX2VjEAwaDmFwLXNvdXRoZWFzdC0xIkYwRAIgF+XX6C0F+P5XgVewIKXVvPt+ahQkHVOj6rHPC5nzAaQCIEq8ldeNs5vv1xvt76Fl+osd/cPZZTbjhrDCYJqeyy7mKqEGCLX//////////wEQABoMNjk0NzEwNDMyOTEyIgyGVcLvP4mHok3ZyIQq9QUBEp/j5AeqnRV6D3IEl4dCiLUhdJaTLX+8JdBinM3eiTSyAlOQUucsNStudFc4qMVPztBnBFpx7diDDjh9FqM3Wx+Xs+qTfWIP6s3dgZioPh+M526e7SUiI4aoSjBhmDzrzAgoVvI5azbNCl3nvfONC7uvGzQC8zZc/W+4/1icnny6vuaooZnQUZn3t8GHasfepVJ1zcDjUUN+76cw+txiuBB7mzoFhnhfvEEDdN1aHgZoMUAYWUhvlAq+gLZa8CdwX4mThkpZodf6t04n8QLkqRmUb1KQd0sG4Vux6OzXbO+j3mtgasbHEtxS7kM2ZY++ZYG9A5tyNhXSxfjtk6HkpaEi5WOHTfH94fk8/VG5gmPj19z48uBoxa1ct4jThsrg81kmcrC00gbNwrXqHh4l0/4ufAvfuO8MWxvHqkXks6U2WU4rzu0QVhSg2cIxHP7mH1FQyYAA31D1Pz23QpYB45o6TppSa/j8VmzsYZ8NCn+fwuVeP7RCxzic0YWdbKc1d5Ts0ID9M8Pg+d/0CgJSVfrlBD0QOytIjLbhvFAwkSJeiDk/Mw6rI4nRNXtQy2EgoUsspaTo4buePIr/eflEUm1dpAEu33CX0TzUhszFmFmq8lLFlQUEl1VKVvw6Jdz0x8uhX2vdT33ixnpavQpWXA3eKu4RVuzSIyvat+OhQX7ywIzpyhbcSsIQR+zq62RfM7RDd6iNG41tzBPNk/dQpJhBmMJdqQE8fX4Uw2PgJaEGEyyFRpvYMT2OtMG+2CUNj6FiyTSCsa00H+ZKR/knXRXhnyHmOdDsQDbbgPjdr5wougoQTxx5BPk9/6lOSXdsGhg9oT1FkOsGOIZgoaaRA+cRvMAzMERQd4hAboeqGmuoP+7dAwgE4QcwChx+vK3kdCWQ8MRfeYs3MQTWvd4R9fx0VOeCfza0nYBEqqsfBs2YBCDYPHJl9nNKU8xrspn1kDnQ03m3P1hwM81FqmuNXpZaTiUnDjHj+sWSDE0e/6f023UzMNWKi/8FOogCS99u4WOLBdmKnHFptz2yH8fM9ewGniGeSE6J40rRxRmGKjfoBiipYeY2XQgRE5TLzxO5RlqRxgcYQ+Y4fddYR66hjQSi0YJPe30aPNgXNolvmabeh5mi17NEeeNklauHeuM1Te81N8dnZSYiubxtpiwbb3EyTZhmM/mi3w22hfQcz+ufrtwZYjBlzCYc+szynuRS5mbS4HnwPhIgeyZyrpPWW/mDwXjWPnV437Cp2654UZkaWi0/HTHuwcnNs0JEOZ81cq9LXwqCUYqyjHzWf25JSTn06q/kVVhW8RZgULDabEcvl3DKgG6dau+dK2sTbVwmOKGHw7lsx2RrCmbA1gqjscOb9zt3",
"x-amz-date": "20201223T041933Z",
"origin": "http://localhost:3000",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://localhost:3000/",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en,en-US;q=0.9"
}

当我运行向我的api端点添加IAM授权程序时,我看到这个签名由AWS验证,如下所示

{
"identity": {
"cognitoIdentityPoolId": "ap-southeast-1:776d43fa-1a9a-4911-b06c-8a6580ae1bcd",
"accountId": "694710432912",
"cognitoIdentityId": "ap-southeast-1:053f57cd-6a21-486d-b4b5-5fd27e17420b",
"caller": "AROA2DP7X6SILQ2KYY6MJ:CognitoIdentityCredentials",
"sourceIp": "103.252.202.229",
"principalOrgId": null,
"accessKey": "ASIA2DP7X6SIGUWRHSN3",
"cognitoAuthenticationType": "unauthenticated",
"cognitoAuthenticationProvider": null,
"userArn": "arn:aws:sts::694710432912:assumed-role/Cognito_MyPoolUnauth_Role/CognitoIdentityCredentials",
"userAgent": "PostmanRuntime/7.26.8",
"user": "AROA2DP7X6SILQ2KYY6MJ:CognitoIdentityCredentials"
}
}

我的问题

我可以使用nodejs(typescript(自己验证签名吗?任何一个脚本的例子,解码这样的头产生这样的身份将是真棒。

我为什么要这么做

用于在本地模拟我的api和授权逻辑。此外,我可能想在我的网关中尝试使用自定义lambda授权器,而不是默认的AWS IAM授权器(以便对我的授权逻辑进行更多控制(。

对您的问题的回答有点复杂。简而言之:是的,你可以!更长的答案是:技术上是可能的,但在实践中不是!

签名过程非常直接。这里有完整的记录。要验证签名(authorization标头(,您只需要重复该过程并检查结果是否等于标头中的签名。问题是:要重复该过程,必须有ACCESS_KEY_IDSECRET_ACCESS_KEY。您可以使用AWS主体访问密钥和机密使其工作。但您使用的是Cognito身份池,在这种情况下,您将永远无法访问SECRET_ACCESS_KEY

如果你的意图只是在本地模仿你的逻辑,它就会起作用。但如果你允许的话,我建议你不要在家里尝试。如果您的目的只是模拟逻辑,那么简单的路径是绕过API网关,并将一个关于API网关事件格式的模拟对象直接发送到具有;解码/模拟";身份令牌。

另一件事:如果你使用Cognito身份池(你正在使用的(转到Custom Authorizer,你将需要手动执行许多任务,比如验证签名和解码身份令牌(我相信这是x-amz-security-token的内容(。总之,您需要手动完成IAM授权人执行的所有任务。

相关内容

  • 没有找到相关文章

最新更新