AWS Cognito Software Token MFA работает один раз, а затем неожиданно возвращается к SMS MFA для всех будущих входов

Фон:

У меня есть веб-приложение React (использующее aws-amplify), которое подключается к пулу пользователей AWS Cognito или использует его для аутентификации.

Я пытаюсь включить MFA и, в частности, хочу, чтобы у моих пользователей была возможность использовать программный токен TOTP MFA (то есть приложение Google Authenticator или подобное).

Когда я настраиваю свой пул пользователей на использование MFA, я вынужден включить SMS MFA, а затем TOTP программного обеспечения является необязательным. В моем случае у меня включен TOTP.

В своем веб-приложении я добавил необходимый компонент через:

import { SelectMFAType } from 'aws-amplify-react';

# other code

<SelectMFAType authData={user} MFATypes={{ SMS: true, TOTP: true }} />

# other code

Если вы не знакомы с aws-amplify-react и / или SelectMFAType, этот компонент предоставляет элемент пользовательского интерфейса, в котором пользователь может выбрать, предпочитает ли он использовать SMS или программный TOTP в качестве метода MFA. Если они выбирают SMS, используется их ранее подтвержденный номер телефона, и все работает.

Если пользователь выбирает TOTP, ему отображается QR-код для сканирования в выбранном им приложении для проверки подлинности, а в поле ввода предлагается ввести 6-значное число из приложения для проверки подлинности для проверки TOTP. Все это очень стандартно для всех, кто использовал опцию TOTP MFA на любом другом веб-сайте. Если пользователь вводит правильный код из приложения, его выбор TOTP подтверждается.

Короче говоря, SelectMFAType - это просто ярлык / замена для быстрого прототипирования и тестирования без необходимости создания специального компонента.

Проблема:

Теперь вот проблема и как ее воспроизвести. (Отправной точкой является пользователь, который только что включил TOTP.):

  1. Пользователь выходит из системы.
  2. Пользователь входит в систему.
  3. Если имя пользователя и пароль верны, пользователю будет предложено ввести TOTP.
  4. Если TOTP правильный, пользователь вошел в систему. Пока все работает отлично, но так не будет.
  5. Пользователь выходит из системы.
  6. Пользователь входит в систему.
  7. Если имя пользователя и пароль верны, пользователю будет предложено ввести SMS MFA и получить текстовое сообщение с 6-значным кодом. Это неожиданное поведение. Я ожидаю, что он продолжит запрашивать TOTP MFA из своего приложения-аутентификатора, если пользователь не изменит свой предпочтительный метод обратно на SMS.
  8. С этого момента у пользователя всегда будет запрашиваться только SMS MFA.

Между шагами 4 и 7 предпочтения пользователя не изменились. Абсолютно ничего не изменилось ни в приложении React, ни в настройках AWS User Pool.

Кроме того, если я опрашиваю пользователя с помощью команды aws cognito-idp admin-get-user --user-pool-id ${MY_ID} --username ${MY_USER_NAME} CLI AWS, я могу подтвердить, что предпочтения MFA пользователя соответствуют моим ожиданиям:

{
    <other irrelevant keys redacted>
    "PreferredMfaSetting": "SOFTWARE_TOKEN_MFA",
    "UserMFASettingList": [
        "SMS_MFA",
        "SOFTWARE_TOKEN_MFA"
    ]
}

Задача MFA - это ответ API от AWS Cognito, когда пользователь пытается пройти аутентификацию, и это либо SMS_MFA, либо SOFTWARE_TOKEN_MFA. В моем случае я получаю один SOFTWARE_TOKEN_MFA вызов, но затем все будущие вызовы, вопреки моему желанию, возвращаются к SMS_MFA.

Если я повторяю процесс настройки TOTP (удаляю запись из приложения для аутентификации, повторно проверяю и т. Д.), Я могу повторить все шаги еще раз. Под этим я подразумеваю, что MFA будет ожидать TOTP один раз, а затем снова вернется к SMS после этого первого раза.

Может ли кто-нибудь пролить свет на эту ситуацию? Вы испытали это? Это известная проблема / ошибка в AWS Cognito? Я делаю что-то неправильно? Мне кажется, что если бы это было сломано, было бы генерироваться довольно много шума, но я не могу найти никого с такой же проблемой.

