调用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
已排查情况
- 调用
sts.get_caller_identity()能获取到预期的IAM已验证角色:
{ "UserId": "ACCESS_KEY_ID:CognitoIdentityCredentials", "Account": "ACCOUNT_ID", "Arn": "arn:aws:sts::ACCOUNT_ID:assumed-role/authRole/CognitoIdentityCredentials" }
- 已为
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
相关产品推荐
相关产品推荐

