将 Cognito 与 IAM 和 Amplify 结合使用进行授权

Authorization using Cognito with IAM and Amplify

我正在尝试创建一个应用程序,用户可以在其中登录,然后根据他们的角色访问某些 api 资源。

用户被移动到用户池中的组中,每个组都有一个自定义 IAM 角色。

我曾使用 CLI 工具来创建身份验证、api 网关和 lambda 函数。 这是在 amplify

中设置的 API
? Please select from one of the below mentioned services: REST
? Please select the REST API you would want to update standardApi
? What would you like to do Update path
? Please select the path you would want to edit /std
? Provide a path (e.g., /book/{isbn}): /std
? Choose a Lambda source Use a Lambda function already added in the current Ampl
ify project
? Choose the Lambda function to invoke by this path standardFunction
? Restrict API access Yes
? Restrict access by? Individual Groups
? Select groups: standard
? What kind of access do you want for standard users? create, read, update, dele
te
Successfully updated resource

在控制台中检查时,资源按预期创建。

问题在于,当我尝试调用 API 时,我收到了 MissingAuthenticationTokenException

这是电话

const apiName = 'standardApi';
const path = '/std';
const myInit = {
    headers: {},
    response: false
};
API.get(apiName, path, myInit)
.then(response => {
    console.log(response);
})
.catch(error => {
    console.log(error.response);
});

我的理解是 Amplify sdk 应该使用正确的身份验证值自动填充请求 headers。

如果我尝试手动传递访问令牌,

headers: {
    Authorization: (await Auth.currentSession()).getIdToken().getJwtToken()
},

我收到 IncompleteSignatureException,消息为

Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.

正在尝试

headers: {
    Authorization: `Bearer ${(await Auth.currentSession()).getIdToken().getJwtToken()}
},

导致没有消息的 IncompleteSignatureException。

其他帖子建议端点可能未正确指定,如果我从控制台的 api 中删除 auth 并重新部署,端点将按预期命中。此外,如果我使用 cognito 用户池创建自定义授权方,则在登录时会正确命中端点并传递不记名令牌。

只是 IAM 案例不起作用。

检查 ID 令牌表明正在传递正确的用户名、组和角色。

"cognito:groups": Array [ "standard" ]
"cognito:preferred_role": "arn:aws:iam::************:role/region-*_*********-standardGroupRole"
"cognito:roles": Array [ "arn:aws:iam::************:role/region-*_*********-standardGroupRole"]
"cognito:username": "0a******-****-****-****-************"

正在使用 auto-generated aws-exports 文件完成 Amplify 配置步骤,该文件包含用户池、身份池和客户端应用程序的正确条目。

我知道这可能会有点晚,但我只是想做你想做的事情。

这是我必须做的才能让它发挥作用:

  • 在您的 UI 中包含身份验证组件,这样您的 API 调用将使用经过身份验证的用户的凭据完成。
  • 一旦您通过 Cognito 的身份验证(使用属于您指定的组的用户),请务必执行 API 调用。
  • 不要包含任何 'Authorization' header(我查看了代码,发现在设置授权 header 时没有生成 AWS 签名)。
  • 确保您的 lambda 代码 returns CORS headers(因此我从 CloudFront 收到了 InternalServerErrorException)。

执行此操作后,我可以在我的浏览器的开发人员控制台中看到请求已签名并且具有 API 网关执行的 IAM 授权验证所需的所有 headers。

我希望这个云对某些人有用,因为我花了很多时间才弄明白。

此致, 安德烈斯·利亚诺斯