You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用AWS AppSync GraphQL端点返回401未授权错误求助

问题:使用PyCognito验证后调用AppSync GraphQL端点返回401未授权

我尝试通过PyCognito完成AWS Cognito用户身份验证,再借助关联身份池的已验证角色,让用户拥有查询AppSync GraphQL端点的权限,但执行后始终收到「401 Client Error: Unauthorized for url」错误。

最小可复现代码

from pycognito import Cognito
import boto3
from requests_aws4auth import AWS4Auth
import requests

user = Cognito(USER_POOL_ID, CLIENT_ID, username=USERNAME)
user.authenticate(password=PASSWORD)
user.check_token()
user.verify_tokens()

boto_session = boto3.Session()            
client = boto_session.client('cognito-identity', region_name=REGION)

identity_id = client.get_id(
    IdentityPoolId=f'{REGION}:{IDENTITY_POOL_ID}',
    Logins={
        f'cognito-idp.{REGION}.amazonaws.com/{USER_POOL_ID}': user.id_token
    }
)['IdentityId']

credentials = client.get_credentials_for_identity(
    IdentityId=identity_id,
    Logins={
        f'cognito-idp.{REGION}.amazonaws.com/{USER_POOL_ID}': user.id_token
    }
)['Credentials']

session = requests.Session()
session.auth = AWS4Auth(
    credentials["AccessKeyId"],
    credentials["SecretKey"],
    REGION,
    'appsync', 
    session_token=credentials["SessionToken"]
)

response = session.post(GRAPHQL_ENDPOINT, json={'query': QUERY, 'variables': {'id': user.id_claims["sub"]}})
response.raise_for_status()

错误信息

401 Client Error: Unauthorized for url: ENDPOINT

已排查情况

  1. 调用sts.get_caller_identity()能获取到预期的IAM已验证角色:
{
    "UserId": "ACCESS_KEY_ID:CognitoIdentityCredentials",
    "Account": "ACCOUNT_ID",
    "Arn": "arn:aws:sts::ACCOUNT_ID:assumed-role/authRole/CognitoIdentityCredentials"
}
  1. 已为authRole添加全量权限的内联策略:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "dynamodb:*",
                "appsync:*"
            ],
            "Resource": "*"
        }
    ]
}

解决方向

1. 确认AppSync认证模式

确保AppSync端点已启用AWS IAM认证模式,且未强制要求其他认证方式(如API_KEY、Cognito用户池)。若仅开启API_KEY,使用IAM凭证访问必然返回401。

2. 校验AWS4Auth参数

  • 确认AWS4Auth的服务参数为'appsync',区域参数REGION与AppSync端点所在区域完全一致(如us-east-1不能简写为us-east)。
  • 显式添加Content-Type请求头,AppSync的IAM认证要求必须携带该头:
    response = session.post(
        GRAPHQL_ENDPOINT,
        json={'query': QUERY, 'variables': {'id': user.id_claims["sub"]}},
        headers={'Content-Type': 'application/json'}
    )
    

3. 检查身份池角色信任关系

验证authRole的信任策略是否允许Cognito Identity服务扮演该角色,正确配置示例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": "YOUR_IDENTITY_POOL_ID"
                },
                "ForAnyValue:StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
        }
    ]
}

4. 验证ID Token有效性

手动解码ID Token(如通过jwt.io),确认:

  • iss字段指向正确的Cognito用户池地址
  • exp字段未过期
  • sub字段与查询用的user.id_claims["sub"]一致
  • 若配置了用户组映射,cognito:groups包含对应组

5. 配置AppSync资源策略

在AppSync控制台「设置」-「资源策略」中添加规则,允许authRole访问:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ACCOUNT_ID:role/authRole"
            },
            "Action": "appsync:GraphQL",
            "Resource": "arn:aws:appsync:REGION:ACCOUNT_ID:apis/API_ID/*"
        }
    ]
}

内容的提问来源于stack exchange,提问作者Austin Ulfers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:25:22