Poradnik: Włączanie uwierzytelniania wieloskładnikowego w jednostronicowej aplikacji React, korzystając z natywnego zestawu SDK do uwierzytelniania w JavaScript.

Dotyczy: Zielone kółko z białym symbolem haczyka, które wskazuje, że poniższa treść dotyczy najemców zewnętrznych. Najemcy zewnętrzni (dowiedz się więcej)

Z tego samouczka dowiesz się, jak dodać uwierzytelnianie wieloskładnikowe (MFA) do aplikacji jednostronicowej React (SPA) przy użyciu natywnego zestawu SDK JavaScript dla uwierzytelniania.

Podobnie jak w przypadku rejestracji metody silnego uwierzytelniania, przepływ uwierzytelniania wieloskładnikowego występuje w trzech scenariuszach:

  • Podczas logowania: użytkownik loguje się i ma zarejestrowaną metodę silnego uwierzytelniania.
  • Po utworzeniu konta: po zakończeniu rejestracji użytkownik przejdzie do logowania. Nowi użytkownicy muszą zarejestrować metodę silnego uwierzytelniania, przed każdym wyzwaniem uwierzytelniania wieloskładnikowego. Ponieważ metoda silnego uwierzytelniania jest również weryfikowana podczas rejestracji, mogą nie być proszeni o dodatkowe uwierzytelnianie wieloskładnikowe.
  • Po samoobsługowym resetowaniu hasła (SSPR) użytkownik pomyślnie resetuje swoje hasło i automatycznie przechodzi do logowania. Jeśli użytkownik ma zarejestrowaną metodę silnego uwierzytelniania, zostanie wyświetlony monit o ukończenie zadania uwierzytelniania wieloskładnikowego.

Gdy uwierzytelnianie wieloskładnikowe jest wymagane, użytkownik wybiera metodę wyzwania uwierzytelniania wieloskładnikowego z listy zarejestrowanych metod. Dostępne opcje to jednorazowy kod dostępu poczty e-mail , jednorazowy kod dostępu sms lub oba te opcje, w zależności od tego, co użytkownik wcześniej zarejestrował.

Na poniższym diagramie przepływu przedstawiono trzy scenariusze:

Wykonaj wyzwanie dotyczące uwierzytelniania wieloskładnikowego.

Wymagania wstępne

Włączanie obsługi uwierzytelniania wieloskładnikowego przez aplikację

Aby włączyć uwierzytelnianie wieloskładnikowe w aplikacji React, zaktualizuj konfigurację aplikacji, dodając wymaganą możliwość:

  1. Znajdź plik src/config/auth-config.ts .

  2. W obiekcie customAuth dodaj lub zaktualizuj właściwość capabilities, aby zawrzeć wartość mfa_required w tablicy, jak pokazano w poniższym fragmencie kodu.

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

Wartość możliwości mfa_required informuje Microsoft Entra, że aplikacja może obsłużyć przepływ uwierzytelniania wieloskładnikowego. Dowiedz się więcej o typach i możliwościach uwierzytelniania natywnego.

Tworzenie składników interfejsu użytkownika

Potrzebujesz, aby składniki formularzy w aplikacji obsługiwały przepływ uwierzytelniania wieloskładnikowego. Aby dodać te składniki do aplikacji, wykonaj następujące czynności:

  1. Utwórz nowy folder src/app/shared/components dla komponentów wielokrotnego użytku (jeśli jeszcze nie istnieje).
  2. W nowym folderze utwórz plik o nazwie MfaAuthMethodSelectionForm.tsx , aby wyświetlić formularz, który umożliwia użytkownikom wybranie zarejestrowanej metody silnego uwierzytelniania. Dodaj kod w pliku MfaAuthMethodSelectionForm.
  3. W nowym folderze utwórz inny plik o nazwie MfaChallengeForm.tsx , aby wyświetlić formularz umożliwiający zweryfikowanie metody silnego uwierzytelniania przy użyciu jednorazowego kodu dostępu odbieranego przez użytkownika. Dodaj kod w pliku MfaChallengeForm.

