Questo articolo illustra come configurare il codice dell'applicazione e modificare l'app Web in modo che non solo consenta agli utenti di accedere, ma anche di chiamare le API Web. L'applicazione creata usa il flusso del codice di autorizzazione OAuth 2.0 per consentire l'accesso dell'utente. Il flusso include due passaggi:
Segreti del client o certificati del client
Dato che l'app Web chiama un'API Web downstream, fornisci un segreto client o un certificato client nel file appsettings.json. È anche possibile aggiungere una sezione che specifica:
- URL dell'API Web downstream
- Ambiti necessari per chiamare l'API
Nell'esempio seguente la GraphBeta sezione specifica queste impostazioni.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret":"[Enter_the_Client_Secret_Here]"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Nota
È possibile proporre una raccolta di credenziali client, inclusa una soluzione senza credenziali, ad esempio la federazione delle identità del carico di lavoro per Azure Kubernetes.
Le versioni precedenti di Microsoft.Identity.Web hanno espresso il segreto client in una singola proprietà "ClientSecret" anziché "ClientCredentials". Questa opzione è ancora supportata per la compatibilità con le versioni precedenti, ma non è possibile usare sia la proprietà "ClientSecret" che l'insieme "ClientCredentials".
Anziché un segreto client, è possibile fornire un certificato client. Il frammento di codice seguente illustra l'uso di un certificato archiviato in Azure Key Vault.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Avviso
Se si dimentica di modificare l'Scopes in un array, quando si tenta di usare i IDownstreamApi gli scope verranno visualizzati come null e IDownstreamApi tenterà una chiamata anonima (non autenticata) all'API downstream, che genererà un 401/unauthenticated.
Microsoft.Identity.Web offre diversi modi per descrivere i certificati, sia per configurazione che per codice. Per informazioni dettagliate, vedere Microsoft.Identity.Web - Uso dei certificati in GitHub.
Modificare il file Startup.cs
L'app Web deve acquisire un token per l'API downstream. È necessario specificarlo aggiungendo la .EnableTokenAcquisitionToCallDownstreamApi() riga dopo .AddMicrosoftIdentityWebApp(Configuration). Questa riga espone il servizio IAuthorizationHeaderProvider che puoi usare nelle azioni del controller e della pagina. Tuttavia, come si vede nelle due opzioni seguenti, può essere fatto più semplicemente. È anche necessario scegliere un'implementazione della cache dei token, ad esempio .AddInMemoryTokenCaches(), in Startup.cs:
using Microsoft.Identity.Web;
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
.AddInMemoryTokenCaches();
// ...
}
// ...
}
Gli ambiti passati a EnableTokenAcquisitionToCallDownstreamApi sono facoltativi e consentono alla tua app Web di richiedere gli ambiti e ottenere il consenso dell'utente per tali ambiti quando effettuano l'accesso. Se non si specificano gli ambiti, Microsoft.Identity.Web abilita un'esperienza di consenso incrementale.
Microsoft.Identity.Web offre due meccanismi per chiamare un'API Web da un'app Web senza dover acquisire un token. L'opzione scelta dipende dal fatto che si voglia chiamare Microsoft Graph o un'altra API.
Opzione 1: Chiamare Microsoft Graph
Se si vuole chiamare Microsoft Graph, Microsoft.Identity.Web consente di usare direttamente l'SDK di Microsoft Graph nelle azioni API (esposto da GraphServiceClient). Per esporre Microsoft Graph:
Aggiungere il pacchetto NuGet Microsoft.Identity.Web.GraphServiceClient al progetto.
Aggiungere .AddMicrosoftGraph() dopo .EnableTokenAcquisitionToCallDownstreamApi() nel file Startup.cs .
.AddMicrosoftGraph() ha diverse ridefinizioni. Usando l'override che accetta una sezione di configurazione come parametro, il codice diventa:
using Microsoft.Identity.Web;
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
.AddMicrosoftGraph(Configuration.GetSection("GraphBeta"))
.AddInMemoryTokenCaches();
// ...
}
// ...
}
Opzione 2: Chiamare un'API Web downstream diversa da Microsoft Graph
Se si vuole chiamare un'API diversa da Microsoft Graph, Microsoft.Identity.Web consente di usare l'interfaccia nelle azioni dell'API IDownstreamApi . Per usare questa interfaccia:
Aggiungere il pacchetto NuGet Microsoft.Identity.Web.DownstreamApi al progetto.
Aggiungere .AddDownstreamApi() dopo .EnableTokenAcquisitionToCallDownstreamApi() nel file Startup.cs .
.AddDownstreamApi() ha due argomenti ed è illustrato nel frammento di codice seguente:
- Nome di un servizio (API), usato nelle azioni del controller per fare riferimento alla configurazione corrispondente
- sezione di configurazione che rappresenta i parametri usati per chiamare l'API Web downstream.
using Microsoft.Identity.Web;
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
.AddDownstreamApi("MyApi", Configuration.GetSection("GraphBeta"))
.AddInMemoryTokenCaches();
// ...
}
// ...
}
Riepilogo
Come per le API Web, è possibile scegliere varie implementazioni della cache dei token. Per informazioni dettagliate, vedere Microsoft.Identity.Web - Serializzazione della cache dei token in GitHub.
L'immagine seguente mostra le varie possibilità di Microsoft.Identity.Web e il relativo effetto sul file Startup.cs :
Segreti del client o certificati del client
Dato che l'app Web chiama un'API Web downstream, fornisci un segreto client o un certificato client nel file appsettings.json. È anche possibile aggiungere una sezione che specifica:
- URL dell'API Web downstream
- Ambiti necessari per chiamare l'API
Nell'esempio seguente la GraphBeta sezione specifica queste impostazioni.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret":"[Enter_the_Client_Secret_Here]"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Nota
È possibile proporre una raccolta di credenziali client, inclusa una soluzione senza credenziali, ad esempio la federazione delle identità del carico di lavoro per Azure Kubernetes.
Le versioni precedenti di Microsoft.Identity.Web hanno espresso il segreto client in una singola proprietà "ClientSecret" anziché "ClientCredentials". Questa opzione è ancora supportata per la compatibilità con le versioni precedenti, ma non è possibile usare sia la proprietà "ClientSecret" che l'insieme "ClientCredentials".
Anziché un segreto client, è possibile fornire un certificato client. Il frammento di codice seguente illustra l'uso di un certificato archiviato in Azure Key Vault.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Enter_the_Application_Id_Here]",
"TenantId": "common",
// To call an API
"ClientCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
},
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": ["user.read"]
}
}
Avviso
Se si dimentica di modificare l'Scopes in un array, quando si tenta di usare i IDownstreamApi gli scope verranno visualizzati come null e IDownstreamApi tenterà una chiamata anonima (non autenticata) all'API downstream, che genererà un 401/unauthenticated.
Microsoft.Identity.Web offre diversi modi per descrivere i certificati, sia per configurazione che per codice. Per informazioni dettagliate, vedere Microsoft.Identity.Web - Uso dei certificati in GitHub.
Startup.Auth.cs
L'app Web deve acquisire un token per l'API downstream, Microsoft.Identity.Web offre due meccanismi per chiamare un'API Web da un'app Web. L'opzione scelta dipende dal fatto che si voglia chiamare Microsoft Graph o un'altra API.
Opzione 1: Chiamare Microsoft Graph
Se si vuole chiamare Microsoft Graph, Microsoft.Identity.Web consente di usare direttamente l'SDK di Microsoft Graph nelle azioni API (esposto da GraphServiceClient). Per esporre Microsoft Graph:
- Aggiungere il pacchetto NuGet Microsoft.Identity.Web.GraphServiceClient al progetto.
- Aggiungere
.AddMicrosoftGraph() alla raccolta di servizi nel file Startup.Auth.cs .
.AddMicrosoftGraph() ha diverse ridefinizioni. Usando l'override che accetta una sezione di configurazione come parametro, il codice diventa:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.IdentityModel.Validators;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
namespace WebApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// Get an TokenAcquirerFactory specialized for OWIN
OwinTokenAcquirerFactory owinTokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
// Configure the web app.
app.AddMicrosoftIdentityWebApp(owinTokenAcquirerFactory,
updateOptions: options => {});
// Add the services you need.
owinTokenAcquirerFactory.Services
.Configure<ConfidentialClientApplicationOptions>(options =>
{ options.RedirectUri = "https://localhost:44326/"; })
.AddMicrosoftGraph()
.AddInMemoryTokenCaches();
owinTokenAcquirerFactory.Build();
}
}
}
Opzione 2: Chiamare un'API Web downstream diversa da Microsoft Graph
Se si vuole chiamare un'API diversa da Microsoft Graph, Microsoft.Identity.Web consente di usare l'interfaccia nelle azioni dell'API IDownstreamApi . Per usare questa interfaccia:
- Aggiungere il pacchetto NuGet Microsoft.Identity.Web.DownstreamApi al progetto.
- Aggiungere
.AddDownstreamApi() dopo .EnableTokenAcquisitionToCallDownstreamApi() nel file Startup.cs .
.AddDownstreamApi() ha due argomenti:
- Nome di un servizio (API): questo nome viene usato nelle azioni del controller per fare riferimento alla configurazione corrispondente
- sezione di configurazione che rappresenta i parametri usati per chiamare l'API Web downstream.
Ecco il codice:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.IdentityModel.Validators;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
namespace WebApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// Get a TokenAcquirerFactory specialized for OWIN.
OwinTokenAcquirerFactory owinTokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
// Configure the web app.
app.AddMicrosoftIdentityWebApp(owinTokenAcquirerFactory,
updateOptions: options => {});
// Add the services you need.
owinTokenAcquirerFactory.Services
.Configure<ConfidentialClientApplicationOptions>(options =>
{ options.RedirectUri = "https://localhost:44326/"; })
.AddDownstreamApi("Graph", owinTokenAcquirerFactory.Configuration.GetSection("GraphBeta"))
.AddInMemoryTokenCaches();
owinTokenAcquirerFactory.Build();
}
}
}
Riepilogo
È possibile scegliere varie implementazioni della cache dei token. Per informazioni dettagliate, vedere Microsoft.Identity.Web - Serializzazione della cache dei token in GitHub.
L'immagine seguente mostra le varie possibilità di Microsoft.Identity.Web e il relativo effetto sul file Startup.cs :
Gli esempi di codice di questo articolo e di quello successivo sono tratti dall'esempio di app Web ASP.NET. È possibile fare riferimento all'esempio per i dettagli di implementazione completi.
Implementare l'esempio di codice Java
Gli esempi di codice di questo articolo e di quello successivo sono tratti dall'applicazione Web Java che chiama Microsoft Graph, un esempio di app Web che usa MSAL per Java.
L'esempio consente attualmente a MSAL per Java di produrre l'URL del codice di autorizzazione e gestisce la navigazione all'endpoint di autorizzazione per Microsoft Identity Platform. È anche possibile usare la sicurezza Sprint per l'accesso dell'utente. È possibile fare riferimento all'esempio per i dettagli di implementazione completi.
Implementare l'esempio di codice Node.js
Gli esempi di codice in questo articolo e i seguenti vengono estratti dall'applicazione Web Node.js & Express.js che chiama Microsoft Graph, un esempio di app Web che usa MSAL Node.
L'esempio consente attualmente a MSAL Node di produrre l'URL del codice di autorizzazione e gestisce la navigazione all'endpoint di autorizzazione per Microsoft Identity Platform. Di seguito è riportato quanto segue:
/**
* Prepares the auth code request parameters and initiates the first leg of auth code flow
* @param req: Express request object
* @param res: Express response object
* @param next: Express next function
* @param authCodeUrlRequestParams: parameters for requesting an auth code url
* @param authCodeRequestParams: parameters for requesting tokens using auth code
*/
redirectToAuthCodeUrl(authCodeUrlRequestParams, authCodeRequestParams, msalInstance) {
return async (req, res, next) => {
// Generate PKCE Codes before starting the authorization flow
const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes();
// Set generated PKCE codes and method as session vars
req.session.pkceCodes = {
challengeMethod: 'S256',
verifier: verifier,
challenge: challenge,
};
/**
* By manipulating the request objects below before each request, we can obtain
* auth artifacts with desired claims. For more information, visit:
* https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest
* https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationcoderequest
**/
req.session.authCodeUrlRequest = {
...authCodeUrlRequestParams,
responseMode: msal.ResponseMode.FORM_POST, // recommended for confidential clients
codeChallenge: req.session.pkceCodes.challenge,
codeChallengeMethod: req.session.pkceCodes.challengeMethod,
};
req.session.authCodeRequest = {
...authCodeRequestParams,
code: '',
};
try {
const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
res.redirect(authCodeUrlResponse);
} catch (error) {
next(error);
}
};
}
Implementare l'esempio di codice Python
I frammenti di codice in questo articolo e nei successivi sono estratti dal campione Python web application calling Microsoft Graph utilizzando il pacchetto identity (un wrapper per MSAL Python).
L'esempio usa il pacchetto di identità per produrre l'URL del codice di autorizzazione e gestisce la navigazione all'endpoint di autorizzazione per Microsoft Identity Platform. È possibile fare riferimento all'esempio per i dettagli di implementazione completi.
Microsoft.Identity.Web semplifica il codice specificando le impostazioni corrette di OpenID Connect, sottoscrivendo l'evento di ricezione del codice e riscattando il codice. Non è necessario alcun codice aggiuntivo per riscattare il codice di autorizzazione. Per informazioni dettagliate su come funziona, vedere Codice sorgente Microsoft.Identity.Web.
Microsoft.Identity.Web.OWIN semplifica il codice impostando le impostazioni corrette di OpenID Connect, registrandosi all'evento di ricezione del codice e riscattando il codice. Non è necessario alcun codice aggiuntivo per riscattare il codice di autorizzazione. Per informazioni dettagliate su come funziona, vedere Codice sorgente Microsoft.Identity.Web.
Il metodo handleRedirect nella classe AuthProvider elabora il codice di autorizzazione ricevuto dall'ID Microsoft Entra. Di seguito è riportato quanto segue:
handleRedirect(options = {}) {
return async (req, res, next) => {
if (!req.body || !req.body.state) {
return next(new Error('Error: response not found'));
}
const authCodeRequest = {
...req.session.authCodeRequest,
code: req.body.code,
codeVerifier: req.session.pkceCodes.verifier,
};
try {
const msalInstance = this.getMsalInstance(this.msalConfig);
if (req.session.tokenCache) {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
}
const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.idToken = tokenResponse.idToken;
req.session.account = tokenResponse.account;
req.session.isAuthenticated = true;
const state = JSON.parse(this.cryptoProvider.base64Decode(req.body.state));
res.redirect(state.successRedirect);
} catch (error) {
next(error);
}
}
}
Dopo che l'app riceve il codice di autorizzazione, il AuthFilter.java#L51-L56:
- Delega al metodo
AuthHelper.processAuthenticationCodeRedirect in AuthHelper.java#L67-L97.
- Chiama
getAuthResultByAuthCode.
class AuthHelper {
// Code omitted
void processAuthenticationCodeRedirect(HttpServletRequest httpRequest, String currentUri, String fullUrl)
throws Throwable {
// Code omitted
AuthenticationResponse authResponse = AuthenticationResponseParser.parse(new URI(fullUrl), params);
// Code omitted
IAuthenticationResult result = getAuthResultByAuthCode(
httpRequest,
oidcResponse.getAuthorizationCode(),
currentUri);
// Code omitted
}
}
Il metodo getAuthResultByAuthCode è definito in AuthHelper.java#L176. Crea un MSAL ConfidentialClientApplication e poi chiama acquireToken() utilizzando AuthorizationCodeParameters, creato dal codice di autorizzazione.
private IAuthenticationResult getAuthResultByAuthCode(
HttpServletRequest httpServletRequest,
AuthorizationCode authorizationCode,
String currentUri) throws Throwable {
IAuthenticationResult result;
ConfidentialClientApplication app;
try {
app = createClientApplication();
String authCode = authorizationCode.getValue();
AuthorizationCodeParameters parameters = AuthorizationCodeParameters.builder(
authCode,
new URI(currentUri)).
build();
Future<IAuthenticationResult> future = app.acquireToken(parameters);
result = future.get();
} catch (ExecutionException e) {
throw e.getCause();
}
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
SessionManagementHelper.storeTokenCacheInSession(httpServletRequest, app.tokenCache().serialize());
return result;
}
private ConfidentialClientApplication createClientApplication() throws MalformedURLException {
return ConfidentialClientApplication.builder(clientId, ClientCredentialFactory.create(clientSecret)).
authority(authority).
build();
}
Vedere Esercitazione: Registrare gli utenti in un'app Web Python Flask usando Microsoft identity platform
La schermata di accesso Microsoft invia il codice di autorizzazione all'URL /getAToken specificato nella registrazione dell'app. La auth_response route gestisce tale URL, chiamando auth.complete_login per elaborare il codice di autorizzazione e quindi restituendo un errore o reindirizzando alla home page.
@app.route(app_config.REDIRECT_PATH)
def auth_response():
result = auth.complete_log_in(request.args)
if "error" in result:
return render_template("auth_error.html", result=result)
return redirect(url_for("index"))
Vedere app.py per il contesto completo del codice.
Anziché un segreto client, l'applicazione client riservata può anche dimostrare la propria identità usando un certificato client o un'asserzione client.
L'uso di asserzioni client è uno scenario avanzato descritto in Asserzioni client.
L'esercitazione di ASP.NET Core usa l'iniezione delle dipendenze per consentire di decidere l'implementazione della cache dei token nel file Startup.cs della tua applicazione. Microsoft.Identity.Web viene fornito con serializzatori predefiniti della cache dei token descritti in Serializzazione della cache dei token. Una possibilità interessante è scegliere le cache di memoria distribuita di ASP.NET Core:
// Use a distributed token cache by adding:
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(
initialScopes: new string[] { "user.read" })
.AddDistributedTokenCaches();
// Then, choose your implementation.
// For instance, the distributed in-memory cache (not cleared when you stop the app):
services.AddDistributedMemoryCache();
// Or a Redis cache:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
// Or even a SQL Server token cache:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = _config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Per dettagli sui provider di cache dei token, vedere anche l'articolo di Microsoft.Identity.Web sulla serializzazione della cache dei token e la fase memorizzazione nella cache dei token delle esercitazioni sull'app Web di ASP.NET Core.
L'esercitazione ASP.NET usa l'injection delle dipendenze per consentirti di decidere l'implementazione della cache dei token nel file Startup.Auth.cs della tua applicazione.
Microsoft.Identity.Web viene fornito con serializzatori predefiniti della cache dei token descritti in Serializzazione della cache dei token. Una possibilità interessante è scegliere le cache di memoria distribuita di ASP.NET Core:
var services = owinTokenAcquirerFactory.Services;
// Use a distributed token cache by adding:
services.AddDistributedTokenCaches();
// Then, choose your implementation.
// For instance, the distributed in-memory cache (not cleared when you stop the app):
services.AddDistributedMemoryCache();
// Or a Redis cache:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
// Or even a SQL Server token cache:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = _config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Per informazioni dettagliate sui provider di cache dei token, vedere anche l'articolo Microsoft.Identity.WebSerializzazione della cache dei token e la fase Cache dei token delle esercitazioni sull'app Web di ASP.NET Core.
Per informazioni dettagliate, vedere Serializzazione della cache dei token per MSAL.NET.
MSAL Java offre metodi per serializzare e deserializzare la cache dei token. L'esempio Java gestisce la serializzazione dalla sessione, come mostrato nel metodo getAuthResultBySilentFlow in AuthHelper.java#L99-L122:
IAuthenticationResult getAuthResultBySilentFlow(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
throws Throwable {
IAuthenticationResult result = SessionManagementHelper.getAuthSessionObject(httpRequest);
IConfidentialClientApplication app = createClientApplication();
Object tokenCache = httpRequest.getSession().getAttribute("token_cache");
if (tokenCache != null) {
app.tokenCache().deserialize(tokenCache.toString());
}
SilentParameters parameters = SilentParameters.builder(
Collections.singleton("User.Read"),
result.account()).build();
CompletableFuture<IAuthenticationResult> future = app.acquireTokenSilently(parameters);
IAuthenticationResult updatedResult = future.get();
// Update session with latest token cache.
SessionManagementHelper.storeTokenCacheInSession(httpRequest, app.tokenCache().serialize());
return updatedResult;
}
Il dettaglio della classe SessionManagementHelper viene fornito nell'esempio MSAL per Java.
Nell'esempio di Node.js viene usata la sessione dell'applicazione per archiviare la cache dei token. Usando i metodi della cache del nodo MSAL, la cache dei token nella sessione viene letta prima dell'esecuzione di una richiesta di token e quindi aggiornata al termine della richiesta di token. Di seguito è riportato quanto segue:
acquireToken(options = {}) {
return async (req, res, next) => {
try {
const msalInstance = this.getMsalInstance(this.msalConfig);
/**
* If a token cache exists in the session, deserialize it and set it as the
* cache for the new MSAL CCA instance. For more, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
*/
if (req.session.tokenCache) {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
}
const tokenResponse = await msalInstance.acquireTokenSilent({
account: req.session.account,
scopes: options.scopes || [],
});
/**
* On successful token acquisition, write the updated token
* cache back to the session. For more, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
*/
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.accessToken = tokenResponse.accessToken;
req.session.idToken = tokenResponse.idToken;
req.session.account = tokenResponse.account;
res.redirect(options.successRedirect);
} catch (error) {
if (error instanceof msal.InteractionRequiredAuthError) {
return this.login({
scopes: options.scopes || [],
redirectUri: options.redirectUri,
successRedirect: options.successRedirect || '/',
})(req, res, next);
}
next(error);
}
};
}
Nell'esempio Python, il pacchetto di identità si occupa della cache dei token, usando l'oggetto globale session per l'archiviazione.
Flask include il supporto predefinito per le sessioni archiviate in un cookie, ma a causa della lunghezza dei cookie di identità, l'esempio usa invece il pacchetto Flask-session . Tutto viene inizializzato in app.py:
import identity
import identity.web
import requests
from flask import Flask, redirect, render_template, request, session, url_for
from flask_session import Session
import app_config
app = Flask(__name__)
app.config.from_object(app_config)
Session(app)
auth = identity.web.Auth(
session=session,
authority=app.config["AUTHORITY"],
client_id=app.config["CLIENT_ID"],
client_credential=app.config["CLIENT_SECRET"],
)
A causa dell'impostazione SESSION_TYPE="filesystem" in app_config.py, il pacchetto Flask-session archivia le sessioni usando il file system locale.
Per la produzione, dovresti usare un'impostazione che persiste tra più istanze e distribuzioni della tua app, come "sqlalchemy" o "redis".
A questo punto, quando l'utente esegue l'accesso, viene archiviato un token nella cache dei token. Viene ora descritto come viene usato in altre parti dell'app Web.