1

我的设置

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

请求的标头看起来像这样

{
  "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"
}

当我运行将 IAM 授权者添加到我的 api 端点时,我看到此签名由 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(打字稿)自己验证签名吗?任何将此类标头解码以产生此类身份的脚本示例都很棒。

为什么我想这样做

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

4

1 回答 1

1

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

签名过程非常简单。它完全记录在这里。要验证签名(authorization标头),您只需重复该过程并检查结果是否等于标头中的签名。问题是:要重复该过程,您必须拥有ACCESS_KEY_ID SECRET_ACCESS_KEY。您可以使其与 AWS 委托人访问密钥和密钥一起使用。但是您使用的是 Cognito 身份池,在这种情况下,您将永远无法访问SECRET_ACCESS_KEY.

如果您的意图只是在本地模拟您的逻辑,它将起作用。但如果你允许我,我建议不要在家里尝试这个。如果您的目的只是为了模拟逻辑,那么简单的方法是绕过 API 网关,并使用“解码/模拟”身份令牌直接向函数发送一个符合 API 网关事件格式的模拟对象。

另一件事:如果您使用 Cognito 身份池(您正在使用的)迁移到自定义授权器,您将需要手动执行许多任务,例如验证签名和解码身份令牌(我相信它是 的内容x-amz-security-token)。总之,您需要手动执行 IAM 授权方执行的所有任务。

于 2020-12-23T18:01:27.770 回答