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

AWS Cognito自定义无密码流集成SOFTWARE_TOKEN_MFA遇CodeMismatch错误

问题诊断与解决方案

核心问题

你的DefineAuthChallenge函数中第一个条件判断逻辑错误,导致系统在处理SOFTWARE_TOKEN_MFA挑战时直接拒绝认证。

原代码中第一个条件:

if (event.request.session &&
  event.request.session.find(attempt => attempt.challengeName !== 'CUSTOM_CHALLENGE')) {
  event.response.issueTokens = false;
  event.response.failAuthentication = true;
}

这个逻辑会拒绝所有包含非CUSTOM_CHALLENGE的会话,包括你在CUSTOM_CHALLENGE成功后切换的SOFTWARE_TOKEN_MFA挑战。当用户提交MFA验证码时,会话中会同时存在成功的CUSTOM_CHALLENGE记录和当前的SOFTWARE_TOKEN_MFA尝试记录,此时find方法会找到非CUSTOM_CHALLENGE的条目,直接触发认证失败,从而抛出CodeMismatchException(实际是认证状态被提前拒绝,而非验证码错误)。

修复方案

修改第一个条件的逻辑,仅在用户未通过CUSTOM_CHALLENGE前拒绝非CUSTOM_CHALLENGE的挑战,允许通过自定义挑战后的SOFTWARE_TOKEN_MFA验证流程:

/**
 * @type {import('@types/aws-lambda').DefineAuthChallengeTriggerHandler}
 */

const getUserPreferredMFA = require('./functions/getUserPreferredMFA');

//define-challenge
exports.handler = async event => {

  try {
    console.log("event: ", JSON.stringify(event, null, 2));
  }
  catch (err) {
    console.log("error: ", err);
  }

  // 判断用户是否已通过CUSTOM_CHALLENGE
  const hasPassedCustomChallenge = event.request.session?.some(attempt => 
    attempt.challengeName === 'CUSTOM_CHALLENGE' && attempt.challengeResult === true
  );

  // 仅在未通过自定义挑战时,拒绝非CUSTOM_CHALLENGE的请求
  if (!hasPassedCustomChallenge && event.request.session &&
    event.request.session.find(attempt => attempt.challengeName !== 'CUSTOM_CHALLENGE')) {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }
  else if (event.request.session &&
    event.request.session.length >= 3 &&
    event.request.session.slice(-1)[0].challengeResult === false) {
    // 连续3次错误尝试,拒绝认证
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }
  else if (event.request.session &&
    event.request.session.length &&
    event.request.session.slice(-1)[0].challengeName === 'CUSTOM_CHALLENGE' &&
    event.request.session.slice(-1)[0].challengeResult === true) {

    if (await getUserPreferredMFA(event.userPoolId, event.userName) === "SOFTWARE_TOKEN_MFA") {
      event.response.challengeName = 'SOFTWARE_TOKEN_MFA';
      event.response.issueTokens = false;
      event.response.failAuthentication = false;
    }
    else {
      event.response.issueTokens = true;
      event.response.failAuthentication = false;
    }
  }
  else if (event.request.session &&
    event.request.session.slice(-1)[0].challengeName === 'SOFTWARE_TOKEN_MFA' &&
    event.request.session.slice(-1)[0].challengeResult === true) {
    // 处理SOFTWARE_TOKEN_MFA验证成功的情况,颁发令牌
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  }
  else {
    // 初始或未完成自定义挑战,继续CUSTOM_CHALLENGE
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = 'CUSTOM_CHALLENGE';
  }
  return event;
};

关键修改说明

  1. 新增hasPassedCustomChallenge判断:标记用户是否已成功完成自定义邮箱验证码挑战,避免后续的MFA挑战被误判为非法请求。
  2. 调整第一个条件的触发逻辑:仅在未通过自定义挑战时,才拒绝非CUSTOM_CHALLENGE的请求。
  3. 新增SOFTWARE_TOKEN_MFA成功后的处理分支:当MFA验证码验证通过时,直接颁发认证令牌,完成登录流程。

验证流程

修改后,认证流程将正常执行:

  1. 用户输入邮箱调用Auth.signIn,返回CUSTOM_CHALLENGE;
  2. 提交邮箱验证码,CUSTOM_CHALLENGE验证通过;
  3. 系统检测到用户启用了SOFTWARE_TOKEN_MFA,切换至该挑战;
  4. 用户提交MFA验证码,SOFTWARE_TOKEN_MFA验证通过,系统颁发令牌,登录完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:16:11