使用C#对接AWS Cognito用户池时PASSWORD_CLAIM_SECRET_BLOCK参数应填什么
解决方案
1. 参数来源说明
PASSWORD_CLAIM_SECRET_BLOCK 不需要自行生成,该值是此前调用 AdminInitiateAuth 接口触发PASSWORD_VERIFIER挑战时,返回结果中 ChallengeParameters 字典自带的字段,直接从返回结果取值即可。
2. 补充所有必填参数
除该参数外,还需从 AdminInitiateAuthResponse 的 ChallengeParameters 中取出以下必填字段,一并填入 ChallengeResponses:
SALTPASSWORD_CLAIM_SECRET_BLOCK
另外此前的逻辑存在两处错误:- 时间戳格式不符合Cognito要求,不能使用ISO格式的
ToString("o"),必须使用指定英文区域的UTC格式 PASSWORD_CLAIM_SIGNATURE不是单纯的客户端密钥哈希,需要结合SALT、SECRET_BLOCK、密码、时间戳通过SRP协议计算得到
3. 修正后可运行代码示例
// 调用AdminInitiateAuth获取挑战参数 var initAuthResponse = await cognitoClient.AdminInitiateAuthAsync(new AdminInitiateAuthRequest { UserPoolId = userPoolId, ClientId = appClientId, AuthFlow = AuthFlowType.ADMIN_USER_PASSWORD_AUTH, AuthParameters = new Dictionary<string, string> { { "USERNAME", username }, { "PASSWORD", password }, // 应用客户端开启了密钥的话需要传入SECRET_HASH { "SECRET_HASH", new CognitoHashCalculator().GetSecretHash(username, appClientId, appClientSecret) } } }); var challengeParams = initAuthResponse.ChallengeParameters; var userPoolIdPrefix = userPoolId.Split('_')[1]; // 计算PASSWORD_CLAIM_SIGNATURE,可直接用AWS SDK自带的SRP客户端 var srpClient = new SrpClient(userPoolIdPrefix); var passwordSignature = srpClient.ComputePasswordClaimSignature( challengeParams["SALT"], challengeParams["SECRET_BLOCK"], DateTime.UtcNow, password ); // 构造挑战响应请求 var challengeRequest = new AdminRespondToAuthChallengeRequest { ChallengeName = ChallengeNameType.PASSWORD_VERIFIER, ClientId = appClientId, UserPoolId = userPoolId, Session = initAuthResponse.Session, ChallengeResponses = new Dictionary<string, string> { { "USERNAME", username }, { "PASSWORD_CLAIM_SECRET_BLOCK", challengeParams["PASSWORD_CLAIM_SECRET_BLOCK"] }, { "PASSWORD_CLAIM_SIGNATURE", passwordSignature }, // 必须使用Cognito要求的时间戳格式 { "TIMESTAMP", DateTime.UtcNow.ToString("ddd MMM d HH:mm:ss UTC yyyy", CultureInfo.InvariantCulture) }, // 应用客户端开启了密钥的话需要传入SECRET_HASH { "SECRET_HASH", new CognitoHashCalculator().GetSecretHash(username, appClientId, appClientSecret) } } }; // 执行请求获取认证结果 var challengeResponse = await cognitoClient.AdminRespondToAuthChallengeAsync(challengeRequest);
优化建议
如果不想手动处理SRP计算和挑战响应流程,可以直接安装 AWS.Extensions.CognitoAuthentication NuGet包,使用包里的 CognitoUser 类封装好的认证方法,可大幅降低出错概率。
内容的提问来源于stack exchange,提问作者Plc Worker
相关产品推荐
相关产品推荐

