Compartir a través de


Tutorial: Habilitación de la autenticación multifactor en una aplicación de página única de React mediante el SDK de JavaScript de autenticación nativa

Se aplica a: Círculo verde con un símbolo de marca de verificación blanca que indica que el siguiente contenido se aplica a los inquilinos externos. Inquilinos externos (más información)

En este tutorial, aprenderá a agregar autenticación multifactor (MFA) en la aplicación de página única (SPA) de React mediante el SDK de JavaScript de la autenticación nativa.

Al igual que en el registro de métodos de autenticación segura, el flujo de MFA se produce en tres escenarios:

  • Durante el inicio de sesión: el usuario inicia sesión y tiene registrado un método de autenticación seguro.
  • Después de registrarse: después de que el usuario complete el registro, continúe con el inicio de sesión. Los nuevos usuarios deben registrar un método de autenticación seguro antes de cualquier desafío de MFA. Dado que el método de autenticación segura también se comprueba durante el registro, es posible que no se le pida un desafío de MFA adicional.
  • Después del autoservicio de restablecimiento de contraseña (SSPR): el usuario restablece correctamente su contraseña y continúa automáticamente para iniciar sesión. Si el usuario tiene registrado un método de autenticación seguro, se le pedirá que complete el desafío de MFA.

Cuando se requiere MFA, el usuario elige un método de desafío de MFA de una lista de métodos registrados. Las opciones disponibles son el código de acceso de un solo uso por correo electrónico , el código de acceso de un solo uso de SMS o ambos, en función de lo que el usuario registró anteriormente.

En el diagrama de flujo siguiente se muestran los tres escenarios:

Complete el desafío de autenticación multifactor.

Prerrequisitos

Habilitación de la aplicación para controlar la autenticación multifactor

Para habilitar MFA en la aplicación React, actualice la configuración de la aplicación agregando la funcionalidad necesaria:

  1. Busque el archivo src/config/auth-config.ts .

  2. En el customAuth objeto , agregue o actualice capabilities la propiedad para incluir el mfa_required valor en la matriz, como se muestra en el siguiente fragmento de código:

    const customAuthConfig: CustomAuthConfiguration = {
        customAuth: {
            ...
            capabilities: ["mfa_required"],
            ...
        },
        ...
    };
    

El valor de funcionalidad mfa_required informa a Microsoft Entra que su aplicación puede manejar un flujo de autenticación multifactor (MFA). Obtenga más información sobre los tipos y funcionalidades de desafío de autenticación nativa.

Creación de componentes de interfaz de usuario

Necesita componentes de formulario en su aplicación para soportar el flujo de autenticación multifactor (MFA). Siga estos pasos para agregar estos componentes a la aplicación:

  1. Cree una carpeta, src/app/shared/components para componentes reutilizables (si aún no existe).
  2. En la nueva carpeta, cree un archivo denominado MfaAuthMethodSelectionForm.tsx para mostrar un formulario que permita a los usuarios seleccionar un método de autenticación segura registrado. Agregue el código en MfaAuthMethodSelectionForm en el archivo.
  3. En la nueva carpeta, cree otro archivo denominado MfaChallengeForm.tsx para mostrar un formulario para comprobar el método de autenticación segura mediante el código de acceso único que recibe el usuario. Agregue el código en MfaChallengeForm en el archivo.

Cuando sea necesario, puede importar y usar componentes reutilizables en el inicio de sesión, el inicio de sesión después del registro y el inicio de sesión después de los flujos de restablecimiento de contraseña por autoservicio (SSPR).

Control de la autenticación multifactor durante el inicio de sesión

