Felhasználók bejelentkezése

Mielőtt elkezdené, győződjön meg arról, hogy tisztában van az alkalmazásobjektum inicializálásával.

Az MSAL bejelentkezési API-jai egy authorization code kérnek le, amely bejelentkezett felhasználó esetén egy azonosító tokenre váltható, miközben a rendszer egy további erőforráshoz tartozó hatókörök jóváhagyását is kéri, valamint egy hozzáférési tokent ad vissza, amely a felhasználó által jóváhagyott hatóköröket tartalmazza, hogy az alkalmazás biztonságosan hívhassa meg az API-t.

Interakciótípus kiválasztása

Lásd itt , ha bizonytalan a különbségek között loginRedirect és loginPopup.

A felhasználó bejelentkezése

Egy kérelemobjektumot kell átadnia a bejelentkezési API-knak. Ez az objektum lehetővé teszi, hogy különböző paramétereket használjon a kérelemben. A kérelemobjektum paramétereiről itt talál további információt.

A bejelentkezési kérelmek esetében az összes paraméter megadása nem kötelező, így csak üres objektumot küldhet.

  • Popup
try {
    const loginResponse = await msalInstance.loginPopup({});
} catch (err) {
    // handle error
}
  • Redirect
try {
    msalInstance.loginRedirect({});
} catch (err) {
    // handle error
}

Vagy elküldheti a hatókörök egy csoportját, hogy előzetes hozzájárulást adjon a következőhöz:

  • Popup
var loginRequest = {
    scopes: ["user.read", "mail.send"] // optional Array<string>
};

try {
    const loginResponse = await msalInstance.loginPopup(loginRequest);
} catch (err) {
    // handle error
}
  • Redirect
var loginRequest = {
    scopes: ["user.read", "mail.send"] // optional Array<string>
};

try {
    msalInstance.loginRedirect(loginRequest);
} catch (err) {
    // handle error
}

Fiók-API-k

Ha egy bejelentkezési hívás sikeres volt, a függvény használatával lekérheti az getAllAccounts() aktuálisan bejelentkezett felhasználók adatait.

const myAccounts: AccountInfo[] = msalInstance.getAllAccounts();

Ha ismeri a fiókadatokat, az API-val is lekérheti a getAccount() fiókadatokat:

const username = "test@contoso.com";
const myAccount: AccountInfo = msalInstance.getAccount({ username });

const homeAccountId = "userid.hometenantid"; // Best to retrieve the homeAccountId from an account object previously obtained through msal
const myAccount: AccountInfo = msalInstance.getAccount({ homeAccountId });

Note

A username szerinti szűrés csak a kényelmet szolgálja, és kevésbé megbízható, mint a homeAccountId alapján végzett keresés. Ha lehetséges, használja a homeAccountId-t.

B2C-forgatókönyvek esetén a B2C-bérlőt úgy kell konfigurálni, hogy a(z) idTokens esetében visszaadja a emails igényt, hogy használni lehessen a username szűrőt a(z) getAccount() API-n.

Ezek az API-k egy fiókobjektumot vagy fiókobjektum-tömböt adnak vissza a következő aláírással:

{
    // home account identifier for this account object
    homeAccountId: string;
    // Entity who issued the token represented as a full host of it (e.g. login.microsoftonline.com)
    environment: string;
    // Full tenant or organizational id that this account belongs to
    tenantId: string;
    // preferred_username claim of the id_token that represents this account.
    username: string;
};

Csendes bejelentkezés ssoSilent() használatával

Ha már rendelkezik a hitelesítési kiszolgálóval meglévő munkamenettel, az ssoSilent() API használatával interakció nélkül kérhet jogkivonatokat.

Felhasználói útmutatással

Ha már rendelkezik a felhasználó bejelentkezési adataival, ezt továbbíthatja az API-ba a teljesítmény javítása érdekében, és meggyőződhet arról, hogy az engedélyezési kiszolgáló a megfelelő fiókmunkamenetet fogja keresni. A token csendes lekéréséhez az alábbiak egyikét adhatja meg a kérésobjektumban.

Javasoljuk, hogy használja a login_hint választható ID-jogkivonatjogcímet (amelyet a(z) ssoSilent számára loginHint néven biztosítanak), mivel ez a csendes (és interaktív) kérésekhez használható legmegbízhatóbb fiókazonosító támpont.

  • account (amely az egyik fiók API-jának használatával kérhető le)
  • sid (amely egy account objektum idTokenClaims-jéből lekérhető)
  • login_hint (a következő módokon kérhető le)
    • A fiókobjektum loginHint tulajdonságaként (ajánlott)
    • A fiókobjektum login_hint azonosítótoken-jogcímeként (ajánlott)
    • A fiókobjektum username tulajdonságaként (nem ajánlott)
    • A fiókobjektum upn azonosító jogkivonataként (nem ajánlott)

Note

A tényleges login_hint jogcím helyett a username és upn tulajdonságok részben támogatottak, de használatuk nem ajánlott. Használja a loginHint vagy idTokenClaims.login_hint fiók tulajdonságait, ha elérhetők.

