无法将请求与 aws cognito 一起使用
Can't use requests with aws cognito
所以我设置了 Cognito 并使用 boto3 我可以使用以下代码获得 AccessToken
、IdToken
和 RefreshToken
:
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,我认为它可能会有所帮助。
所以我设置了 Cognito 并使用 boto3 我可以使用以下代码获得 AccessToken
、IdToken
和 RefreshToken
:
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,我认为它可能会有所帮助。