Вещи, которые я пробовал:

  • Подробно искал кого-нибудь с такой же проблемой здесь, в Google и на форумах AWS.
  • Я писал сообщения на форумах AWS, но это никуда не делось: https://forums.aws.amazon.com/thread.jspa?threadID=324131.
  • Создал пользовательский компонент для замены SelectMFAType в соответствии с теорией, что что-то не так с реализацией в aws-amplify-react. Я вставлю этот пользовательский компонент в конце этого вопроса в качестве справки.
  • Полностью уничтожен и воссоздан пул пользователей AWS Cognito. Я подумал, что, возможно, он поврежден или не работает. Это не имело значения.

SetupTOTP.js Компонент:

import React, { useContext, useEffect, useState } from 'react';
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContextText,
  DialogTitle,
  TextField,
} from '@material-ui/core';
import { Auth } from 'aws-amplify';
import { ToastsStore } from 'react-toasts';
import QRCode from 'qrcode.react';

import { AuthStateContext } from 'Context/auth-context';

const SetupTOTP = React.memo(props => {
  const { open, handleClose } = props;
  const { username } = useContext(AuthStateContext);
  const [user, setUser] = useState(null);
  const [qrCode, setQrCode] = useState('');
  const [token, setToken] = useState('');

  const handleSave = () => {
    Auth.verifyTotpToken(user, token)
      .then(() => {
        Auth.setPreferredMFA(user, 'TOTP').then(() => {
          ToastsStore.success('Token Verified Updated');
          handleClose();
        });
      })
      .catch(err => {
        console.log(err);
        ToastsStore.error(err.message);
      });
  };

  useEffect(() => {
    Auth.currentAuthenticatedUser().then(user => {
      setUser(user);
    });
  }, []);

  useEffect(() => {
    if (username && user) {
      Auth.setupTOTP(user).then(code => {
        setQrCode(
          `otpauth://totp/AWSCognito:${username}?secret=${code}&issuer=REDACTED`
        );
      });
    }
  }, [username, user]);

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      aria-labelledby="form-dialog-title"
    >
      <DialogTitle id="form-dialog-title">Change Password</DialogTitle>
      <DialogContent>
        <QRCode value={qrCode} />

        <TextField
          margin="dense"
          id="name"
          label="Verify Token"
          type="text"
          fullWidth
          onChange={e => setToken(e.target.value)}
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color="primary">
          Cancel
        </Button>
        <Button onClick={handleSave} color="primary">
          Save
        </Button>
      </DialogActions>
    </Dialog>
  );
});

export default SetupTOTP;

person WGriffing    schedule 01.07.2020    source источник
comment
Я столкнулся с этим с двумя пользователями. Есть ли в этом прогресс? Похоже на довольно серьезную ошибку, чтобы включить Software MFA и пропустить его, как это происходит, когда я выключаю SMS MFA и оставляю программное обеспечение включенным (для случайных пользователей, у которых это происходит).   -  person Zach    schedule 26.08.2020
comment
К сожалению, не от меня. Мне пришлось отказаться от усилий. Вместо этого я пробовал использовать SMS MFA, но доставка SMS клиентам T-Mobile ненадежна, поэтому мне пришлось отказаться и от этого. Вместо этого я использую 3 триггера Cognito Lambda (определение, создание и проверка аутентификации) для реализации моего собственного MFA на основе электронной почты. Я считаю, что вы могли бы использовать аналогичный подход для реализации пользовательского программного токена TOTP, но электронная почта на самом деле лучше всего подходила для моего варианта использования.   -  person WGriffing    schedule 27.08.2020


Ответы (1)


Я считаю, что это ошибка Cognito. См. Эту проблему Amplify.

person Zach    schedule 25.08.2020
comment
Спасибо за ответ, но я не уверен, что меня мучает та же проблема. Как вы можете видеть из моего примера кода SetupTOTP, я вызвал setPreferredMfa после вызова verifyTotpToken. Другое отличие состоит в том, что мое приложение не отказывалось от MFA, а скорее возвращалось к SMS MFA. Похоже, этот пользователь говорит, что его приложение вообще не выполняло никакой MFA: github.com/aws-amplify/amplify-js/issues/. Это может быть та же ошибка, я просто не уверен, и, как я уже упоминал выше, я обошел проблему, сделав свое собственное решение MFA. - person WGriffing; 27.08.2020