Ha megad egy fiókot, a rendszer először az login_hint opcionális ID-jogcímet keresi (preferált), majd az sid opcionális ID-jogcímet, végül pedig a loginHint értéket használja (ha meg van adva), vagy a fiók felhasználónevét.

const account = msalInstance.getAllAccounts()[0];

const silentRequest = {
    scopes: ["User.Read", "Mail.Read"],
    loginHint: account.loginHint, // alternatively, account.idTokenClaims.login_hint
};

try {
    const loginResponse = await msalInstance.ssoSilent(silentRequest);
} catch (err) {
    if (err instanceof InteractionRequiredAuthError) {
        const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
            // handle error
        });
    } else {
        // handle error
    }
}

Felhasználói tipp nélkül

Ha nincs elegendő információ a felhasználóról, megpróbálhatja az ssoSilent API-t anélkül használni, hogy átadna egy account, sid vagy login_hint elemet.

const silentRequest = {
    scopes: ["User.Read", "Mail.Read"]
};

Vegye figyelembe azonban, hogy ha az alkalmazás több felhasználó kódútvonalával rendelkezik egy böngészős munkamenetben, vagy ha a felhasználó több fiókkal rendelkezik az adott böngésző munkamenethez, akkor nagyobb a csendes bejelentkezési hibák valószínűsége. Az alábbi hibaüzenet jelenhet meg az engedélyezési kiszolgáló által talált több fiók munkamenete esetén:

InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.

Ez azt jelzi, hogy a kiszolgáló nem tudta meghatározni, hogy melyik fiókba kell bejelentkeznie, és a fiók kiválasztásához a fenti paraméterek egyikét (account, , login_hint) sidvagy egy interaktív bejelentkezést igényel.

Warning

Ha használja ssoSilent, a szolgáltatás megkísérli betölteni az átirányítási URI-oldalt egy láthatatlan beágyazott iframe-be. Az alkalmazás átirányítási URI-oldalának válaszában található tartalombiztonsági szabályzatok és HTTP-fejlécértékek, például X-FRAME-OPTIONS: DENY és X-FRAME-OPTIONS: SAMEORIGIN, megakadályozhatják, hogy az alkalmazás betöltődjön az iframe-ben, ami gyakorlatilag blokkolhatja a csendes egyszeri bejelentkezést. Ha használni ssoSilentszeretné, győződjön meg arról, hogy az átirányítási URI olyan lapra mutat, amely nem implementál ilyen szabályzatokat.

A redirect URI-val kapcsolatos szempontok

Most már minden hitelesítési folyamathoz dedikált átirányítási oldal szükséges , amely implementálja az MSAL átirányítási hidat. Ez szükséges a COOP (Cross-Origin-Opener-Policy) fejlécek támogatásához, valamint az előugró/iframe ablakok és a fő alkalmazás közötti biztonságos kommunikáció engedélyezéséhez.

Az átirányítási oldal beállítása

Az Ön redirectUri elemének egy olyan külön oldalra kell mutatnia, amely betölti az átirányítási híd szkriptet. Ennek a lapnak a következőnek kell lennie:

  1. Az átirányítási híd szkriptjének betöltése – Ez a szkript kezeli a főablakkal való kommunikációt
  2. A hídszkript kivételével ne tartalmazzon JavaScriptet – Az átirányítási oldalnak csak a hídszkriptet kell futtatnia
  3. Ne tartalmazzon útvonalkezelő logikát – Kerülje az olyan routerkönyvtárakat, amelyek zavarhatják a hash kezelését
  4. Regisztrálva kell lennie az alkalmazásregisztrációban – Az URI-nak pontosan meg kell egyeznie a Azure portálon regisztráltakéval

Például átirányítási oldal (csomagköteg használata esetén, például Vite vagy Webpack):

<!DOCTYPE html>
<html>
<head>
    <title>Redirect</title>
</head>
<body>
    <p>Processing authentication...</p>
    <script type="module">
        import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

        broadcastResponseToMainFrame();
    </script>
</body>
</html>

Note

A @azure/msal-browser/redirect-bridge kijelölőt egy csomagkötegelőnek (Vite, Webpack stb.) kell feloldania – ez nem egy OLYAN URL- cím, amelyet a böngészők közvetlenül lekérhetnek. A keretrendszerre vonatkozó utasításokért tekintse meg az Átirányítási híd beállítási útmutatót.

Konfiguráció

A(z) redirectUri globálisan az MSAL-konfigurációban vagy kérelmenként is beállítható:

Globális konfiguráció:

const msalConfig = {
    auth: {
        clientId: "your-client-id",
        authority: "https://login.microsoftonline.com/common",
        redirectUri: "http://localhost:3000/redirect"
    }
};

const msalInstance = new PublicClientApplication(msalConfig);

Kérésenkénti konfiguráció:

msalInstance.loginPopup({
    scopes: ["user.read"],
    redirectUri: "http://localhost:3000/redirect"
});

A további információkért és a teljes mintamegvalósításokért lásd:

Előugró interaction_in_progress hibák kezelése

