Cognito自定义认证挑战未触发问题求助
我在Cognito中用Python创建了三个自定义认证挑战触发器(Define auth challenge、Create auth-challenge、Verify auth challenge),逻辑与官方示例一致。已为用户池客户端开启ALLOW_CUSTOM_AUTH授权流,编写Python测试客户端完成SRP_A和PASSWORD_VERIFIER挑战后,未触发预期的CUSTOM_CHALLENGE,直接获取了访问令牌和ID令牌。Define auth challenge Lambda在SRP_A流程中执行正常,请问该问题原因是什么?
Define auth challenge 代码
def lambda_handler(event, context): if (len(event['request']['session']) == 1 and event['request']['session'][0]['challengeName'] == "SRP_A"): event['response']['issueTokens'] = False event['response']['failAuthentication'] = False event['response']['challengeName'] = "PASSWORD_VERIFIER" elif (len(event['request']['session']) == 2 and event['request']['session'][1]['challengeName'] == "PASSWORD_VERIFIER" and event['request']['session'][1]['challengeResult'] is True): event['response']['issueTokens'] = False event['response']['failAuthentication'] = False event['response']['challengeName'] = "CUSTOM_CHALLENGE" elif (len(event['request']['session']) == 3 and event['request']['session'][2]['challengeName'] == "CUSTOM_CHALLENGE" and event['request']['session'][2]['challengeResult'] is True): event['response']['issueTokens'] = False event['response']['failAuthentication'] = False event['response']['challengeName'] = "CUSTOM_CHALLENGE" elif (len(event['request']['session']) == 4 and event['request']['session'][3]['challengeName'] == "CUSTOM_CHALLENGE" and event['request']['session'][3]['challengeResult'] is True): event['response']['issueTokens'] = True event['response']['failAuthentication'] = False else: event['response']['issueTokens'] = False event['response']['failAuthentication'] = True return event
Create auth-challenge 代码
def lambda_handler(event, context): if event['request']['challengeName'] != "CUSTOM_CHALLENGE": return event if len(event['request']['session']) == 2: event['response']['publicChallengeParameters'] = {} event['response']['privateChallengeParameters'] = {} event['response']['publicChallengeParameters']['captchaUrl'] = "url/123.jpg" event['response']['privateChallengeParameters']['answer'] = "5" if len(event['request']['session']) == 3: event['response']['publicChallengeParameters'] = {} event['response']['privateChallengeParameters'] = {} event['response']['publicChallengeParameters']['securityQuestion'] = "Who is your favorite team mascot?" event['response']['privateChallengeParameters']['answer'] = "Peccy" return event
Verify auth challenge 代码
def lambda_handler(event, context): if event['request']['privateChallengeParameters']['answer'] == event['request']['challengeAnswer']: event['response']['answerCorrect'] = True else: event['response']['answerCorrect'] = False return event
测试客户端代码
import boto3 from pycognito import AWSSRP session = boto3.Session(profile_name="aws-profile") cognito = session.client('cognito-idp') cognito_user_pool_id = "xx-xxxx-x_xxxxxxxxx" cognito_user_pool_client_id = "xxxxxxxxxxxxxxxxxxxxxxxxxx" username = "xxxx" password = "xxxx" aws_srp = AWSSRP( username=username, password=password, pool_id=cognito_user_pool_id, client_id=cognito_user_pool_client_id, client=cognito ) print("\nInitiate CUSTOM_AUTH with SRP_A challenge") auth_params = aws_srp.get_auth_params() resp = cognito.initiate_auth( AuthFlow='CUSTOM_AUTH', AuthParameters={**auth_params, **{ "CHALLENGE_NAME": "SRP_A" }}, ClientId=cognito_user_pool_client_id ) print(resp) print("\nRespond to PASSWORD_VERIFIER challenge") assert resp["ChallengeName"] == "PASSWORD_VERIFIER" challenge_response = aws_srp.process_challenge(resp["ChallengeParameters"], auth_params) resp = cognito.respond_to_auth_challenge( ClientId=cognito_user_pool_client_id, ChallengeName="PASSWORD_VERIFIER", ChallengeResponses={**challenge_response} ) print(resp)
问题原因与解决方法
核心原因
用户池客户端同时启用了USER_SRP_AUTH流
即使开启了ALLOW_CUSTOM_AUTH,只要USER_SRP_AUTH(默认开启)未被禁用,Cognito会优先走标准SRP认证流程。当客户端完成PASSWORD_VERIFIER挑战后,Cognito判定标准SRP流程已完成,直接返回令牌,不会触发自定义挑战的后续逻辑。Define auth challenge Lambda的触发验证
虽然SRP_A流程中Lambda执行正常,但需要确认该Lambda是否正确关联到用户池的Define Auth Challenge触发器,且Cognito服务拥有调用该Lambda的权限(比如配置了正确的IAM角色)。
解决步骤
禁用USER_SRP_AUTH流
登录AWS控制台,进入目标Cognito用户池的客户端设置页面,在"认证流"选项中,仅保留ALLOW_CUSTOM_AUTH的勾选,取消USER_SRP_AUTH的勾选。这会强制Cognito走自定义认证流路径。验证Lambda的session逻辑
在Define auth challenge Lambda中添加日志输出,查看实际的session结构:import logging logger = logging.getLogger() logger.setLevel(logging.INFO) logger.info(f"Session details: {event['request']['session']}")通过CloudWatch日志检查session的长度和挑战名称是否符合预期,调整代码中的判断条件。
确认客户端AuthFlow参数
确保测试客户端发起认证时,AuthFlow参数严格设置为'CUSTOM_AUTH',避免混入其他流程参数(你的测试代码已正确设置,但需确认无其他配置冲突)。
内容的提问来源于stack exchange,提问作者João Pedro Schmitt

