V tomto článku se dozvíte, jak nakonfigurovat kód aplikace a upravit webovou aplikaci tak, aby nejen přihlašuje uživatele, ale také volá webová rozhraní API. Aplikace, kterou vytvoříte, používá tok autorizačního kódu OAuth 2.0 k přihlášení uživatele. Tento tok má dva kroky:
Tajné klíče klienta nebo klientské certifikáty
Vzhledem k tomu, že vaše webová aplikace teď volá podřízené webové rozhraní API, zadejte tajný klíč klienta nebo klientský certifikát do souboru appsettings.json . Můžete také přidat oddíl, který určuje:
- Adresa URL podřízeného webového rozhraní API
- Obory vyžadované pro volání rozhraní API
V následujícím příkladu GraphBeta část určuje tato nastavení.
{
"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"]
}
}
Poznámka:
Můžete navrhnout kolekci přihlašovacích údajů klienta, včetně řešení bez přihlašovacích údajů, jako je federace identit úloh pro Azure Kubernetes.
Předchozí verze Microsoft.Identity.Web vyjádřily tajný klíč klienta v jedné vlastnosti ClientSecret místo ClientCredentials. Tato funkce je stále podporovaná pro zpětnou kompatibilitu, ale nemůžete použít vlastnost ClientSecret i kolekci ClientCredentials.
Místo tajného klíče klienta můžete zadat klientský certifikát. Následující fragment kódu ukazuje použití certifikátu uloženého ve službě 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"]
}
}
Varování
Pokud zapomenete změnit Scopes na pole, při pokusu o použití IDownstreamApi se obory zobrazí jako null a IDownstreamApi dojde k pokusu o anonymní (neověřené) volání do podřízeného rozhraní API, což bude mít za následek 401/unauthenticated.
Microsoft.Identity.Web nabízí několik způsobů, jak popsat certifikáty podle konfigurace nebo kódu. Podrobnosti najdete v tématu Microsoft.Identity.Web – Použití certifikátů na GitHubu.
Úprava souboru Startup.cs
Vaše webová aplikace potřebuje získat token pro podřízené rozhraní API. Zadáte to tak, že přidáte řádek .EnableTokenAcquisitionToCallDownstreamApi() za .AddMicrosoftIdentityWebApp(Configuration). Tento řádek zveřejňuje IAuthorizationHeaderProvider službu, kterou můžete použít v kontroleru a akcích stránky. Jak ale vidíte v následujících dvou možnostech, můžete to udělat jednodušeji. Musíte také zvolit implementaci mezipaměti tokenů, například .AddInMemoryTokenCaches()v 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();
// ...
}
// ...
}
Obory předané EnableTokenAcquisitionToCallDownstreamApi jsou volitelné a umožňují webové aplikaci požadovat obory a souhlas uživatele s těmito obory při přihlášení. Pokud nezadáte obory, Microsoft.Identity.Web povolí přírůstkové vyjádření souhlasu.
Microsoft.Identity.Web nabízí dva mechanismy pro volání webového rozhraní API z webové aplikace, aniž byste museli získat token. Možnost, kterou zvolíte, závisí na tom, jestli chcete volat Microsoft Graph nebo jiné rozhraní API.
Možnost 1: Volání Microsoft Graphu
Pokud chcete volat Microsoft Graph, Microsoft.Identity.Web umožňuje přímo používat GraphServiceClient (vystavené sadou Microsoft Graph SDK) v akcích rozhraní API. Zpřístupnění Microsoft Graphu:
Přidejte do projektu balíček NuGet Microsoft.Identity.Web.GraphServiceClient .
Přidejte .AddMicrosoftGraph() za .EnableTokenAcquisitionToCallDownstreamApi() do souboru Startup.cs.
.AddMicrosoftGraph() má několik přednastavení. Pomocí přepsání, které jako parametr přebírá oddíl konfigurace, se kód stane:
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();
// ...
}
// ...
}
Možnost 2: Volání podřízeného webového rozhraní API jiného než Microsoft Graphu
Pokud chcete volat jiné rozhraní než Microsoft Graph, Microsoft.Identity.Web umožňuje používat IDownstreamApi rozhraní v akcích rozhraní API. Chcete-li použít toto rozhraní:
Přidejte do projektu balíček NuGet Microsoft.Identity.Web.DownstreamApi .
Přidejte .AddDownstreamApi() za .EnableTokenAcquisitionToCallDownstreamApi() do souboru Startup.cs.
.AddDownstreamApi() má dva argumenty a zobrazuje se v následujícím fragmentu kódu:
- Název služby (API), která se používá v akcích kontroleru k odkazování na odpovídající konfiguraci
- oddíl konfigurace představující parametry používané k volání podřízeného webového rozhraní API.
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();
// ...
}
// ...
}
Shrnutí
Stejně jako u webových rozhraní API můžete zvolit různé implementace mezipaměti tokenů. Podrobnosti najdete v tématu Microsoft.Identity.Web – Serializace mezipaměti tokenů na GitHubu.
Následující obrázek ukazuje různé možnosti Microsoft.Identity.Web a jejich vliv na soubor Startup.cs :
Tajné klíče klienta nebo klientské certifikáty
Vzhledem k tomu, že vaše webová aplikace teď volá podřízené webové rozhraní API, zadejte tajný klíč klienta nebo klientský certifikát do souboru appsettings.json . Můžete také přidat oddíl, který určuje:
- Adresa URL podřízeného webového rozhraní API
- Obory vyžadované pro volání rozhraní API
V následujícím příkladu GraphBeta část určuje tato nastavení.
{
"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"]
}
}
Poznámka:
Můžete navrhnout kolekci přihlašovacích údajů klienta, včetně řešení bez přihlašovacích údajů, jako je federace identit úloh pro Azure Kubernetes.
Předchozí verze Microsoft.Identity.Web vyjádřily tajný klíč klienta v jedné vlastnosti ClientSecret místo ClientCredentials. Tato funkce je stále podporovaná pro zpětnou kompatibilitu, ale nemůžete použít vlastnost ClientSecret i kolekci ClientCredentials.
Místo tajného klíče klienta můžete zadat klientský certifikát. Následující fragment kódu ukazuje použití certifikátu uloženého ve službě 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"]
}
}
Varování
Pokud zapomenete změnit Scopes na pole, při pokusu o použití IDownstreamApi se obory zobrazí jako null a IDownstreamApi dojde k pokusu o anonymní (neověřené) volání do podřízeného rozhraní API, což bude mít za následek 401/unauthenticated.
Microsoft.Identity.Web nabízí několik způsobů, jak popsat certifikáty podle konfigurace nebo kódu. Podrobnosti najdete v tématu Microsoft.Identity.Web – Použití certifikátů na GitHubu.
Startup.Auth.cs
Vaše webová aplikace potřebuje získat token pro podřízené rozhraní API, Microsoft.Identity.Web poskytuje dva mechanismy pro volání webového rozhraní API z webové aplikace. Možnost, kterou zvolíte, závisí na tom, jestli chcete volat Microsoft Graph nebo jiné rozhraní API.
Možnost 1: Volání Microsoft Graphu
Pokud chcete volat Microsoft Graph, Microsoft.Identity.Web umožňuje přímo používat GraphServiceClient (vystavené sadou Microsoft Graph SDK) v akcích rozhraní API. Zpřístupnění Microsoft Graphu:
- Přidejte do projektu balíček NuGet Microsoft.Identity.Web.GraphServiceClient .
- Přidejte
.AddMicrosoftGraph() do kolekce služeb v souboru Startup.Auth.cs .
.AddMicrosoftGraph() má několik přednastavení. Pomocí přepsání, které jako parametr přebírá oddíl konfigurace, se kód stane:
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();
}
}
}
Možnost 2: Volání podřízeného webového rozhraní API jiného než Microsoft Graphu
Pokud chcete volat jiné rozhraní než Microsoft Graph, Microsoft.Identity.Web umožňuje používat IDownstreamApi rozhraní v akcích rozhraní API. Chcete-li použít toto rozhraní:
- Přidejte do projektu balíček NuGet Microsoft.Identity.Web.DownstreamApi .
- Přidejte
.AddDownstreamApi() za .EnableTokenAcquisitionToCallDownstreamApi() do souboru Startup.cs.
.AddDownstreamApi() má dva argumenty:
- Název služby (API): Tento název použijete v akcích kontroleru k odkazování na odpovídající konfiguraci.
- oddíl konfigurace představující parametry používané k volání podřízeného webového rozhraní API.
Tady je kód:
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();
}
}
}
Shrnutí
Můžete zvolit různé implementace mezipaměti tokenů. Podrobnosti najdete v tématu Microsoft.Identity.Web – Serializace mezipaměti tokenů na GitHubu.
Následující obrázek ukazuje různé možnosti Microsoft.Identity.Web a jejich vliv na soubor Startup.cs :
Příklady kódu v tomto článku a následující příklady se extrahují z ukázky webové aplikace ASP.NET. Na tuto ukázku můžete chtít odkazovat pro úplné podrobnosti implementace.
Implementace ukázky kódu Java
Příklady kódu v tomto článku a následující příklady jsou extrahovány z webové aplikace Java, která volá Microsoft Graph, ukázku webové aplikace, která používá MSAL pro Javu.
Ukázka v současné době umožňuje msAL pro Javu vytvořit adresu URL autorizačního kódu a zpracovává navigaci do koncového bodu autorizace pro platformu Microsoft Identity Platform. K přihlášení uživatele je také možné použít zabezpečení Sprintu. Můžete se podívat na ukázku s úplnými podrobnostmi implementace.
Implementace ukázky kódu Node.js
Příklady kódu v tomto článku a v následujícím článku jsou extrahovány z webové aplikace Node.js a Express.js, která využívá Microsoft Graph, ukázky webové aplikace využívající MSAL Node.
Ukázka v současné době umožňuje uzlu MSAL vytvořit adresu URL autorizačního kódu a zpracuje navigaci do koncového bodu autorizace pro platformu Microsoft Identity Platform. Toto je znázorněno níže:
/**
* 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);
}
};
}
Implementace ukázky kódu Pythonu
Fragmenty kódu v tomto článku a následující fragmenty jsou extrahovány z příkladu webové aplikace Python volající Microsoft Graph pomocí balíčku identity (obálky kolem MSAL Pythonu).
Ukázka používá identity balíček k vytvoření adresy URL autorizačního kódu a zpracovává navigaci ke koncovému bodu autorizace pro Microsoft Identity Platform. Můžete se podívat na ukázku s úplnými podrobnostmi implementace.
Metoda handleRedirect ve třídě AuthProvider zpracovává autorizační kód přijatý z ID Microsoft Entra. Toto je znázorněno níže:
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);
}
}
}
Jakmile aplikace obdrží autorizační kód, AuthFilter.java#L51-L56:
- Deleguje metodu
AuthHelper.processAuthenticationCodeRedirect v AuthHelper.java#L67-L97.
- Zavolá
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
}
}
Metoda je definována getAuthResultByAuthCode v AuthHelper.java#L176. Vytvoří knihovnu MSAL ConfidentialClientApplication a potom zavolá acquireToken() s AuthorizationCodeParameters vytvořeným z autorizačního kódu.
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();
}
Projděte si kurz: Přihlášení uživatelů k webové aplikaci Python Flask pomocí platformy Microsoft Identity Platform
Přihlašovací obrazovka Microsoftu odešle autorizační kód na /getAToken adresu URL zadanou v registraci aplikace. Trasa auth_response zpracuje tuto adresu URL, volá auth.complete_login k zpracování autorizačního kódu, a pak buď vrátí chybu, nebo přesměruje na domovskou stránku.
@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"))
Úplný kontext tohoto kódu najdete v app.py .
Místo tajného klíče klienta může důvěrná klientská aplikace také prokázat svou identitu pomocí klientského certifikátu nebo klientského kontrolního výrazu.
Použití klientských kontrolních výrazů je pokročilý scénář podrobně popsaný v klientských kontrolních výrazech.
Kurz ASP.NET Core používá injektáž závislostí, což vám umožňuje rozhodnout se o implementaci mezipaměti tokenů v souboru Startup.cs pro vaši aplikaci. Microsoft.Identity.Web obsahuje předem sestavené serializátory token-cache popsané v serializaci mezipaměti tokenů. Zajímavou možností je zvolit distribuované paměťové mezipaměti 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";
});
Podrobnosti o poskytovatelích mezipaměti tokenů najdete v článku o serializaci mezipaměti tokenů v Microsoft.Identity.Web a v kurzech webových aplikací ASP.NET Core | Fáze ukládání mezipaměti tokenů v rámci tutoriálu webových aplikací.
Kurz ASP.NET používá injektáž závislostí, abyste mohli rozhodnout o implementaci mezipaměti tokenů v souboru Startup.Auth.cs pro vaši aplikaci.
Microsoft.Identity.Web obsahuje předem sestavené serializátory token-cache popsané v serializaci mezipaměti tokenů. Zajímavou možností je zvolit distribuované paměťové mezipaměti 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";
});
Podrobnosti o poskytovatelích mezipaměti tokenů najdete také v článku o serializaci mezipaměti tokenů Microsoft.Identity.Web a v části kurzů webové aplikace ASP.NET Core | Mezipaměti tokenů tutoriálu webové aplikace.
Podrobnosti naleznete v tématu Serializace mezipaměti tokenů pro MSAL.NET.
MSAL Java poskytuje metody serializace a deserializace mezipaměti tokenů. Ukázka Javy zpracovává serializaci ze session, jak je uvedeno v getAuthResultBySilentFlow metodě v 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;
}
Podrobnosti SessionManagementHelper třídy jsou uvedeny v ukázce MSAL pro Javu.
V ukázce Node.js se aplikační relace používá pro uložení token cache. Pomocí metod cache MSAL Node se mezipaměť tokenů v relaci přečte před provedením požadavku na token a po úspěšném dokončení požadavku na token se aktualizuje. Toto je znázorněno níže:
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);
}
};
}
V ukázce Pythonu se balíček identity postará o mezipaměť tokenů pomocí globálního session objektu pro úložiště.
Flask má integrovanou podporu relací uložených v souboru cookie, ale vzhledem k délce souborů cookie identity používá ukázkový příklad místo toho balíček Flask-session. Vše se inicializuje v 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"],
)
Kvůli nastavení v SESSION_TYPE="filesystem" balíčku Flask-session ukládá relace pomocí místního systému souborů.
V produkčním prostředí byste měli použít nastavení, které se zachová napříč několika instancemi a nasazeními vaší aplikace, například SQLAlchemy nebo Redis.
Když se uživatel přihlásí, v tomto okamžiku se token uloží do mezipaměti tokenů. Pojďme se podívat, jak se pak používá v jiných částech webové aplikace.