Applicazione a pagina singola: accesso e disconnessione
Articolo
Prima di poter ottenere token per accedere alle API nell'applicazione, è necessario un contesto utente autenticato. Per autenticare un utente, è possibile usare una finestra popup e/o un metodo di accesso di reindirizzamento.
Se l'applicazione ha accesso a un contesto utente autenticato o a un token ID, è possibile ignorare il passaggio di accesso e acquisire direttamente i token. Per informazioni dettagliate, vedere Single Sign-On (SSO) con hint utente.
Scegliere tra un'esperienza popup o di reindirizzamento
La scelta tra un'esperienza popup o di reindirizzamento dipende dal flusso dell'applicazione.
Usare una finestra popup se non si vuole che gli utenti si spostino dalla pagina principale dell'applicazione durante l'autenticazione. Poiché il reindirizzamento dell'autenticazione si verifica in una finestra popup, lo stato dell'applicazione principale viene mantenuto.
Per richiamare un'esperienza di accesso per una route specifica, importare @angular/router e aggiungere MsalGuard alla definizione di route.
// In app-routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { ProfileComponent } from "./profile/profile.component";
import { MsalGuard } from "@azure/msal-angular";
import { HomeComponent } from "./home/home.component";
const routes: Routes = [
{
path: "profile",
component: ProfileComponent,
canActivate: [MsalGuard],
},
{
path: "",
component: HomeComponent,
},
];
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: false })],
exports: [RouterModule],
})
export class AppRoutingModule {}
Per abilitare un'esperienza di finestra popup, impostare la configurazione interactionType su InteractionType.Popup nel MsalGuardConfiguration. È anche possibile passare gli ambiti che richiedono il consenso.
Per richiamare un'esperienza di accesso quando un utente non è già connesso, usare la funzione MsalAuthenticationTemplate da @azure/msal-react. Il wrapper React MSAL protegge componenti specifici eseguendo il wrapping nel componente MsalAuthenticationTemplate.
import { InteractionType } from "@azure/msal-browser";
import { MsalAuthenticationTemplate, useMsal } from "@azure/msal-react";
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<MsalAuthenticationTemplate interactionType={InteractionType.Popup}>
<p>This will only render if a user is not signed-in.</p>
<WelcomeUser />
</MsalAuthenticationTemplate>
);
}
Per richiamare un'esperienza di accesso specifica in base all'interazione dell'utente (ad esempio, selezionare il pulsante), usare la funzione AuthenticatedTemplate e/o UnauthenticatedTemplate da @azure/msal-react.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signInClickHandler(instance) {
instance.loginPopup();
}
// SignInButton Component returns a button that invokes a popup sign in when clicked
function SignInButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return <button onClick={() => signInClickHandler(instance)}>Sign In</button>;
}
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
<SignInButton />
</UnauthenticatedTemplate>
</>
);
}
const config = {
auth: {
clientId: "your_app_id",
redirectUri: "your_app_redirect_uri", //defaults to application start page
postLogoutRedirectUri: "your_app_logout_redirect_uri",
},
};
const loginRequest = {
scopes: ["User.ReadWrite"],
};
let accountId = "";
const myMsal = new PublicClientApplication(config);
function handleResponse(response) {
if (response !== null) {
accountId = response.account.homeAccountId;
// Display signed-in user content, call API, etc.
} else {
// In case multiple accounts exist, you can select
const currentAccounts = myMsal.getAllAccounts();
if (currentAccounts.length === 0) {
// no accounts signed-in, attempt to sign a user in
myMsal.loginRedirect(loginRequest);
} else if (currentAccounts.length > 1) {
// Add choose account code here
} else if (currentAccounts.length === 1) {
accountId = currentAccounts[0].homeAccountId;
}
}
}
myMsal.handleRedirectPromise().then(handleResponse);
Per abilitare un'esperienza di reindirizzamento, impostare la configurazione interactionType su InteractionType.Redirect nel MsalGuardConfiguration e quindi eseguire il bootstrap di MsalRedirectComponent per gestire i reindirizzamenti.
Per richiamare un'esperienza di accesso quando un utente non è connesso, usare la funzione MsalAuthenticationTemplate da @azure/msal-react.
import { InteractionType } from "@azure/msal-browser";
import { MsalAuthenticationTemplate, useMsal } from "@azure/msal-react";
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<MsalAuthenticationTemplate interactionType={InteractionType.Redirect}>
<p>This will only render if a user is not signed-in.</p>
<WelcomeUser />
</MsalAuthenticationTemplate>
);
}
Per richiamare un'esperienza di accesso specifica in base all'interazione dell'utente (ad esempio, selezionare il pulsante), usare la funzione AuthenticatedTemplate e/o UnauthenticatedTemplate da @azure/msal-react.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signInClickHandler(instance) {
instance.loginRedirect();
}
// SignInButton Component returns a button that invokes a popup login when clicked
function SignInButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return <button onClick={() => signInClickHandler(instance)}>Sign In</button>;
}
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
<SignInButton />
</UnauthenticatedTemplate>
</>
);
}
Comportamento di disconnesso nei browser
Per garantire la disconnessione sicura di una o più app, sono consigliati i metodi seguenti:
Nei dispositivi condivisi, gli utenti devono usare la modalità privata/in incognito di un browser e chiudere tutte le finestre del browser prima di allontanarsi dal dispositivo.
Nei dispositivi che non sono condivisi, gli utenti devono usare una schermata di blocco del sistema operativo per bloccare o disconnettersi dall'intera sessione del sistema operativo nel dispositivo. Microsoft usa la pagina di disconnessione per ricordare agli utenti queste procedure consigliate per la privacy e la sicurezza.
Se un utente sceglie di non disconnettersi usando le raccomandazioni, sono disponibili altri metodi per abilitare la funzionalità di disconnessione:
Disconnessione front channel di OpenID Connect di Microsoft per la disconnessione federata. È possibile usare questa opzione quando un'app condivide uno stato di accesso con una nuova app, ma gestisce i propri token/cookie di sessione. Esistono alcune limitazioni a questa implementazione in cui il contenuto viene bloccato, ad esempio quando i browser bloccano i cookie di terze parti.
Finestra popup e/o un reindirizzamento per la disconnessione dell'app locale. I metodi popup e reindirizzamento terminano la sessione dell'utente nell'endpoint e per l'app locale. Tuttavia, questi metodi potrebbero non cancellare immediatamente la sessione per altre applicazioni federate se la comunicazione front-channel è bloccata.
Disconnettersi con una finestra popup
MSAL.js v2 e versioni successive fornisce un metodo di logoutPopup che cancella la cache nell'archiviazione del browser e apre una finestra popup alla pagina di disconnessione di Microsoft Entra. Dopo la disconnessione, il reindirizzamento viene impostato per impostazione predefinita sulla pagina iniziale di accesso e il popup viene chiuso.
Per l'esperienza di disconnessione, è possibile impostare il postLogoutRedirectUri per reindirizzare l'utente a un URI specifico. Questo URI deve essere registrato come URI di reindirizzamento nella registrazione dell'applicazione. È anche possibile configurare logoutPopup per reindirizzare la finestra principale a una pagina diversa, ad esempio la home page o la pagina di accesso passando mainWindowRedirectUri come parte della richiesta.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signOutClickHandler(instance) {
const logoutRequest = {
account: instance.getAccountByHomeId(homeAccountId),
mainWindowRedirectUri: "your_app_main_window_redirect_uri",
postLogoutRedirectUri: "your_app_logout_redirect_uri",
};
instance.logoutPopup(logoutRequest);
}
// SignOutButton component returns a button that invokes a pop-up sign out when clicked
function SignOutButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return (
<button onClick={() => signOutClickHandler(instance)}>Sign Out</button>
);
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<SignOutButton />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
</UnauthenticatedTemplate>
</>
);
}
Disconnettersi con un reindirizzamento
MSAL.js fornisce un metodo di logout in v1 e un metodo di logoutRedirect in v2 che cancella la cache nell'archiviazione del browser ed esegue il reindirizzamento alla pagina di disconnessione di Microsoft Entra. Dopo la disconnessione, il reindirizzamento viene impostato per impostazione predefinita sulla pagina iniziale di accesso.
Per l'esperienza di disconnessione, è possibile impostare il postLogoutRedirectUri per reindirizzare l'utente a un URI specifico. Questo URI deve essere registrato come URI di reindirizzamento nella registrazione dell'applicazione.
Poiché il promemoria di Microsoft sulle procedure consigliate per la privacy internet sull'uso di un browser privato e della schermata di blocco non viene visualizzato in questo metodo, è possibile descrivere le procedure consigliate e ricordare agli utenti di chiudere tutte le finestre del browser.
const config = {
auth: {
clientId: "your_app_id",
redirectUri: "your_app_redirect_uri", //defaults to application start page
postLogoutRedirectUri: "your_app_logout_redirect_uri",
},
};
const myMsal = new PublicClientApplication(config);
// you can select which account application should sign out
const logoutRequest = {
account: myMsal.getAccountByHomeId(homeAccountId),
};
myMsal.logoutRedirect(logoutRequest);
// In app.module.ts
@NgModule({
imports: [
MsalModule.forRoot( new PublicClientApplication({
auth: {
clientId: 'your_app_id',
postLogoutRedirectUri: 'your_app_logout_redirect_uri'
}
}), null, null)
]
})
// In app.component.ts
logout() {
this.authService.logoutRedirect();
}
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signOutClickHandler(instance) {
const logoutRequest = {
account: instance.getAccountByHomeId(homeAccountId),
postLogoutRedirectUri: "your_app_logout_redirect_uri",
};
instance.logoutRedirect(logoutRequest);
}
// SignOutButton Component returns a button that invokes a redirect logout when clicked
function SignOutButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return (
<button onClick={() => signOutClickHandler(instance)}>Sign Out</button>
);
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<SignOutButton />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
</UnauthenticatedTemplate>
</>
);
}