Secretos de cliente o certificados de cliente
Dado que la aplicación web ahora llama a una API web de nivel inferior, proporciona un secreto de cliente o un certificado de cliente en el archivo appsettings.json. También puedes agregar una sección que especifique:
- La dirección URL de la API web de nivel inferior.
- Los ámbitos necesarios para llamar a la API.
En el ejemplo siguiente, la sección GraphBeta
especifica esta configuración.
{
"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
Puedes proponer una colección de credenciales de cliente, incluida una solución sin credenciales, como la federación de identidades de carga de trabajo para Azure Kubernetes.
Las versiones anteriores de Microsoft.Identity.Web expresaron el secreto de cliente en una sola propiedad "ClientSecret" en lugar de "ClientCredentials". Esto sigue siendo compatible con versiones anteriores, pero no puedes usar la propiedad "ClientSecret" y la colección "ClientCredentials".
En lugar de un secreto de cliente, puedes proporcionar un certificado de cliente. En el fragmento de código siguiente se muestra el uso de un certificado almacenado en 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"]
}
}
Advertencia
Si olvidas cambiar Scopes
a una matriz, cuando intentes usar IDownstreamApi
los ámbitos aparecerán como nulos, y IDownstreamApi
intentará una llamada anónima (sin autenticar) a la API descendente, lo cual resultará en un 401/unauthenticated
.
Microsoft.Identity.Web proporciona varias maneras de describir certificados, tanto mediante configuración como mediante código. Para más información, consulta Microsoft.Identity.Web: uso de certificados en GitHub.
Selecciona el archivo Startup.cs.
La aplicación web tiene que adquirir un token para la API de nivel inferior. Para especificarlo, agrega la línea .EnableTokenAcquisitionToCallDownstreamApi()
después de .AddMicrosoftIdentityWebApp(Configuration)
. Esta línea expone el servicio IAuthorizationHeaderProvider
, que puedes usar en las acciones del controlador y la página. Sin embargo, como ves en las dos opciones siguientes, se puede hacer de forma más sencilla. También debes elegir una implementación de la caché de tokens, por ejemplo .AddInMemoryTokenCaches()
, en 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();
// ...
}
// ...
}
Los ámbitos que se pasan a EnableTokenAcquisitionToCallDownstreamApi
son opcionales y permiten que la aplicación web solicite los ámbitos y el consentimiento del usuario a esos ámbitos cuando inicie sesión. Si no especificas los ámbitos, Microsoft.Identity.Web habilita una experiencia de consentimiento incremental.
Microsoft.Identity.Web ofrece dos mecanismos para llamar a una API web desde una aplicación web sin tener que adquirir un token. La opción que elijas dependerá de si deseas llamar a Microsoft Graph o a otra API.
Opción 1: Llamada a Microsoft Graph
Si deseas llamar a Microsoft Graph, Microsoft.Identity.Web le permite usar directamente GraphServiceClient
(expuesto por el SDK de Microsoft Graph) en las acciones de la API. Para exponer Microsoft Graph:
Agrega el paquete NuGet Microsoft.Identity.Web.GraphServiceClient a tu proyecto.
Agrega .AddMicrosoftGraph()
después de .EnableTokenAcquisitionToCallDownstreamApi()
en el archivo Startup.cs. .AddMicrosoftGraph()
tiene varias invalidaciones. Cuando se utiliza la invalidación que toma una sección de la configuración como parámetro, el código se convierte en:
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();
// ...
}
// ...
}
Opción 2: Llamada a una API web de nivel inferior que no sea Microsoft Graph
Si deseas llamar a una API distinta de Microsoft Graph, Microsoft.Identity.Web le permite usar la interfaz IDownstreamApi
en sus acciones de API. Para usar esta interfaz:
Agrega el paquete NuGet Microsoft.Identity.Web.DownstreamApi al proyecto.
Agrega .AddDownstreamApi()
después de .EnableTokenAcquisitionToCallDownstreamApi()
en el archivo Startup.cs. .AddDownstreamApi()
tiene dos argumentos y se muestra en el fragmento de código siguiente:
- Nombre de un servicio (API), que se usa en las acciones del controlador para hacer referencia a la configuración correspondiente
- una sección de configuración que representa los parámetros usados para llamar a la API web de bajada.
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();
// ...
}
// ...
}
Resumen
Al igual que con las API web, puedes elegir varias implementaciones de la memoria caché de tokens. Para obtener más información, consulta Microsoft.Identity.Web: serialización de la memoria caché de tokens en GitHub.
En la imagen siguiente se muestran las distintas posibilidades de Microsoft.Identity.Web y su efecto en el archivo Startup.cs:
Secretos de cliente o certificados de cliente
Dado que la aplicación web ahora llama a una API web de nivel inferior, proporciona un secreto de cliente o un certificado de cliente en el archivo appsettings.json. También puedes agregar una sección que especifique:
- La dirección URL de la API web de nivel inferior.
- Los ámbitos necesarios para llamar a la API.
En el ejemplo siguiente, la sección GraphBeta
especifica esta configuración.
{
"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
Puedes proponer una colección de credenciales de cliente, incluida una solución sin credenciales, como la federación de identidades de carga de trabajo para Azure Kubernetes.
Las versiones anteriores de Microsoft.Identity.Web expresaron el secreto de cliente en una sola propiedad "ClientSecret" en lugar de "ClientCredentials". Esto sigue siendo compatible con versiones anteriores, pero no puedes usar la propiedad "ClientSecret" y la colección "ClientCredentials".
En lugar de un secreto de cliente, puedes proporcionar un certificado de cliente. En el fragmento de código siguiente se muestra el uso de un certificado almacenado en 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"]
}
}
Advertencia
Si olvidas cambiar Scopes
a una matriz, cuando intentes usar IDownstreamApi
los ámbitos aparecerán como nulos, y IDownstreamApi
intentará una llamada anónima (sin autenticar) a la API descendente, lo cual resultará en un 401/unauthenticated
.
Microsoft.Identity.Web proporciona varias maneras de describir certificados, tanto mediante configuración como mediante código. Para obtener más información, consulta Microsoft.Identity.Web: uso de certificados en GitHub.
Startup.Auth.cs
La aplicación web debe adquirir un token para la API de bajada, Microsoft.Identity.Web proporciona dos mecanismos para llamar a una API web desde una aplicación web. La opción que elijas dependerá de si deseas llamar a Microsoft Graph o a otra API.
Opción 1: Llamada a Microsoft Graph
Si deseas llamar a Microsoft Graph, Microsoft.Identity.Web le permite usar directamente GraphServiceClient
(expuesto por el SDK de Microsoft Graph) en las acciones de la API. Para exponer Microsoft Graph:
- Agrega el paquete NuGet Microsoft.Identity.Web.GraphServiceClient a tu proyecto.
- Agrega
.AddMicrosoftGraph()
a la colección de servicios en el archivo Startup.Auth.cs. .AddMicrosoftGraph()
tiene varias invalidaciones. Cuando se utiliza la invalidación que toma una sección de la configuración como parámetro, el código se convierte en:
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();
}
}
}
Opción 2: Llamada a una API web de nivel inferior que no sea Microsoft Graph
Si deseas llamar a una API distinta de Microsoft Graph, Microsoft.Identity.Web le permite usar la interfaz IDownstreamApi
en sus acciones de API. Para usar esta interfaz:
- Agrega el paquete NuGet Microsoft.Identity.Web.DownstreamApi al proyecto.
- Agrega
.AddDownstreamApi()
después de .EnableTokenAcquisitionToCallDownstreamApi()
en el archivo Startup.cs. .AddDownstreamApi()
tiene dos argumentos:
- El nombre de un servicio (API): usa este nombre en las acciones del controlador para hacer referencia a la configuración correspondiente
- una sección de configuración que representa los parámetros usados para llamar a la API web de bajada.
Este es el código:
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();
}
}
}
Resumen
Puedes elegir varias implementaciones de la memoria caché de tokens. Para obtener más información, consulta Microsoft.Identity.Web: serialización de la memoria caché de tokens en GitHub.
En la imagen siguiente se muestran las distintas posibilidades de Microsoft.Identity.Web y su efecto en el archivo Startup.cs:
Los ejemplos de código de este artículo y el siguiente se han extraído del ejemplo de aplicación web de ASP.NET. Es posible que desees consultar dicho ejemplo para obtener detalles completos de la implementación.
Implementación del ejemplo de código de Java
Los ejemplos de código de este artículo y el siguiente se han extraído de la aplicación web de Java que llama a Microsoft Graph, un ejemplo de aplicación web que usa MSAL para Java.
El ejemplo permite actualmente que MSAL para Java genere la dirección URL del código de autorización y controla la navegación al punto de conexión de autorización para la Plataforma de identidad de Microsoft. También es posible usar la seguridad de Sprint para iniciar la sesión del usuario. Es posible que desee consultar dicho ejemplo para obtener detalles completos de la implementación.
Implementación del ejemplo de código de Node.js
Los ejemplos de código de este artículo y el siguiente se han extraído de la aplicación web de Node.js y Express.js que llama a Microsoft Graph, un ejemplo de aplicación web que usa MSAL Node.
El ejemplo permite actualmente que MSAL Node genere la dirección URL del código de autorización y controla la navegación al punto de conexión de autorización de la Plataforma de identidad de Microsoft. A continuación, aparece esto:
/**
* 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);
}
};
}
Implementación del ejemplo de código de Python
Los fragmentos de código de este artículo y los siguientes se extraen del ejemplo de aplicación web de Python que llama a Microsoft Graph usando el paquete de identidad (un contenedor alrededor de MSAL Python).
El ejemplo usa el paquete de identidad para generar la dirección URL del código de autorización y controla la navegación al punto de conexión de autorización de la plataforma de identidad de Microsoft. Es posible que desee consultar dicho ejemplo para obtener detalles completos de la implementación.
Microsoft.Identity.Web simplifica el código mediante la definición de la configuración correcta de OpenID Connect, la suscripción al evento recibido del código y el canje del código. No es necesario ningún código adicional para canjear el código de autorización. Vea Código fuente de Microsoft.Identity.Web para obtener información detallada sobre cómo funciona esto.
Microsoft.Identity.Web.OWIN simplifica el código mediante la definición de la configuración correcta de OpenID Connect, la suscripción al evento recibido del código y el canje del código. No es necesario ningún código adicional para canjear el código de autorización. Vea Código fuente de Microsoft.Identity.Web para obtener información detallada sobre cómo funciona esto.
El método handleRedirect de la clase AuthProvider procesa el código de autorización recibido de Microsoft Entra ID. A continuación, aparece esto:
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);
}
}
}
Consulte Aplicación web que permite iniciar sesión a los usuarios: configuración del código para comprender cómo el ejemplo de Java obtiene el código de autorización. Una vez que la aplicación recibe el código, AuthFilter.java#L51-L56:
- Delega en el método
AuthHelper.processAuthenticationCodeRedirect
en AuthHelper.java#L67-L97.
- Llama a
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
}
}
El método getAuthResultByAuthCode
se define en AuthHelper.java#L176. Crea un MSAL ConfidentialClientApplication
y luego llama a acquireToken()
con AuthorizationCodeParameters
creado a partir del código de autorización.
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();
}
Consulte Aplicación web que permite iniciar sesión a los usuarios: configuración del código para comprender cómo el ejemplo de Python obtiene el código de autorización.
La pantalla de inicio de sesión de Microsoft envía el código de autorización a la dirección URL /getAToken
especificada en el registro de la aplicación. La ruta auth_response
controla esa dirección URL, llamando a auth.complete_login
para procesar el código de autorización y, a continuación, devuelve un error o redirige a la página principal.
@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"))
Consulte app.py para obtener el contexto completo de ese código.
En lugar de un secreto de cliente, la aplicación cliente confidencial también puede demostrar su identidad mediante un certificado de cliente o una aserción de cliente.
El uso de aserciones de cliente es un escenario avanzado, que se detalla en Aserciones de cliente.
En el tutorial de ASP.NET Core se usa la inserción de dependencias para permitir decidir la implementación de la caché de tokens en el archivo Startup.cs de la aplicación. Microsoft.Identity.Web incluye varios serializadores de caché de tokens pregenerados que se describen en Serialización del almacenamiento en caché de los tokens. Una posibilidad interesante es elegir las cachés de memoria distribuidas de 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";
});
Para información detallada sobre los proveedores de cachés de tokens, vea también el artículo Serialización de la caché de tokens de Microsoft.Identity.Web y el tutorial de la fase de las aplicaciones web de Tutoriales de aplicación web de ASP.NET Core | Cachés de tokens.
En el tutorial de ASP.NET se usa la inserción de dependencias para permitir decidir la implementación de la caché de tokens en el archivo Startup.Auth.cs de la aplicación. Microsoft.Identity.Web incluye varios serializadores de caché de tokens pregenerados que se describen en Serialización del almacenamiento en caché de los tokens. Una posibilidad interesante es elegir las cachés de memoria distribuidas de 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";
});
Para obtener información detallada sobre los proveedores de cachés de tokens, consulte también el artículo Microsoft.Identity.Web Serialización de caché de token y la fase tutoriales de aplicación web de ASP.NET Core | Cachés de tokens del tutorial de la aplicación web.
Para más información, vea Serialización de la memoria caché de tokens en MASL.NET.
Java de MSAL proporciona métodos para serializar y deserializar la caché de tokens. En el ejemplo de Java se controla la serialización de la sesión, como se muestra en el método getAuthResultBySilentFlow
de 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;
}
Los detalles de la clase SessionManagementHelper
se proporcionan en el ejemplo de MSAL para Java.
En el ejemplo de Node.js, la sesión de una aplicación se usa para almacenar la caché de tokens. Mediante los métodos de caché de MSAL Node, la caché de tokens en sesión se lee antes de que se realice una solicitud de tokens y, a continuación, se actualiza una vez que la solicitud de tokens se ha completado correctamente. A continuación, aparece esto:
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);
}
};
}
En el ejemplo de Python, el paquete de identidad se encarga de la caché de tokens mediante el objeto global session
para el almacenamiento.
Flask tiene compatibilidad integrada con sesiones almacenadas en una cookie, pero debido a la longitud de las cookies de identidad, el ejemplo usará el paquete Flask-session en su lugar. Todo se inicializa en 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"],
)
Debido a la configuración de SESSION_TYPE="filesystem"
en app_config.py
, el paquete Flask-session almacenará las sesiones mediante el sistema de archivos local.
Para producción, deberías usar una configuración que persista en varias instancias e implementaciones de la aplicación, como "sqlachemy" o "redis".
En este momento, cuando el usuario inicia sesión, un token se almacena en la caché de tokens. A continuación, veremos cómo se usa en otras partes de la aplicación web.