Előugró folyamatok esetén a overrideInteractionInProgress jelölővel megszakíthat egy függőben lévő interakciót, és elindíthat egy újat. Ez hasznos lehet olyan helyreállítási esetekben, amikor a felhasználó bezárt egy felugró ablakot, vagy egy interakció sikertelen volt.

Note

Ez a funkció csak előugró folyamatokhoz érhető el , és átirányítási folyamatok esetében nem támogatott. A COOP (Cross-Origin-Opener-Policy) fejlécben a hagyományos window.opener kapcsolat megszakad, így az előugró ablakok csak a BroadcastChannelen keresztül kommunikálhatnak a fő kerettel.

Important

Ha ezt true értékre állítja, az kényszerítve megszakítja a függőben lévő felugró hitelesítési kéréseket, de nem zárja be a már megnyitott felugró ablakokat.

Ha a következő értékre van trueállítva:

  • Ha egy másik előugró művelet jelenleg folyamatban van, akkor a művelet kényszerítetten megszakad, de a megnyitott előugró ablakok nincsenek bezárva
  • A függőben lévő interakció egy interaction_in_progress_cancelled hibával meghiúsul
  • Az új felugró ablak folyamata azonnal továbbhalad

Érvényes használati esetek:

  • Helyreállítás azokból a hibákból, amikor a felhasználó megszakította a felugró ablakot (a felugró ablakot a hitelesítés befejezése nélkül zárták be)
  • Egyéni hiba-helyreállítási folyamatok implementálása
  • "Újrapróbálkozás" mechanizmus biztosítása sikertelen előugró interakció után

Alapértelmezett:false

Fontos: Csak kattintásra használható

Ne próbálja meg automatikusan újra egy interaction_in_progress hiba elkapásakor. A felülbírálást csak egy explicit felhasználói művelet aktiválhatja (például az "Újrapróbálkozás" gombra kattintva). Az interakciók automatikus felülírása a következőhöz vezethet:

  • Versenyfeltételek több hitelesítési folyamat között
  • A jogos hitelesítési kísérletek váratlan megszakítása
  • Gyenge felhasználói élmény a hitelesítési folyamatok váratlan indításával és leállításával kapcsolatban
  • Túl sok megnyitott felugró ablak, amely nem eredményez sikeres hitelesítési választ

Példa: Megfelelő hibakezelés felhasználó által aktivált újrapróbálkozással

A vizuális visszajelzésekkel rendelkező teljes megvalósításokért lásd:

  • Express Sample – JavaScript-implementáció bemutatása egyéni CSS-sel
  • React Router-minta – A React implementációját mutatja be Material-UI összetevőkkel

Mindkét minta a következőt szemlélteti:

  • Figyelmeztető üzenet jelenik meg az előugró hitelesítés során
  • Hiba esetén próbálkozzon újra a modális/párbeszédpanellel, egyértelmű magyarázattal interaction_in_progress
  • A felhasználó által aktivált újrapróbálkozások megfelelő állapotkezelése
  • Éles használatra kész felhasználói felületi összetevők
// State to track if user wants to retry
let userWantsRetry = false;

// Button click handler
async function handleLoginClick() {
    try {
        const loginRequest = {
            scopes: ["user.read"]
        };

        // If user explicitly clicked retry, override the existing interaction
        if (userWantsRetry) {
            loginRequest.overrideInteractionInProgress = true;
            userWantsRetry = false; // Reset flag
        }

        const response = await msalInstance.loginPopup(loginRequest);
        // Handle successful login
    } catch (error) {
        if (error.errorCode === 'interaction_in_progress') {
            // Show retry button to user - DO NOT automatically retry
            showRetryButton();
        } else {
            // Handle other errors
            console.error(error);
        }
    }
}

// Retry button click handler
function handleRetryClick() {
    userWantsRetry = true; // Set flag for next login attempt
    handleLoginClick(); // User explicitly requested retry
}

Példa: React-összetevő felhasználó által kezdeményezett újrapróbálással

function LoginButton() {
    const { instance } = useMsal();
    const [showRetry, setShowRetry] = useState(false);
    const [retryRequested, setRetryRequested] = useState(false);

    const handleLogin = async () => {
        try {
            const loginRequest = {
                scopes: ["user.read"],
                // Only override if user clicked the retry button
                overrideInteractionInProgress: retryRequested
            };

            setRetryRequested(false); // Reset retry flag

            const response = await instance.loginPopup(loginRequest);
            setShowRetry(false);
        } catch (error) {
            if (error.errorCode === 'interaction_in_progress') {
                // Show retry button - let user decide whether to retry
                setShowRetry(true);
            } else {
                console.error(error);
            }
        }
    };

    const handleRetry = () => {
        setRetryRequested(true); // User explicitly requested retry
        handleLogin();
    };

    return (
        <div>
            <button onClick={handleLogin}>Login</button>
            {showRetry && (
                <button onClick={handleRetry}>
                    Retry Login (Cancel Pending)
                </button>
            )}
        </div>
    );
}

Következő lépések

Ismerje meg, hogyan szerezhet be és használhat hozzáférési jogkivonatot!