【问题标题】:Is it possible to get temporary credentials via boto3 with aws cognito google oauth access_token?是否可以使用 aws cognito google oauth access_token 通过 boto3 获取临时凭证?
【发布时间】:2021-04-10 16:30:14
【问题描述】:

我想通过 AWS Cognito(Google 身份提供商)授权用户对 API 的请求。目前我可以从 aws 接收 JWT 令牌(id_token 和 access_token)并授权请求,但我是使用 id_token 而不是 access_token 来完成的。但是有些文章说使用 id_token 来授权 API 请求是一种不好的做法(从前端的 headers 中发送 id_token),我应该使用 access_token。是否可以用 access_token 而不是 id_token 做同样的事情?

import boto3

id_token = get_token_from_headers(headers)

identity_client = boto3.client('cognito-identity')

id_response = identity_client.get_id(
     AccountId='account_id',
     IdentityPoolId='identity_pool_id',
     Logins={
         'cognito-idp.us-west-1.amazonaws.com/us-west-1_blabla: id_token'
     }
 )

response = identity_client.get_credentials_for_identity(
     IdentityId=id_response['IdentityId'],
     Logins={
         'cognito-idp.us-west-1.amazonaws.com/us-west-1_blabla': id_token
     })


access_key = response['Credentials']['AccessKeyId']
secret_key = response['Credentials']['SecretKey']
session_key = response['Credentials']['SessionToken']

看起来它能够从 assume_role_with_web_identity link to docs 获取带有 access_token 的临时凭证,但文档说此方法的 WebIdentityToken 参数仅在 oAuth 提供商是 Amazon 和 Facebook 的情况下接受 access_token

【问题讨论】:

    标签: python amazon-web-services boto3 amazon-cognito


    【解决方案1】:

    似乎通过 AWS Cognito 身份池检索临时凭证总是通过身份令牌:https://docs.aws.amazon.com/cognito/latest/developerguide/google.html

    成功的身份验证会生成一个包含 id_token 的响应对象,Amazon Cognito 使用它来对用户进行身份验证并生成唯一标识符

    我认为这不会破坏安全性,因为 AWS Cognito 身份池专门设置为使用身份令牌,您可以根据返回的身份令牌配置将分配给临时 AWS 凭证的 IAM 角色你来自身份池:https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.htmlhttps://docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html

    但是,您不应将 Google id_token 发送到获取 AWS 临时凭证的(我假设基于 AWS)API。 相反,您应该在客户端获取 AWS 临时凭证,然后使用 Signature V4 标头调用 AWS 资源。

    或者,如果您的 API 可以承担 AWS 服务角色并且您不需要获取临时 AWS 凭证,则可以使用 AWS Cognito 用户池。他们还支持 Google 身份提供商 - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-social-idp.html

    对于托管在 EC2 上的 API,您无法真正使用 Cognito 身份池生成的安全凭证,因为您无法通过 IAM 策略有效控制 EC2 HTTP(S) 端口访问。但是,您的 EC2 托管应用程序可以接受 Google id_token 并对其进行验证 - https://developers.google.com/identity/sign-in/web/backend-auth#:~:text=After%20you%20receive%20the%20ID,to%20verify%20the%20token's%20signature。没有理由使用身份池,并且通过 Google id_token 验证 API 访问没有安全风险,因为令牌是由 Google 签名的,您可以在您的 API 上进行验证。您还可以使用 Cognito 用户池:您从客户端上的用户池中检索访问令牌并将其发送到托管在 EC2 上的 API。然后,您在托管应用程序上验证访问令牌 - https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html

    如果您的 EC2 是通过 Elastic Load Balancer 访问的,您可以将用户身份验证转移到 ELB 级别。您可以使用 Cognito 用户池或 Google 身份提供者用户身份验证 - https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html

    对于 Amazon API Gateway,您可以使用 Cognito 身份池:您在客户端生成的安全凭证将允许执行给定的 API Gateway,并且您在 API Gateway -https://aws.amazon.com/premiumsupport/knowledge-center/iam-authentication-api-gateway/ 上启用 IAM 身份验证。您还可以使用 Cognito 用户池:您从客户端上的用户池中检索访问令牌并将其发送到启用 Cognito 身份验证的 API Gateway - https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html

    【讨论】:

    • 是的,看起来是这样。但我没有使用基于 AWS 的 API(它在 EC2 上运行,但我没有使用 AWS API Gateaway)。那么将标头中的 id_token 发送到 API 是不是很糟糕?而不是这个,我需要查看 AWS API Gateaway(用于 REST API)和 AWS AppSync for GraphQL?
    • 或者我可以代替切换到 AWS API Gateway 在前端生成 aws 临时凭证并将它们发送到后端 API 吗?您提到 API Gateway 的此流程。是否可以安全地使用在 EC2 上运行的常规 API 代码?
    • @JonhyBeebop 您可以将 id_token 发送到您的 EC2 托管 API,然后您可以直接针对 Google API 进行验证,而无需使用身份池。身份池临时凭证正在使用 IAM 策略,而 AFAIK 没有合适的策略来控制 EC2 HTTP(S) 端口访问。我扩展了关于 EC2 身份验证选项的答案。
    猜你喜欢
    • 2021-01-05
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 2018-06-07
    • 1970-01-01
    相关资源
    最近更新 更多