【问题标题】:Can't use requests with aws cognito无法通过 aws cognito 使用请求
【发布时间】:2021-04-24 18:41:00
【问题描述】:

所以我已经设置了 Cognito 并使用 boto3 我可以使用以下代码获得 AccessTokenIdTokenRefreshToken

client = boto3.client('cognito-idp', region_name="us-east-1")
resp = client.initiate_auth(
    AuthFlow='USER_PASSWORD_AUTH',
    AuthParameters={
        'USERNAME': username,
        'PASSWORD': pwd,
        'SECRET_HASH': secret_hash
    },
    ClientId=app_client_id,
)

到目前为止一切顺利。但现在我正在尝试像这样访问我的资源:

# A dns entry pointing to a LoadBalancer using Cognito on port 443
aws_lb_endpoint = "https://my_endpoint.com/"
auth_endpoint = "https://myendpoint.auth.us-east-1.amazoncognito.com"

id_token = resp['AuthenticationResult']['IdToken']

r = requests.get(aws_lb_endpoint, headers={'Authorization': id_token})

但我没有让我的网页在 Cognito 后面,而是得到 Cognito 登录页面作为回报:

<!DOCTYPE html>
<html lang="en">
<head><head>
    <link href="https://d3oia8etllorh5.cloudfront.net/20201215211355/css/bootstrap.min.css" rel="stylesheet"
        media="screen" />
    <link href="https://d3oia8etllorh5.cloudfront.net/20201215211355/css/cognito-login.css" rel="stylesheet"
        media="screen" />
    
    <title>Signin</title>

    <script src="https://d3oia8etllorh5.cloudfront.net/20201215211355/js/amazon-cognito-advanced-security-data.min.js" ></script>
    <script>
    function getAdvancedSecurityData(formReference) {
        if (typeof AmazonCognitoAdvancedSecurityData === "undefined") {
            return true;
        }

        // UserpoolId is not available on frontend for springboard. We do not use userPoolId
        // anyway other than put in context data. 
        var userPoolId = "";
        var clientId = getUrlParameter("client_id");
...

这是关于如何将 Cognito 连接到 ALB 的 terraform 代码:​​

resource "aws_lb_listener" "front_end_ssl" {
  load_balancer_arn = aws_lb.my_alb.arn
  port = "443"
  protocol = "HTTPS"
  ssl_policy = "ELBSecurityPolicy-2016-08"
  certificate_arn = var.certificate_arn

  default_action {
    type = "authenticate-cognito"

    authenticate_cognito {
      user_pool_arn       = aws_cognito_user_pool.my_pool.arn
      user_pool_client_id = aws_cognito_user_pool_client.webfront_pool_client.id
      user_pool_domain    = aws_cognito_user_pool_domain.my_pool_domain.domain
    }
  }

  default_action {
    type = "forward"
    target_group_arn = aws_lb_target_group.my_group_of_ec2_instances.arn
  }
}

resource "aws_cognito_user_pool_client" "webfront_pool_client" {
  name = "webfront_pool_client"

  user_pool_id = aws_cognito_user_pool.my_pool.id

  # Secret is mandatory here for the loadbalancer
  generate_secret = true
  prevent_user_existence_errors = "ENABLED"
  callback_urls = [
    "https://${aws_route53_record.server[0].fqdn}/oauth2/idpresponse"
  ]
  allowed_oauth_flows_user_pool_client = true

  # client_credentials would be ideal here for machine-to-machine communication. But we can't use client_credentials with Aws ALB
  allowed_oauth_flows = [
    "code"
  ]
  allowed_oauth_scopes = [
    "email",
    "openid"
  ]
  explicit_auth_flows = [
    "USER_PASSWORD_AUTH"
  ]
  supported_identity_providers = [
    "COGNITO"
  ]
}


有谁知道我如何通过 REST 请求并使用 IdToken 访问 Cognito 登录页面后面的资源?谢谢!

【问题讨论】:

    标签: python-3.x amazon-web-services boto3 amazon-cognito


    【解决方案1】:

    您的代码看起来不错。如果您的应用程序和 Cognito 配置正确,则问题可能是您在提供 id 令牌时缺少 Authorization 标头中的 Bearer 前缀。

    请尝试:

    r = requests.get(aws_lb_endpoint, headers={'Authorization': 'Bearer ' + id_token})
    

    请考虑阅读此related SO question,我认为这可能会有所帮助。

    【讨论】:

    • 我已经尝试过了,我什至尝试使用r = requests.get(aws_lb_endpoint, headers={'Authorization': id_token}),但我没有得到 LB 背后的内容,而是返回了 Cognito 登录页面
    • 我看到了@E-Kami。请注意,在任何情况下,您都可能需要为授权标头提供指定的 Bearer 前缀。那么问题很可能出现在 Cognito 或应用程序设置中。请问,你能更详细地描述你的架构吗?我的意思是,例如,您是否在 Beanstalk 中部署了应用程序?您在使用 API 网关吗?
    • 我刚刚用 terraform 代码更新了问题的所有细节
    • 抱歉,我误解了您的设置。您似乎正在尝试在 ALB 上执行 Cognito 身份验证。在这种授权中,流程是不同的:请参阅this link、此blog postofficial documentation。查看下一条评论
    • 可以看到,认证流程有点不同,很多步骤都是由 ALB 自己完成的。 ALB 将查找在成功进行用户身份验证后创建的 AWSELBAuthSessionCookie 会话 cookie,而不是 IDP 返回的 JWT 令牌。这可能是它将您重定向到登录页面的原因。老实说,我之前没有尝试过设置,但我认为这个想法将包括寻找 AWSELBAuthSessionCookie 会话 cookie 并将其包含在以下请求中。请尝试联系 AB,分析响应,看看是否定义了 cookie
    猜你喜欢
    • 2020-06-23
    • 2015-09-17
    • 2019-04-19
    • 1970-01-01
    • 2018-12-20
    • 2018-06-11
    • 1970-01-01
    • 2021-09-28
    • 2020-12-21
    相关资源
    最近更新 更多