Secretos de cliente o certificados de cliente
Dado que la aplicación web ahora llama a una API web de nivel inferior, proporcione un secreto de cliente o un certificado de cliente en el archivo appsettings.json. También puede 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
Puede 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 puede usar la propiedad "ClientSecret" y la colección "ClientCredentials".
En lugar de un secreto de cliente, puede 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 olvida cambiar Scopes
a una matriz, cuando intente 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, consulte Microsoft.Identity.Web: uso de certificados en GitHub.
Startup.cs
La aplicación web tiene que adquirir un token para la API de nivel inferior. Para especificarlo, agregue la línea .EnableTokenAcquisitionToCallDownstreamApi()
después de .AddMicrosoftIdentityWebApp(Configuration)
. Esta línea expone el servicio IAuthorizationHeaderProvider
, que puede usar en las acciones del controlador y la página. Sin embargo, como ve en las dos opciones siguientes, se puede hacer de forma más sencilla. También debe 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 especifica 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 elija dependerá de si desea llamar a Microsoft Graph o a otra API.
Opción 1: Llamada a Microsoft Graph
Si desea 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:
Agregue el paquete NuGet Microsoft.Identity.Web.GraphServiceClient a su proyecto.
Agregue .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 desea 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:
Agregue el paquete NuGet Microsoft.Identity.Web.DownstreamApi al proyecto.
Agregue .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, puede elegir varias implementaciones de la memoria caché de tokens. Para más información, consulte 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, proporcione un secreto de cliente o un certificado de cliente en el archivo appsettings.json. También puede 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
Puede 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 puede usar la propiedad "ClientSecret" y la colección "ClientCredentials".
En lugar de un secreto de cliente, puede 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 olvida cambiar Scopes
a una matriz, cuando intente 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, consulte 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 elija dependerá de si desea llamar a Microsoft Graph o a otra API.
Opción 1: Llamada a Microsoft Graph
Si desea 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:
- Agregue el paquete NuGet Microsoft.Identity.Web.GraphServiceClient a su proyecto.
- Agregue
.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 desea 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:
- Agregue el paquete NuGet Microsoft.Identity.Web.DownstreamApi al proyecto.
- Agregue
.AddDownstreamApi()
después de .EnableTokenAcquisitionToCallDownstreamApi()
en el archivo Startup.cs. .AddDownstreamApi()
tiene dos argumentos:
- El nombre de un servicio (API): se 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
Puede elegir varias implementaciones de la memoria caché de tokens. Para más información, consulte 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 desee consultar dicho ejemplo para obtener detalles completos de la implementación.
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.
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);
}
};
}
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 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.
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ía 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.