Accedi utenti

Prima di iniziare, assicurarsi di comprendere come inizializzare l'oggetto applicazione.

Le API di accesso di MSAL recuperano un authorization code che può essere scambiato con un ID token per un utente autenticato, concedendo al contempo le autorizzazioni per una risorsa aggiuntiva, e con un token di accesso contenente le autorizzazioni a cui l'utente ha acconsentito, per permettere all'app di chiamare l'API in modo sicuro.

Scelta di un tipo di interazione

Vedere qui se si è incerti sulle differenze tra loginRedirect e loginPopup.

Accedere all'utente

È necessario passare un oggetto richiesta alle API di accesso. Questo oggetto consente di usare parametri diversi nella richiesta. Per altre informazioni sui parametri dell'oggetto richiesta, vedere qui .

Per le richieste di accesso, tutti i parametri sono facoltativi, quindi è sufficiente inviare un oggetto vuoto.

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

In alternativa, è possibile inviare un insieme di scope per il preconsenso a:

  • 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
}

API dell'account

Quando una chiamata di accesso ha avuto esito positivo, è possibile usare la getAllAccounts() funzione per recuperare informazioni sugli utenti attualmente connessi.

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

Se si conoscono le informazioni sull'account, è anche possibile recuperare le informazioni sull'account usando l'API getAccount() :

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

Il filtro per username è fornito per comodità e deve essere considerato meno affidabile della ricerca basata su homeAccountId. Se possibile, usare homeAccountId.

Negli scenari B2C, il tenant B2C deve essere configurato per restituire il claim emails in idTokens per poter usare il filtro username sull'API getAccount().

Queste API restituiscono un oggetto account o una matrice di oggetti account con la firma seguente:

{
    // 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;
};

Accesso invisibile con ssoSilent()

Se si dispone già di una sessione esistente con il server di autenticazione, è possibile usare l'API ssoSilent() per effettuare richieste di token senza interazione.

Con suggerimento utente

Se si dispone già delle informazioni di accesso dell'utente, è possibile passarlo all'API per migliorare le prestazioni e assicurarsi che il server di autorizzazione cerchi la sessione dell'account corretta. È possibile passare uno dei seguenti elementi nell'oggetto richiesta per ottenere correttamente un token in modo invisibile all'utente.

