无法将请求与 aws cognito 一起使用

Can't use requests with aws cognito

所以我设置了 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,而是在 return 中获得了 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 请求访问 Cognito 登录页面后面的资源并使用它 IdToken?谢谢!

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

请尝试:

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

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