在.NET中使用AWS SDK获取Cognito指定角色会话令牌遇授权异常
解决.NET(Xamarin)中Cognito指定CustomRoleArn获取临时凭证的问题
我之前也碰到过这个模糊角色映射的错误,核心问题是你当前的调用方式触发了身份池的默认角色映射规则,和你指定的CustomRoleArn产生了冲突,导致服务端无法确定该使用哪个角色。下面是具体的解决思路和修正后的代码:
错误原因分析
当你的身份池配置了基于用户组或令牌的角色映射规则时,如果你先通过GetCognitoAWSCredentials获取了默认凭证,再调用GetCredentialsForIdentityAsync传递CustomRoleArn,服务端会同时收到默认角色映射的请求和自定义角色的请求,规则冲突就会抛出NotAuthorizedException,提示"ambiguous role mapping rules"。
修正后的实现步骤
1. 先获取IdentityId(避免硬编码)
首先需要用用户池的ID Token获取对应的IdentityId,而不是直接硬编码(硬编码容易出错,也不灵活):
2. 直接调用GetCredentialsForIdentityAsync传递CustomRoleArn
使用空凭证初始化AmazonCognitoIdentityClient(因为我们是通过Logins里的ID Token来认证身份,不需要提前获取AWS凭证),然后明确传递CustomRoleArn,避免触发默认角色映射。
using Amazon.CognitoIdentity; using System.Threading.Tasks; public async Task<CognitoIdentityCredentials> GetCustomRoleCredentials(string customRoleArn) { var region = RegionEndpoint.USEast1; var identityPoolId = "us-east-1:ef964b45-939e-4ef3-91c6-xxxxxxxxxxxx"; var userPoolProviderUrl = "cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx"; var idToken = _authenticationService.AuthenticationResult.IdToken; // 初始化Cognito Identity客户端(空凭证,因为用ID Token认证) var cognitoClient = new AmazonCognitoIdentityClient(null, region); // 第一步:获取IdentityId var getIdRequest = new GetIdRequest { IdentityPoolId = identityPoolId, Logins = new Dictionary<string, string> { { userPoolProviderUrl, idToken } } }; var getIdResponse = await cognitoClient.GetIdAsync(getIdRequest); var identityId = getIdResponse.IdentityId; // 第二步:获取指定角色的临时凭证 var getCredsRequest = new GetCredentialsForIdentityRequest { IdentityId = identityId, Logins = new Dictionary<string, string> { { userPoolProviderUrl, idToken } }, CustomRoleArn = customRoleArn }; var getCredsResponse = await cognitoClient.GetCredentialsForIdentityAsync(getCredsRequest); return getCredsResponse.Credentials; }
关键注意事项
- 避免阻塞异步调用:不要用
.Result同步等待异步方法,Xamarin环境下容易引发死锁,改用await。 - 检查IAM角色信任策略:确保你指定的
customRoleArn对应的IAM角色信任策略允许Cognito身份池的身份调用它,示例信任策略如下:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "你的身份池ID" }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } } } ] } - 身份池角色解析设置:在身份池的「身份验证提供程序」->「Cognito」配置中,确保角色解析规则不会和自定义角色冲突。如果主要用
CustomRoleArn,可以将角色解析设置为「使用默认角色」,但自定义角色会覆盖这个默认值。
内容的提问来源于stack exchange,提问作者Chris Whisker
相关产品推荐
相关产品推荐