Actualice el archivo src/app/sign-in/page.tsx para permitir que la aplicación controle el flujo de MFA durante el inicio de sesión. Consulte el código completo en page.tsx:

  1. Importe los tipos y componentes necesarios, como se muestra en el siguiente fragmento de código:

    import {
        CustomAuthPublicClientApplication,
        ICustomAuthPublicClientApplication,
        SignInCodeRequiredState,
        SignInCompletedState,
        AuthFlowStateBase,
        MfaAwaitingState,
        MfaVerificationRequiredState,
    } from "@azure/msal-browser/custom-auth";
    import { MfaAuthMethodSelectionForm } from "../components/shared/MfaAuthMethodSelectionForm";
    import { MfaChallengeForm } from "../components/shared/MfaChallengeForm";
    
  2. Agregue nuevas variables de estado para MFA:

    export default function SignIn() {
        ...
        // MFA states
    const [mfaAuthMethods, setMfaAuthMethods] = useState<AuthenticationMethod[]>([]);
    const [selectedMfaAuthMethod, setSelectedMfaAuthMethod] = useState<AuthenticationMethod | undefined>(undefined);
    const [mfaChallenge, setMfaChallenge] = useState("");
    
        // ... initialization code
    }
    
  3. Actualice las funciones startSignIn, handlePasswordSubmit y handleCodeSubmit para comprobar si se requiere MFA.

    const startSignIn = async (e: React.FormEvent) => {
        // Start the sign-in flow
        const result = await authClient.signIn({
            username,
        });
    
        ...
    
        if (result.isMfaRequired()) {
            const methods = result.state.getAuthMethods();
            setMfaAuthMethods(methods);
            setSelectedMfaAuthMethod(methods.length > 0 ? methods[0] : undefined);
        }
    
        ...
    };
    
    const handlePasswordSubmit = async (e: React.FormEvent) => {
        if (signInState instanceof SignInPasswordRequiredState) {
            const result = await signInState.submitPassword(password);
    
            ...
    
            // Check for MFA requirement
            if (result.isMfaRequired()) {
                const methods = result.state.getAuthMethods();
                setMfaAuthMethods(methods);
                setSelectedMfaAuthMethod(methods.length > 0 ? methods[0] : undefined);
                setSignInState(result.state);
            }
    
            ...
        }
    };
    
    const handleCodeSubmit = async (e: React.FormEvent) => {
        if (signInState instanceof SignInCodeRequiredState) {
            const result = await signInState.submitCode(code);
    
            ...
    
            // Check for MFA requirement
            if (result.isMfaRequired()) {
                const methods = result.state.getAuthMethods();
                setMfaAuthMethods(methods);
                setSelectedMfaAuthMethod(methods.length > 0 ? methods[0] : undefined);
                setSignInState(result.state);
            }
    
            ...
        }
    };
    

    En cada una de las funciones, observe que se comprueba si se requiere MFA mediante el siguiente fragmento de código:

    if (result.isMfaRequired()) {...}
    
  4. Agregue el controlador para la selección del desafío de MFA:

    const handleMfaAuthMethodSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setError("");
        setLoading(true);
    
        if (!selectedMfaAuthMethod) {
            setError("Please select an authentication method.");
            setLoading(false);
            return;
        }
    
        if (signInState instanceof MfaAwaitingState) {
            const result = await signInState.requestChallenge(selectedMfaAuthMethod.id);
    
            if (result.isFailed()) {
                if (result.error?.isInvalidInput()) {
                    setError("Incorrect verification contact.");
                } else {
                    setError(
                        result.error?.errorData?.errorDescription ||
                            "An error occurred while verifying the authentication method"
                    );
                }
            }
    
            if (result.isVerificationRequired()) {
                setSignInState(result.state);
            }
        }
    
        setLoading(false);
    };
    
  5. Agregue el controlador para la comprobación del desafío de MFA:

    const handleMfaChallengeSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setError("");
        setLoading(true);
    
        if (!mfaChallenge) {
            setError("Please enter a code.");
            setLoading(false);
            return;
        }
    
        if (signInState instanceof MfaVerificationRequiredState) {
            const result = await signInState.submitChallenge(mfaChallenge);
    
            if (result.isFailed()) {
                if (result.error?.isIncorrectChallenge()) {
                    setError("Incorrect code.");
                } else {
                    setError(
                        result.error?.errorData?.errorDescription ||
                            "An error occurred while verifying the challenge response"
                    );
                }
            }
    
            if (result.isCompleted()) {
                setData(result.data);
                setCurrentSignInStatus(true);
                setSignInState(result.state);
            }
        }
    
        setLoading(false);
    };
    
  6. Actualice la renderForm() función para mostrar los formularios de desafío de MFA correctos (selección del método de desafío de MFA o comprobación del método de desafío de MFA):

    const renderForm = () => {
        if (loadingAccountStatus) {
            return;
        }
    
        ...
    
        // Display MfaAuthMethodSelectionForm if the current state is MFA awaiting state
        if (signInState instanceof MfaAwaitingState) {
            return (
                <MfaAuthMethodSelectionForm
                    onSubmit={handleMfaAuthMethodSubmit}
                    authMethods={mfaAuthMethods}
                    selectedAuthMethod={selectedMfaAuthMethod}
                    setSelectedAuthMethod={setSelectedMfaAuthMethod}
                    loading={loading}
                    styles={styles}
                />
            );
        }
    
        // Display MfaChallengeForm if the current state is MFA verification required state
        if (signInState instanceof MfaVerificationRequiredState) {
            return (
                <MfaChallengeForm
                    onSubmit={handleMfaChallengeSubmit}
                    challenge={mfaChallenge}
                    setChallenge={setMfaChallenge}
                    loading={loading}
                    styles={styles}
                />
            );
        }
    
        ...
    };
    