W razie potrzeby możesz zaimportować i użyć składników wielokrotnego użytku w procesach logowania, logowania po rejestracji oraz logowania po przepływach samoobsługowego resetowania hasła (SSPR).

Obsługa uwierzytelniania wieloskładnikowego podczas logowania

Zaktualizuj plik src/app/sign-in/page.tsx , aby umożliwić aplikacji obsługę przepływu uwierzytelniania wieloskładnikowego podczas logowania. Zobacz pełny kod w pliku page.tsx:

  1. Zaimportuj wymagane typy i składniki, jak pokazano w poniższym fragmencie kodu:

    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. Dodaj nowe zmienne stanu dla uwierzytelniania wieloskładnikowego:

    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. Zaktualizuj funkcje startSignIn, handlePasswordSubmit i handleCodeSubmit, aby sprawdzić, czy wymagane jest MFA (uwierzytelnianie wieloskładnikowe).

    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);
            }
    
            ...
        }
    };
    

    W każdej funkcji zwróć uwagę, że sprawdzamy, czy uwierzytelnianie wieloskładnikowe jest wymagane przy użyciu następującego fragmentu kodu:

    if (result.isMfaRequired()) {...}
    
  4. Dodaj obsługującego dla wyboru wyzwania 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. Dodaj funkcję obsługi weryfikacji wyzwania 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. Zaktualizuj funkcję renderForm(), aby wyświetlić prawidłowe formularze wyzwań MFA (wybór metody wyzwań MFA lub weryfikacja metody wyzwań 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}
                />
            );
        }
    
        ...
    };
    

Obsługa uwierzytelniania wieloskładnikowego po zarejestrowaniu się lub zresetowaniu hasła

Przepływ MFA po zarejestrowaniu się i zresetowaniu hasła działa podobnie do MFA w procesie logowania. Po pomyślnym zarejestrowaniu się lub zresetowaniu hasła zestaw SDK może automatycznie kontynuować proces logowania. Jeśli użytkownik ma zarejestrowaną metodę silnego uwierzytelniania, przepływ przechodzi do weryfikacji wyzwania uwierzytelniania wieloskładnikowego.

Obsługa uwierzytelniania wieloskładnikowego po zarejestrowaniu

Aby skonfigurować przepływ uwierzytelniania wieloskładnikowego po rejestracji, należy zaktualizować plik /src/app/sign-up/page.tsx. Zobacz pełny kod w pliku page.tsx:

  1. Upewnij się, że importujesz wymagane typy i składniki.

  2. Obsłuż stany wymagań dotyczących MFA w podobny sposób, jak to się dzieje w przepływie logowania; po pomyślnym zakończeniu rejestracji użyj wyniku do automatycznego uruchomienia przepływu logowania, jak pokazano w poniższym fragmencie kodu:

    // 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
    

Obsługa uwierzytelniania wieloskładnikowego po zresetowaniu hasła

W przypadku procesu uwierzytelniania wieloskładnikowego po samodzielnym resetowaniu hasła należy zaktualizować plik /src/app/reset-password/page.tsx. Zobacz pełny kod w pliku page.tsx:

  1. Upewnij się, że importujesz wymagane typy i składniki.

  2. Obsłuż stany wymagań uwierzytelniania wieloskładnikowego w podobny sposób jak w procesie logowania. Po pomyślnym zakończeniu samoobsługowego resetowania hasła możesz użyć wyniku, aby automatycznie wyzwolić logowanie, jak pokazano w poniższym fragmencie kodu:

    // 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
    

Uruchamianie i testowanie aplikacji

Przed przetestowaniem aplikacji upewnij się, że masz konto użytkownika, które ma zarejestrowaną metodę silnego uwierzytelniania. Wykonaj kroki opisane w temacie Uruchamianie i testowanie aplikacji , aby uruchomić aplikację, ale tym razem przetestuj przepływ uwierzytelniania wieloskładnikowego.