Segredos do cliente ou certificados do cliente
Como seu aplicativo Web agora chama uma API da Web downstream, forneça um segredo do cliente ou um certificado de cliente no arquivo appsettings.json . Você também pode adicionar uma seção que especifique:
- O URL da API Web downstream
- Os escopos necessários para chamar a API
No exemplo a seguir, a GraphBeta
seção especifica essas configurações.
{
"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
Você pode propor uma coleção de credenciais de cliente, incluindo uma solução sem credenciais, como federação de identidade de carga de trabalho para Kubernetes do Azure.
Versões anteriores do Microsoft.Identity.Web expressavam o segredo do cliente em uma única propriedade "ClientSecret" em vez de "ClientCredentials". Isso ainda é suportado para compatibilidade com versões anteriores, mas você não pode usar a propriedade "ClientSecret" e a coleção "ClientCredentials".
Em vez de um segredo do cliente, você pode fornecer um certificado de cliente. O trecho de código a seguir mostra o uso de um certificado armazenado no Cofre de Chaves do Azure.
{
"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"]
}
}
Aviso
Se você esquecer de alterar o Scopes
para uma matriz, quando tentar usar os IDownstreamApi
escopos aparecerá nulo e IDownstreamApi
tentará uma chamada anônima (não autenticada) para a API downstream, o que resultará em um 401/unauthenticated
arquivo .
Microsoft.Identity.Web fornece várias maneiras de descrever certificados, tanto por configuração quanto por código. Para obter detalhes, consulte Microsoft.Identity.Web - Usando certificados no GitHub.
Modificar o arquivo Startup.cs
Seu aplicativo Web precisa adquirir um token para a API downstream. Para especificar, adicione a .EnableTokenAcquisitionToCallDownstreamApi()
linha após .AddMicrosoftIdentityWebApp(Configuration)
. Esta linha expõe o IAuthorizationHeaderProvider
serviço que você pode usar em suas ações de controlador e página. No entanto, como você vê nas duas opções a seguir, isso pode ser feito de forma mais simples. Você também precisa escolher uma implementação de cache de token, por exemplo .AddInMemoryTokenCaches()
, em 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();
// ...
}
// ...
}
Os escopos passados para EnableTokenAcquisitionToCallDownstreamApi
são opcionais e permitem que seu aplicativo Web solicite os escopos e o consentimento do usuário para esses escopos quando entrar. Se você não especificar os escopos, Microsoft.Identity.Web habilitará uma experiência de consentimento incremental.
Microsoft.Identity.Web oferece dois mecanismos para chamar uma API Web de um aplicativo Web sem que você precise adquirir um token. A opção escolhida depende se você deseja chamar o Microsoft Graph ou outra API.
Opção 1: Chamar o Microsoft Graph
Se você quiser chamar o Microsoft Graph, Microsoft.Identity.Web permite que você use diretamente o GraphServiceClient
(exposto pelo SDK do Microsoft Graph) em suas ações de API. Para expor o Microsoft Graph:
Adicione o pacote NuGet Microsoft.Identity.Web.GraphServiceClient ao seu projeto.
Adicione .AddMicrosoftGraph()
depois .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs . .AddMicrosoftGraph()
tem várias substituições. Usando a substituição que usa uma seção de configuração como parâmetro, o código se torna:
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();
// ...
}
// ...
}
Opção 2: Chamar uma API da Web downstream diferente do Microsoft Graph
Se você quiser chamar uma API diferente do Microsoft Graph, Microsoft.Identity.Web permitirá que você use a interface em suas ações de IDownstreamApi
API. Para usar esta interface:
Adicione o pacote NuGet Microsoft.Identity.Web.DownstreamApi ao seu projeto.
Adicione .AddDownstreamApi()
depois .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs . .AddDownstreamApi()
tem dois argumentos e é mostrado no seguinte trecho:
- O nome de um serviço (API), que é usado nas ações do controlador para fazer referência à configuração correspondente
- uma seção de configuração que representa os parâmetros usados para chamar a API da 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();
// ...
}
// ...
}
Resumo
Assim como nas APIs da Web, você pode escolher várias implementações de cache de token. Para obter detalhes, consulte Microsoft.Identity.Web - Serialização de cache de token no GitHub.
A imagem a seguir mostra as várias possibilidades de Microsoft.Identity.Web e seu efeito no arquivo Startup.cs :
Segredos do cliente ou certificados do cliente
Como seu aplicativo Web agora chama uma API da Web downstream, forneça um segredo do cliente ou um certificado de cliente no arquivo appsettings.json . Você também pode adicionar uma seção que especifique:
- O URL da API Web downstream
- Os escopos necessários para chamar a API
No exemplo a seguir, a GraphBeta
seção especifica essas configurações.
{
"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
Você pode propor uma coleção de credenciais de cliente, incluindo uma solução sem credenciais, como federação de identidade de carga de trabalho para Kubernetes do Azure.
Versões anteriores do Microsoft.Identity.Web expressavam o segredo do cliente em uma única propriedade "ClientSecret" em vez de "ClientCredentials". Isso ainda é suportado para compatibilidade com versões anteriores, mas você não pode usar a propriedade "ClientSecret" e a coleção "ClientCredentials".
Em vez de um segredo do cliente, você pode fornecer um certificado de cliente. O trecho de código a seguir mostra o uso de um certificado armazenado no Cofre de Chaves do Azure.
{
"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"]
}
}
Aviso
Se você esquecer de alterar o Scopes
para uma matriz, quando tentar usar os IDownstreamApi
escopos aparecerá nulo e IDownstreamApi
tentará uma chamada anônima (não autenticada) para a API downstream, o que resultará em um 401/unauthenticated
arquivo .
Microsoft.Identity.Web fornece várias maneiras de descrever certificados, tanto por configuração quanto por código. Para obter detalhes, consulte Microsoft.Identity.Web - Usando certificados no GitHub.
Startup.Auth.cs
Seu aplicativo Web precisa adquirir um token para a API downstream, Microsoft.Identity.Web fornece dois mecanismos para chamar uma API Web de um aplicativo Web. A opção escolhida depende se você deseja chamar o Microsoft Graph ou outra API.
Opção 1: Chamar o Microsoft Graph
Se você quiser chamar o Microsoft Graph, Microsoft.Identity.Web permite que você use diretamente o GraphServiceClient
(exposto pelo SDK do Microsoft Graph) em suas ações de API. Para expor o Microsoft Graph:
- Adicione o pacote NuGet Microsoft.Identity.Web.GraphServiceClient ao seu projeto.
- Adicione
.AddMicrosoftGraph()
à coleção de serviços no arquivo Startup.Auth.cs . .AddMicrosoftGraph()
tem várias substituições. Usando a substituição que usa uma seção de configuração como parâmetro, o código se torna:
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();
}
}
}
Opção 2: Chamar uma API da Web downstream diferente do Microsoft Graph
Se você quiser chamar uma API diferente do Microsoft Graph, Microsoft.Identity.Web permitirá que você use a interface em suas ações de IDownstreamApi
API. Para usar esta interface:
- Adicione o pacote NuGet Microsoft.Identity.Web.DownstreamApi ao seu projeto.
- Adicione
.AddDownstreamApi()
depois .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs . .AddDownstreamApi()
tem dois argumentos:
- O nome de um serviço (API): você usa esse nome nas ações do controlador para fazer referência à configuração correspondente
- uma seção de configuração que representa os parâmetros usados para chamar a API da Web downstream.
Aqui está o 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();
}
}
}
Resumo
Você pode escolher várias implementações de cache de token. Para obter detalhes, consulte Microsoft.Identity.Web - Serialização de cache de token no GitHub.
A imagem a seguir mostra as várias possibilidades de Microsoft.Identity.Web e seu efeito no arquivo Startup.cs :
Exemplos de código neste artigo e no seguinte são extraídos do exemplo de aplicativo Web ASP.NET. Talvez você queira consultar esse exemplo para obter detalhes completos da implementação.
Implementar o exemplo de código Java
Exemplos de código neste artigo e no seguinte são extraídos do aplicativo Web Java que chama o Microsoft Graph, um exemplo de aplicativo Web que usa MSAL para Java.
O exemplo atualmente permite que o MSAL for Java produza a URL do código de autorização e manipule a navegação até o ponto de extremidade de autorização para a plataforma de identidade da Microsoft. Também é possível usar a segurança da Sprint para fazer login no usuário. Talvez você queira consultar o exemplo para obter detalhes completos da implementação.
Implementar o exemplo de código Node.js
Exemplos de código neste artigo e no seguinte são extraídos do Node.js & Express.js aplicativo Web que chama o Microsoft Graph, um exemplo de aplicativo Web que usa o nó MSAL.
O exemplo atualmente permite que o MSAL Node produza a URL do código de autorização e manipula a navegação para o ponto de extremidade de autorização para a plataforma de identidade da Microsoft. Isso é mostrado abaixo:
/**
* 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);
}
};
}
Implementar o exemplo de código Python
Trechos de código neste artigo e os seguintes são extraídos do aplicativo Web Python chamando o exemplo Microsoft Graph usando o pacote de identidade (um wrapper em torno do MSAL Python).
O exemplo usa o pacote de identidade para produzir a URL do código de autorização e manipula a navegação para o ponto de extremidade de autorização para a plataforma de identidade da Microsoft. Talvez você queira consultar o exemplo para obter detalhes completos da implementação.
Microsoft.Identity.Web simplifica seu código definindo as configurações corretas do OpenID Connect, assinando o evento de código recebido e resgatando o código. Nenhum código extra é necessário para resgatar o código de autorização. Consulte o código-fonte Microsoft.Identity.Web para obter detalhes sobre como isso funciona.
Microsoft.Identity.Web.OWIN simplifica seu código definindo as configurações corretas do OpenID Connect, assinando o evento de código recebido e resgatando o código. Nenhum código extra é necessário para resgatar o código de autorização. Consulte o código-fonte Microsoft.Identity.Web para obter detalhes sobre como isso funciona.
O método handleRedirect na classe AuthProvider processa o código de autorização recebido do Microsoft Entra ID. Isso é mostrado abaixo:
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 Aplicativo Web que entra em usuários: Configuração de código para entender como o exemplo Java obtém o código de autorização. Depois que o aplicativo recebe o código, o AuthFilter.java#L51-L56:
- Delega ao
AuthHelper.processAuthenticationCodeRedirect
método em AuthHelper.java#L67-L97.
- Convocatórias
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
}
}
O getAuthResultByAuthCode
método é definido em AuthHelper.java#L176. Ele cria um MSAL ConfidentialClientApplication
e, em seguida, chama acquireToken()
com AuthorizationCodeParameters
criado a partir do código de autorização.
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 Aplicativo Web que entra em usuários: Configuração de código para entender como o exemplo Python obtém o código de autorização.
O ecrã de início de sessão da Microsoft envia o código de autorização para o /getAToken
URL especificado no registo da aplicação. A auth_response
rota manipula essa URL, chamando auth.complete_login
para processar o código de autorização e, em seguida, retornando um erro ou redirecionando para a página inicial.
@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 obter o contexto completo desse código.
Em vez de um segredo do cliente, o aplicativo cliente confidencial também pode provar sua identidade usando um certificado de cliente ou uma declaração de cliente.
O uso de asserções de cliente é um cenário avançado, detalhado em Asserções de cliente.
O tutorial ASP.NET principal usa a injeção de dependência para permitir que você decida a implementação do cache de token no arquivo Startup.cs para seu aplicativo. Microsoft.Identity.Web vem com serializadores de cache de token pré-construídos descritos em Serialização de cache de token. Uma possibilidade interessante é escolher caches de memória distribuída 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 obter detalhes sobre os provedores de cache de token, consulte também o artigo Serialização de cache de token do Microsoft.Identity.Web e os tutoriais do aplicativo Web ASP.NET Core | Fase de caches de token do tutorial de aplicativos Web.
O tutorial ASP.NET usa injeção de dependência para permitir que você decida a implementação do cache de token no arquivo Startup.Auth.cs para seu aplicativo. Microsoft.Identity.Web vem com serializadores de cache de token pré-construídos descritos em Serialização de cache de token. Uma possibilidade interessante é escolher caches de memória distribuída 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 obter detalhes sobre os provedores de cache de token, consulte também o artigo de serialização de cache de token Microsoft.Identity.Web e os tutoriais do aplicativo Web ASP.NET Core | Fase de caches de token do tutorial do aplicativo Web.
Para obter detalhes, consulte Serialização de cache de token para MSAL.NET.
MSAL Java fornece métodos para serializar e desserializar o cache de token. O exemplo Java manipula a serialização da sessão, conforme mostrado no getAuthResultBySilentFlow
método em 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;
}
O detalhe da SessionManagementHelper
classe é fornecido no exemplo MSAL para Java.
No exemplo de Node.js, a sessão do aplicativo é usada para armazenar o cache de token. Usando métodos de cache do nó MSAL, o cache de token na sessão é lido antes de uma solicitação de token ser feita e, em seguida, atualizado assim que a solicitação de token é concluída com êxito. Isso é mostrado abaixo:
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);
}
};
}
No exemplo de Python, o pacote de identidade cuida do cache de token, usando o objeto global session
para armazenamento.
O Flask tem suporte integrado para sessões armazenadas em um cookie, mas devido ao comprimento dos cookies de identidade, a amostra usa o pacote Flask-session . Tudo é inicializado em 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"],
)
Devido à SESSION_TYPE="filesystem"
configuração no app_config.py
, o pacote Flask-session armazena sessões usando o sistema de arquivos local.
Para produção, você deve usar uma configuração que persista em várias instâncias e implantações do seu aplicativo, como "sqlachemy" ou "redis".
Neste ponto, quando o usuário entra, um token é armazenado no cache de tokens. Vamos ver como ele é usado em outras partes do aplicativo Web.