Control de la autenticación multifactor después del registro o el restablecimiento de contraseña

El flujo de MFA después del registro y el restablecimiento de contraseña funciona de forma similar a la MFA en el flujo de inicio de sesión. Después de un registro correcto o un restablecimiento de contraseña, el SDK puede continuar automáticamente con el flujo de inicio de sesión. Si el usuario tiene registrado un método de autenticación seguro, el flujo pasa a la comprobación del desafío de MFA.

Control de la autenticación multifactor después del registro

Para el flujo de MFA después del registro, necesita actualizar el archivo /src/app/sign-up/page.tsx . Consulte el código completo en page.tsx:

  1. Asegúrese de importar los tipos y componentes necesarios.

  2. Controle los estados de requisitos de MFA de forma similar a como sucede en el flujo de inicio de sesión; Una vez que el registro se complete correctamente, use el resultado para desencadenar automáticamente un flujo de inicio de sesión, como se muestra en el siguiente fragmento de código:

    // In your sign-up completion handler
    if (signUpState instanceof SignUpCompletedState) {
        // Continue with sign-in using the continuation token
        const result = await signUpState.signIn();
    
        ...
    
        if (result.isMfaRequired()) {
            const methods = result.state.getAuthMethods();
            setMfaAuthMethods(methods);
            setSelectedMfaAuthMethod(methods.length > 0 ? methods[0] : undefined);
            setSignUpState(state);
        }
    
        ...
    }
    
    // Then use the same renderForm logic to display MfaAuthMethodSelectionForm
    // and MfaChallengeForm components
    

Control de la autenticación multifactor después del restablecimiento de contraseña

Para el flujo de MFA después de SSPR, debe actualizar el archivo /src/app/reset-password/page.tsx . Consulte el código completo en page.tsx:

  1. Asegúrese de importar los tipos y componentes necesarios.

  2. Controle los estados de requisitos de MFA de forma similar a en el flujo de inicio de sesión. Una vez que SSPRS se complete correctamente, puede usar el resultado para desencadenar automáticamente un inicio de sesión, como se muestra en el siguiente fragmento de código:

    // In your password reset completion handler
    if (resetPasswordState instanceof ResetPasswordCompletedState) {
        // Continue with sign-in using the continuation token
        const result = await signUpState.signIn();
    
        ...
    
        if (result.isMfaRequired()) {
            const methods = result.state.getAuthMethods();
            setMfaAuthMethods(methods);
            setSelectedMfaAuthMethod(methods.length > 0 ? methods[0] : undefined);
            setResetState(state);
        }
    
        ...
    }
    
    // Then use the same renderForm logic to display MfaAuthMethodSelectionForm
    // and MfaChallengeForm components
    

Ejecución y prueba de la aplicación

Antes de probar la aplicación, asegúrese de que tiene una cuenta de usuario que tenga un método de autenticación segura registrado. Siga los pasos descritos en Ejecución y prueba de la aplicación para ejecutar la aplicación, pero esta vez, pruebe el flujo de MFA.