Si consiglia di utilizzare l'attestazione facoltativa del token IDlogin_hint (fornita a ssoSilent come loginHint), in quanto è l'indicazione dell'account più affidabile per le richieste silenziose (e interattive).

  • account (che può essere ottenuto tramite una delle API dell'account)
  • sid (che può essere recuperato dal idTokenClaims di un oggetto account)
  • login_hint (può essere recuperato nei modi seguenti)
    • Come proprietà dell'oggetto loginHint account (scelta consigliata)
    • Come attestazione del token ID dell'oggetto account login_hint (scelta consigliata)
    • Come proprietà username dell'oggetto account (non consigliato)
    • Come attestazione del token ID dell'oggetto account upn (non consigliata)

Note

Le username e upn proprietà sono parzialmente supportate al posto della vera e propria dichiarazione login_hint, ma non sono consigliate. Usare le proprietà dell'account loginHint o idTokenClaims.login_hint se disponibili.

Se si passa un account, verrà cercato prima il claim facoltativo del token ID login_hint (preferito), poi il claim facoltativo del token id sid e, in mancanza, si ripiegherà su loginHint (se fornito) oppure sul nome utente dell'account.

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

Senza suggerimento utente

Se non sono disponibili informazioni sufficienti sull'utente, è possibile provare a utilizzare l'API ssoSilentsenza passare un account, sid o login_hint.

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

Tuttavia, tenere presente che se l'applicazione dispone di percorsi di codice per più utenti in una singola sessione del browser o se l'utente ha più account per tale singola sessione del browser, esiste una maggiore probabilità di errori di accesso invisibile all'utente. È possibile che venga visualizzato l'errore seguente in caso di più sessioni di account trovate dal server di autorizzazione:

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

Ciò indica che il server non è riuscito a determinare l'account da accedere e richiederà uno dei parametri precedenti (account, login_hint, sid) o un accesso interattivo per scegliere l'account.

Avvertimento

Quando si usa ssoSilent, il servizio tenta di caricare la pagina dell'URI di reindirizzamento in un iframe incorporato invisibile. I criteri di sicurezza del contenuto e i valori di intestazione HTTP presenti nella risposta della pagina URI di reindirizzamento dell'app, ad esempio X-FRAME-OPTIONS: DENY e X-FRAME-OPTIONS: SAMEORIGIN, possono impedire il caricamento dell'app nell'iframe, bloccando in modo efficace l'accesso SSO invisibile all'utente. Se si intende usare ssoSilent, assicurarsi che l'URI di reindirizzamento punti a una pagina che non implementa tali criteri.

Considerazioni sull'URI di reindirizzamento

Tutti i flussi di autenticazione richiedono ora una pagina di reindirizzamento dedicata che implementa il bridge di reindirizzamento MSAL. Ciò è necessario per supportare le intestazioni COOP (Cross-Origin-Opener-Policy) e abilitare la comunicazione sicura tra finestre popup/iframe e l'applicazione principale.

Configurazione della pagina di reindirizzamento

Il tuo redirectUri deve puntare a una pagina dedicata che carica lo script ponte di reindirizzamento. Questa pagina deve:

  1. Caricare lo script del bridge di reindirizzamento : questo script gestisce la comunicazione con la finestra principale
  2. Non includere javaScript ad eccezione dello script bridge : la pagina di reindirizzamento deve eseguire solo lo script bridge
  3. Non includere la logica di routing : evitare librerie router che potrebbero interferire con la gestione degli hash
  4. Essere registrati nella registrazione dell'app: l'URI deve corrispondere esattamente a ciò che è registrato nel portale di Azure

Pagina di reindirizzamento di esempio (quando si usa un bundler, ad esempio Vite o 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

L'identificatore @azure/msal-browser/redirect-bridge deve essere risolto da un bundler (Vite, Webpack e così via), non è un URL che i browser possono recuperare direttamente. Per istruzioni specifiche del framework, vedere la guida alla configurazione di Redirect Bridge.

Configurazione

È possibile impostare redirectUri globalmente nella configurazione di MSAL o per ogni richiesta:

Configurazione globale:

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

const msalInstance = new PublicClientApplication(msalConfig);

Configurazione per richiesta:

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

Per altre informazioni e per completare le implementazioni di esempio, vedere:

Gestione degli errori popup interaction_in_progress

Per i flussi popup, è possibile usare il overrideInteractionInProgress flag per annullare un'interazione in sospeso e avviarne una nuova. Ciò è utile per gli scenari di ripristino in cui l'utente ha annullato un popup o un'interazione non riuscita.

Note

Questa funzionalità è disponibile solo per i flussi popup e non è supportata per i flussi di reindirizzamento. Con l'intestazione COOP (Cross-Origin-Opener-Policy), la connessione tradizionale window.opener viene interrotta, consentendo alle finestre popup di comunicare con il frame principale solo tramite BroadcastChannel.

Importante

L'impostazione di questa opzione su true comporta l'annullamento forzato di qualsiasi richiesta di autenticazione popup in sospeso, ma non chiuderà i popup aperti.

Se impostato su true:

  • Se è in corso un'altra interazione popup, viene annullata forzatamente, ma tutti i popup aperti non vengono chiusi
  • L'interazione in sospeso si conclude con un errore interaction_in_progress_cancelled
  • Il nuovo flusso del pop-up prosegue immediatamente

Casi d'uso validi:

  • Ripristino da errori in cui l'utente ha annullato un popup (popup è stato chiuso senza completare l'autenticazione)
  • Implementazione di flussi di ripristino degli errori personalizzati
  • Fornire un meccanismo di ripetizione dei tentativi dopo un'interazione popup non riuscita

Predefinito:false

Importante: usare solo al clic del pulsante

Non riprovare automaticamente quando si rileva un interaction_in_progress errore. L'override deve essere attivato solo da un'azione esplicita dell'utente, ad esempio facendo clic su un pulsante "Riprova". La sovrascrittura automatica delle interazioni può causare:

  • Race condition tra più flussi di autenticazione
  • Annullamenti imprevisti di tentativi di autenticazione legittimi
  • Esperienza utente scarsa con i flussi di autenticazione avviati e arrestati in modo imprevisto
  • Numerosi popup aperti che non portano a risposte di autenticazione con esito positivo

Esempio: gestione corretta degli errori con nuovo tentativo avviato dall'utente

Per le implementazioni complete con feedback visivo, vedere:

Entrambi gli esempi illustrano:

  • Messaggio di avviso visualizzato durante l'autenticazione popup
  • Riprovare modale/finestra di dialogo con una spiegazione chiara quando interaction_in_progress si verifica un errore
  • Corretta gestione dello stato per il nuovo tentativo avviato dall'utente
  • Componenti dell'interfaccia utente pronti per la produzione
// 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
}

Esempio: componente React con tentativi attivati dall'utente

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

Operazioni successive

Informazioni su come acquisire e usare un token di accesso.