使用不记名令牌的 AWS Cognito 身份验证

AWS Cognito authentication with Bearer token

我在 AWS EKS 上的 kubernetes pod 中提供 external-facing REST GET API 服务。我已经为此服务配置了一个 ALB Ingress,它强制执行 Cognito 用户池身份验证。 Cognito 配置为 Authorization code grant 并启用了 openid OAuth 范围。

如果我从浏览器调用我的 REST API,我将被重定向到 Cognito 登录页面。在此处的表单上成功验证后,我可以正常访问我的 REST GET API。这行得通,但这不是我想要实现的。

取而代之的是,在成功通过身份验证后,我需要使用 Bearer 令牌。所以首先我使用 Postman 调用 https://cognito-idp.ap-southeast-1.amazonaws.com 请求:

    "AuthParameters" : {
        "USERNAME" : "<email>",
        "PASSWORD" : "<mypass>",
        "SECRET_HASH" : "<correctly calculated hash>"
    },
    "AuthFlow" : "USER_PASSWORD_AUTH",
    "ClientId" : "<cognito user pool id>"
}

我得到了一个成功的响应,比如:

  "AuthenticationResult": {
    "AccessToken": "...",
    "ExpiresIn": 3600,
    "IdToken": "...",
    "RefreshToken": "...",
    "TokenType": "Bearer"
  },
  "ChallengeParameters": {}
}

在最后一步中,我尝试调用我的 REST API 服务,通过 Authorization HTTP header 值 Bearer <AccessToken> 但我仍然得到 HTML 响应登录页面。

我如何配置 Cognito 以接受我的 Bearer 令牌作为经过身份验证的身份进行此调用?

标准行为

我的目标是一个标准的解决方案,其工作方式如下:

  • API returns 收到有效访问令牌时的数据,或者如果令牌丢失、无效或过期则返回 401 - API 永远不会重定向呼叫者

  • UI 当还没有令牌或从 API

    收到 401 时,它们自己重定向到授权服务器

如果有帮助,我的 OAuth Message Workflow 博客 post 演示了 UI、API 和授权服务器之间的三足行为。

API 网关模式

使用 API 网关设计模式非常好,其中令牌验证是在点击您的 API 之前通过中间件完成的。

但是当令牌被拒绝时中间件必须 return 401 而不是重定向 API 客户端。

APIs 重定向客户端的影响

这可能只适用于 Web UIs,但用户体验会受到限制,因为 UI 在重定向之前没有机会保存用户的数据或位置。

对于移动/桌面应用程序,问题更大,因为 UI 必须使用系统浏览器而不是正常的 UI 视图进行重定向 - 请参阅我的 Quick Start Page 上的屏幕截图。

选择

以下任何一种解决方案都可以:

  • 可能您使用的中间件可以进行不同的配置,使其表现得像一个合适的 API 网关?

  • 或者您可以寻找可执行令牌验证的替代中间件,例如 AWS Lambda 自定义授权方?

  • 或者在 API 的代码中使用 OAuth,就像我的 Sample API

我的偏好

有时我更喜欢编写代码来完成 OAuth 工作,因为它可以在处理自定义声明时提供更好的可扩展性。我的 API Authorization 博客 post 对此有一些进一步的信息。

引用 AWS 对这个主题的支持:“不能使用承载令牌代替会话 cookie,因为在涉及承载令牌的流中会导致生成会话 cookie”。

很遗憾,这个用例到今天还无法实现。