Segredos do cliente ou certificados do cliente
Considerando que sua API Web agora recorre a uma API Web downstream, forneça um segredo do cliente ou um certificado do cliente no arquivo appsettings.json. Você também pode adicionar uma seção que especifica:
- a URL da API Web downstream
- os escopos necessários para chamar a API
No exemplo a seguir, a seção GraphBeta
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"]
}
}
Observação
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 o Kubernetes do Azure.
As versões anteriores do Microsoft.Identity.Web expressam o segredo do cliente em uma única propriedade "ClientSecret" em vez de "ClientCredentials". Ela ainda tem suporte 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 do cliente. O snippet de código a seguir mostra o uso de um certificado armazenado no 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"]
}
}
Aviso
Se você esquecer de alterar 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
.
O Microsoft.Identity.Web fornece várias maneiras de descrever os certificados, tanto por configuração quanto por código. Para obter mais detalhes, confira o Microsoft.Identity.Web – usando certificados no GitHub.
Modifique o arquivo Startup.cs
Seu aplicativo Web precisará adquirir um token para a API downstream. Você o especifica adicionando a linha .EnableTokenAcquisitionToCallDownstreamApi()
após .AddMicrosoftIdentityWebApp(Configuration)
. Essa linha expõe o serviço IAuthorizationHeaderProvider
, que você pode usar em suas ações de página e controlador. No entanto, como você pode ver 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 ao fazer logon. Se você não especificar os escopos, o Microsoft.Identity.Web habilitará uma experiência de consentimento incremental.
Microsoft.Identity.Web oferece dois mecanismos para chamar uma API Web a partir 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 recorrer ao Microsoft Graph, o Microsoft.Identity.Web permitirá 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 de .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs. .AddMicrosoftGraph()
tem várias substituições. Usando a substituição que tem uma seção de configuração como um 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 Web downstream diferente do Microsoft Graph
Se você quiser chamar uma API diferente do Microsoft Graph, o Microsoft.Identity.Web permitirá que você use a interface IDownstreamApi
em suas ações de API. Para usar essa interface:
Adicione o pacote NuGet Microsoft.Identity.Web.DownstreamApi ao projeto.
Adicione .AddDownstreamApi()
depois de .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs. .AddDownstreamApi()
tem dois argumentos e é mostrado no trecho de código a seguir:
- O nome de um serviço (API), que é usado nas ações do controlador para referenciar a configuração correspondente
- uma seção de configuração que representa os parâmetros usados para chamar a 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();
// ...
}
// ...
}
Resumo
Assim como acontece com as APIs da Web, você pode escolher várias implementações de cache de token. Para obter mais detalhes, confira Microsoft Identity Web – serialização de cache de token no GitHub.
A seguinte imagem mostra as várias possibilidades do Microsoft.Identity.Web e o impacto no arquivo Startup.cs:
Segredos do cliente ou certificados do cliente
Considerando que sua API Web agora recorre a uma API Web downstream, forneça um segredo do cliente ou um certificado do cliente no arquivo appsettings.json. Você também pode adicionar uma seção que especifica:
- a URL da API Web downstream
- os escopos necessários para chamar a API
No exemplo a seguir, a seção GraphBeta
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"]
}
}
Observação
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 o Kubernetes do Azure.
As versões anteriores do Microsoft.Identity.Web expressam o segredo do cliente em uma única propriedade "ClientSecret" em vez de "ClientCredentials". Ela ainda tem suporte 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 do cliente. O snippet de código a seguir mostra o uso de um certificado armazenado no 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"]
}
}
Aviso
Se você esquecer de alterar 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
.
O Microsoft.Identity.Web fornece várias maneiras de descrever os certificados, tanto por configuração quanto por código. Para obter mais detalhes, confira o 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 recorrer ao Microsoft Graph, o Microsoft.Identity.Web permitirá 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 tem uma seção de configuração como um 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 Web downstream diferente do Microsoft Graph
Se você quiser chamar uma API diferente do Microsoft Graph, o Microsoft.Identity.Web permitirá que você use a interface IDownstreamApi
em suas ações de API. Para usar essa interface:
- Adicione o pacote NuGet Microsoft.Identity.Web.DownstreamApi ao projeto.
- Adicione
.AddDownstreamApi()
depois de .EnableTokenAcquisitionToCallDownstreamApi()
no arquivo Startup.cs. .AddDownstreamApi()
usa dois argumentos:
- O nome de um serviço (API): você usa esse nome nas ações do controlador para referenciar a configuração correspondente
- uma seção de configuração que representa os parâmetros usados para chamar a API Web downstream.
O código é o seguinte:
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 mais detalhes, confira Microsoft Identity Web – serialização de cache de token no GitHub.
A seguinte imagem mostra as várias possibilidades do Microsoft.Identity.Web e o impacto no arquivo Startup.cs:
Os exemplos de código neste artigo e o seguinte são extraídos do exemplo de aplicativo do ASP.NET Web. Se desejar, consulte esse exemplo para obter detalhes completos sobre a implementação.
Implementar o exemplo de código Java
Os exemplos de código neste artigo e o 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 para Java produza a URL de código de autorização e manipula 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 do Sprint para conectar o usuário. Se desejar, consulte o exemplo para obter detalhes completos sobre a implementação.
Implementar o exemplo de código Node.js
Os exemplos de código neste artigo e no seguinte são extraídos do aplicativo Web Node.js e Express.js que chama o Microsoft Graph, um exemplo de aplicativo Web que usa a MSAL para Node.
O exemplo atualmente permite que a MSAL Node produza a URL de 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. 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
Os snippets de código neste artigo e os seguintes foram extraídos da amostra Aplicativo Web em Python chamando o 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 de código de autorização e manipula a navegação até o ponto de extremidade de autorização para a plataforma de identidade da Microsoft. Se desejar, consulte o exemplo para obter detalhes completos sobre a implementação.
O Microsoft. Identity. Web simplifica seu código definindo as configurações corretas do OpenID Connect, inscrevendo-se no evento de código recebido e resgatando o código. Nenhum código adicional é 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, inscrevendo-se no evento de código recebido e resgatando o código. Nenhum código adicional é 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 da ID do Microsoft Entra. 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);
}
}
}
Veja o aplicativo Web que conecta os usuários: Codifique a configuração para entender como o exemplo do Java obtém o código de autorização. Depois que o aplicativo recebe o código, o AuthFilter.java#L51-L56:
- Delega para o método
AuthHelper.processAuthenticationCodeRedirect
em AuthHelper.java#L67-L97.
- Chama
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
}
}
The método getAuthResultByAuthCode
é definido em AuthHelper.java#L176. Ele cria um MSAL ConfidentialClientApplication
e, em seguida, chama acquireToken()
com AuthorizationCodeParameters
, que foi 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 ingressa os usuários: configuração de código para entender como o exemplo do Java obtém o código de autorização.
A tela de entrada da Microsoft envia o código de autorização para a URL /getAToken
especificada no registro do aplicativo. A rota auth_response
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 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"))
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 asserção de cliente.
O uso de asserções de cliente é um cenário avançado, detalhado na Declarações de cliente.
O tutorial do ASP.NET Core usa injeção de dependência para permitir que você decida a implementação do cache de token no arquivo Startup.cs para seu aplicativo. O Microsoft.Identity.Web vem com serializadores pré-criados de cache de token descritos em Serialização de cache de token. Uma possibilidade interessante é escolher os caches de memória distribuída do 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 a fase Tutoriais de aplicativos Web ASP.NET Core | Caches de Token do tutorial de aplicativos Web.
O tutorial do 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. O Microsoft.Identity.Web vem com serializadores pré-criados de cache de token descritos em Serialização de cache de token. Uma possibilidade interessante é escolher os caches de memória distribuída do 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, confira também o artigo Microsoft.Identity.WebSerialização de cache de token e a fase Tutoriais de aplicativos Web ASP.NET Core | Caches de token do tutorial de aplicativos Web.
Para saber mais, confira Serialização de cache de Token para MSAL.NET.
O MSAL Java fornece métodos para serializar e desserializar o cache do token. O exemplo de Java manipula a serialização da sessão, conforme mostrado no método getAuthResultBySilentFlow
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;
}
Os detalhes da classe SessionManagementHelper
são fornecidos 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 da MSAL Node, o cache de token na sessão é lido antes de uma solicitação de token ser feita e, em seguida, atualizado depois 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 do Python, o pacote de identidade cuida do cache de token, usando o objeto global session
para armazenamento.
O Flask tem suporte interno para sessões armazenadas em um cookie, mas devido ao comprimento dos cookies de identidade, o exemplo 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 à configuração SESSION_TYPE="filesystem"
em 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 de seu aplicativo, como "sqlachemy" ou "redis".
Neste ponto, quando o usuário faz logon, um token é armazenado no cache de token. Vamos ver como ele é usado em outras partes do aplicativo Web.