Geheime Clientschlüssel oder Clientzertifikate
Wenn Ihre Web-App jetzt eine Downstream-Web-API aufruft, geben Sie in der Datei appsettings.json einen geheimen Clientschlüssel oder ein Clientzertifikat an. Sie können auch einen Abschnitt hinzufügen, in dem Folgendes angegeben wird:
- Die URL der Downstream-Web-API
- Die zum Aufrufen der API erforderlichen Bereiche
Im folgenden Beispiel sind diese Einstellungen im Abschnitt GraphBeta
angegeben.
{
"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"]
}
}
Hinweis
Sie können eine Sammlung von Clientanmeldeinformationen vorschlagen, einschließlich einer Lösung ohne Anmeldeinformationen wie Workloadidentitätsverbund für Azure Kubernetes.
In früheren Versionen von Microsoft.Identity.Web wurde der geheime Clientschlüssel in einer einzelnen Eigenschaft namens „ClientSecret“ anstelle von „ClientCredentials“ ausgedrückt. Dies wird aus Gründen der Abwärtskompatibilität weiterhin unterstützt, Sie können aber nicht sowohl die Eigenschaft „ClientSecret“ als auch die Sammlung „ClientCredentials“ verwenden.
Statt eines geheimen Clientschlüssels können Sie ein Clientzertifikat angeben. Im folgenden Codeausschnitt ist die Verwendung eines in Azure Key Vault gespeicherten Zertifikats dargestellt.
{
"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"]
}
}
Warnung
Wenn Sie vergessen, die Scopes
in ein Array zu ändern, erscheinen die Scopes bei der Verwendung der IDownstreamApi
als Null und die IDownstreamApi
versucht einen anonymen (unauthentifizierten) Aufruf der Downstream API, was zu 401/unauthenticated
führt.
Microsoft.Identity.Web bietet verschiedene Möglichkeiten, Zertifikate zu beschreiben, sowohl durch Konfiguration als auch durch Code. Weitere Informationen finden Sie unter Microsoft.Identity.Web: Verwenden von Zertifikaten auf GitHub.
Ändern Sie die Datei Startup.cs.
Ihre Web-App muss ein Token für die Downstream-API abrufen. Die Angabe erfolgt durch Hinzufügen der Zeile .EnableTokenAcquisitionToCallDownstreamApi()
nach .AddMicrosoftIdentityWebApp(Configuration)
. Diese Zeile macht den IAuthorizationHeaderProvider
-Dienst verfügbar, den Sie in Ihren Controller- und Seitenaktionen verwenden können. Wie jedoch aus den folgenden beiden Optionen hervorgeht, ist ein einfacheres Vorgehen möglich. Sie müssen zudem eine Tokencacheimplementierung (z. B. .AddInMemoryTokenCaches()
) in Startup.cs auswählen:
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();
// ...
}
// ...
}
Die an EnableTokenAcquisitionToCallDownstreamApi
übergebenen Bereiche sind optional und ermöglichen Ihrer Web-App das Anfordern der Bereiche und der Zustimmung des Benutzers zu diesen Bereichen bei der Anmeldung. Wenn Sie die Bereiche nicht angeben, aktiviert Microsoft.Identity.Web einen inkrementellen Zustimmungsprozess.
Microsoft.Identity.Web bietet zwei Mechanismen zum Aufrufen einer Web-API aus einer Web-App, ohne dass Sie ein Token abrufen müssen. Welche Option Sie auswählen, hängt davon ab, ob Sie Microsoft Graph oder eine andere API aufrufen möchten.
Option 1: Aufrufen von Microsoft Graph
Wenn Sie Microsoft Graph aufrufen möchten, bietet Microsoft.Identity.Web die Möglichkeit, den (über das Microsoft Graph SDK verfügbar gemachten) GraphServiceClient
in Ihren API-Aktionen direkt zu verwenden. Gehen Sie wie folgt vor, um Microsoft Graph verfügbar zu machen:
Fügen Sie Ihrem Projekt das NuGet-Paket Microsoft.Identity.Web.GraphServiceClient hinzu.
Fügen Sie in der Datei Startup.cs nach .EnableTokenAcquisitionToCallDownstreamApi()
den Eintrag .AddMicrosoftGraph()
hinzu. .AddMicrosoftGraph()
verfügt über mehrere Überschreibungen. Wenn Sie die Überschreibung verwenden, die einen Konfigurationsabschnitt als Parameter annimmt, sieht der Code wie folgt aus:
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();
// ...
}
// ...
}
Option 2: Aufrufen einer anderen Downstream-Web-API als Microsoft Graph
Wenn Sie eine andere API als Microsoft Graph aufrufen möchten, bietet Microsoft.Identity.Web die Möglichkeit, die IDownstreamApi
-Schnittstelle in Ihren API-Aktionen zu verwenden. So verwenden Sie diese Schnittstelle
Fügen Sie Ihrem Projekt das NuGet-Paket Microsoft.Identity.Web.DownstreamApi hinzu.
Fügen Sie in der Datei Startup.cs nach .EnableTokenAcquisitionToCallDownstreamApi()
den Eintrag .AddDownstreamApi()
hinzu. .AddDownstreamApi()
hat zwei Argumente und wird im folgenden Codeausschnitt gezeigt:
- Der Name eines Diensts (API), der in Ihren Controlleraktionen verwendet wird, um auf die entsprechende Konfiguration zu verweisen
- Konfigurationsabschnitt, der die Parameter darstellt, die zum Aufrufen der Downstream-Web-API verwendet werden
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();
// ...
}
// ...
}
Zusammenfassung
Wie bei Web-APIs können Sie verschiedene Tokencacheimplementierungen auswählen. Weitere Informationen finden Sie unter Microsoft.Identity.Web: Tokencacheserialisierung auf GitHub.
In der folgenden Abbildung sind die verschiedenen Möglichkeiten von Microsoft.Identity.Web und die Auswirkungen auf die Datei Startup.cs dargestellt:
Geheime Clientschlüssel oder Clientzertifikate
Wenn Ihre Web-App jetzt eine Downstream-Web-API aufruft, geben Sie in der Datei appsettings.json einen geheimen Clientschlüssel oder ein Clientzertifikat an. Sie können auch einen Abschnitt hinzufügen, in dem Folgendes angegeben wird:
- Die URL der Downstream-Web-API
- Die zum Aufrufen der API erforderlichen Bereiche
Im folgenden Beispiel sind diese Einstellungen im Abschnitt GraphBeta
angegeben.
{
"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"]
}
}
Hinweis
Sie können eine Sammlung von Clientanmeldeinformationen vorschlagen, einschließlich einer Lösung ohne Anmeldeinformationen wie Workloadidentitätsverbund für Azure Kubernetes.
In früheren Versionen von Microsoft.Identity.Web wurde der geheime Clientschlüssel in einer einzelnen Eigenschaft namens „ClientSecret“ anstelle von „ClientCredentials“ ausgedrückt. Dies wird aus Gründen der Abwärtskompatibilität weiterhin unterstützt, Sie können aber nicht sowohl die Eigenschaft „ClientSecret“ als auch die Sammlung „ClientCredentials“ verwenden.
Statt eines geheimen Clientschlüssels können Sie ein Clientzertifikat angeben. Im folgenden Codeausschnitt ist die Verwendung eines in Azure Key Vault gespeicherten Zertifikats dargestellt.
{
"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"]
}
}
Warnung
Wenn Sie vergessen, die Scopes
in ein Array zu ändern, erscheinen die Scopes bei der Verwendung der IDownstreamApi
als Null und die IDownstreamApi
versucht einen anonymen (unauthentifizierten) Aufruf der Downstream API, was zu 401/unauthenticated
führt.
Microsoft.Identity.Web bietet verschiedene Möglichkeiten, Zertifikate zu beschreiben, sowohl durch Konfiguration als auch durch Code. Weitere Informationen finden Sie unter Microsoft.Identity.Web: Verwenden von Zertifikaten auf GitHub.
Startup.Auth.cs
Ihre Web-App muss ein Token für die Downstream-API abrufen. Microsoft.Identity.Web bietet zwei Mechanismen zum Aufrufen einer Web-API über eine Web-App. Welche Option Sie auswählen, hängt davon ab, ob Sie Microsoft Graph oder eine andere API aufrufen möchten.
Option 1: Aufrufen von Microsoft Graph
Wenn Sie Microsoft Graph aufrufen möchten, bietet Microsoft.Identity.Web die Möglichkeit, den (über das Microsoft Graph SDK verfügbar gemachten) GraphServiceClient
in Ihren API-Aktionen direkt zu verwenden. Gehen Sie wie folgt vor, um Microsoft Graph verfügbar zu machen:
- Fügen Sie Ihrem Projekt das NuGet-Paket Microsoft.Identity.Web.GraphServiceClient hinzu.
- Fügen Sie
.AddMicrosoftGraph()
der Dienstsammlung in der Datei Startup.Auth.cs hinzu. .AddMicrosoftGraph()
verfügt über mehrere Überschreibungen. Wenn Sie die Überschreibung verwenden, die einen Konfigurationsabschnitt als Parameter annimmt, sieht der Code wie folgt aus:
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();
}
}
}
Option 2: Aufrufen einer anderen Downstream-Web-API als Microsoft Graph
Wenn Sie eine andere API als Microsoft Graph aufrufen möchten, bietet Microsoft.Identity.Web die Möglichkeit, die IDownstreamApi
-Schnittstelle in Ihren API-Aktionen zu verwenden. So verwenden Sie diese Schnittstelle
- Fügen Sie Ihrem Projekt das NuGet-Paket Microsoft.Identity.Web.DownstreamApi hinzu.
- Fügen Sie in der Datei Startup.cs nach
.EnableTokenAcquisitionToCallDownstreamApi()
den Eintrag .AddDownstreamApi()
hinzu. .AddDownstreamApi()
hat zwei Argumente:
- Name eines Diensts (API): Sie verwenden diesen Namen in Ihren Controlleraktionen, um auf die entsprechende Konfiguration zu verweisen.
- Konfigurationsabschnitt, der die Parameter darstellt, die zum Aufrufen der Downstream-Web-API verwendet werden
Der Code lautet wie folgt:
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();
}
}
}
Zusammenfassung
Sie können verschiedene Tokencacheimplementierungen auswählen. Weitere Informationen finden Sie unter Microsoft.Identity.Web: Tokencacheserialisierung auf GitHub.
In der folgenden Abbildung sind die verschiedenen Möglichkeiten von Microsoft.Identity.Web und die Auswirkungen auf die Datei Startup.cs dargestellt:
Die Codebeispiele in diesem und dem folgenden Artikel stammen aus dem ASP.NET-Web-App-Beispiel. Dieses Beispiel enthält auch ausführliche Informationen zur Implementierung.
Implementieren des Java-Codebeispiels
Die Codebeispiele in diesem und dem folgenden Artikel stammen aus dem Web-App-Beispiel Java-Webanwendung für den Aufruf von Microsoft Graph, bei dem MSAL für Java verwendet wird.
Im Beispiel wird aktuell von MSAL für Java die Autorisierungscode-URL erzeugt und die Navigation zum Autorisierungsendpunkt für Microsoft Identity Platform gesteuert. Es ist auch möglich, die Sprint-Sicherheit für die Anmeldung des Benutzers zu verwenden. Das Beispiel enthält auch ausführliche Informationen zur Implementierung.
Implementieren des Node.js-Codebeispiels
Die Codebeispiele in diesem und dem folgenden Artikel stammen aus der Node.js Express.js-Webanwendung zum Aufruf von Microsoft Graph, einem Webanwendungsbeispiel, das MSAL Node verwendet.
In diesem Beispiel lässt MSAL Node die URL für den Autorisierungscode erzeugen und übernimmt die Navigation zum Autorisierungsendpunkt für die Microsoft Identitätsplattform. Die Abbildung unten zeigt dies:
/**
* 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);
}
};
}
Implementieren des Python-Codebeispiels
Die Codeausschnitte in diesem und den folgenden Artikeln stammen aus dem Beispiel Python-Webanwendung, die Microsoft Graph aufruft, in dem das Identitätspaket (ein Wrapper um MSAL-Python) verwendet wird.
Im Beispiel wird das Identitätspaket verwendet, um die Autorisierungscode-URL zu erzeugen, und die Navigation zum Autorisierungsendpunkt für Microsoft Identity Platform wird gesteuert. Das Beispiel enthält auch ausführliche Informationen zur Implementierung.
Microsoft.Identity.Web vereinfacht Ihren Code, indem es die richtigen OpenID-Verbindungseinstellungen festlegt, das Ereignis „Code erhalten“ abonniert und den Code einlöst. Zum Einlösen des Autorisierungscodes ist kein weiterer Code erforderlich. Ausführliche Informationen zur Funktionsweise finden Sie im Microsoft.Identity.Web-Quellcode.
Microsoft.Identity.Web.OWIN vereinfacht Ihren Code, indem es die richtigen OpenID-Verbindungseinstellungen festlegt, das Ereignis „Code erhalten“ abonniert und den Code einlöst. Zum Einlösen des Autorisierungscodes ist kein weiterer Code erforderlich. Ausführliche Informationen zur Funktionsweise finden Sie im Microsoft.Identity.Web-Quellcode.
Die handleRedirect-Methode in der AuthProvider-Klasse verarbeitet den von Microsoft Entra ID empfangenen Autorisierungscode. Die Abbildung unten zeigt dies:
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);
}
}
}
Lesen Sie Web-App, die Benutzer anmeldet: Codekonfiguration, um zu verstehen, wie das Java-Beispiel den Autorisierungscode abruft. Nachdem die App den Code erhalten hat, geht AuthFilter.java#L51-L56 wie folgt vor:
- Delegierung an die
AuthHelper.processAuthenticationCodeRedirect
-Methode in AuthHelper.java#L67-L97.
- Aufruf von
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
}
}
Die getAuthResultByAuthCode
-Methode ist in AuthHelper.java#L176 definiert. Sie erstellt eine MSAL-ConfidentialClientApplication
und ruft acquireToken()
mit den aus dem Autorisierungscode erstellten AuthorizationCodeParameters
auf.
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();
}
Lesen Sie Web-App, die Benutzer anmeldet: Codekonfiguration, um zu verstehen, wie das Python-Beispiel den Autorisierungscode abruft.
Der Microsoft-Anmeldebildschirm sendet den Autorisierungscode an die /getAToken
-URL, die in der App-Registrierung angegeben wurde. Die auth_response
-Route verarbeitet diese URL, ruft auth.complete_login
auf, um den Autorisierungscode zu verarbeiten, und gibt dann entweder einen Fehler zurück oder leitet zur Startseite um.
@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"))
Den vollständigen Kontext dieses Codes finden Sie unter app.py.
Die vertrauliche Clientanwendung kann ihre Identität statt mit einem geheimen Clientschlüssel auch mithilfe eines Clientzertifikats oder einer Clientassertion nachweisen.
Die Verwendung von Clientassertionen ist ein erweitertes Szenario, das unter Clientassertionen detailliert beschrieben ist.
Im ASP.NET Core-Tutorial wird die Abhängigkeitsinjektion verwendet, um Ihnen die Entscheidung über die Tokencache-Implementierung in der Datei „Startup.cs“ für Ihre Anwendung zu ermöglichen. „Microsoft.Identity.Web“ enthält eine Reihe vordefinierter Tokencache-Serialisierungsmodule, die unter Tokencacheserialisierung beschrieben sind. Eine interessante Möglichkeit besteht darin, verteilte Arbeitsspeichercaches von ASP.NET Core auszuwählen:
// 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";
});
Ausführliche Informationen zu den Tokencacheanbietern finden Sie im Artikel Tokencacheserialisierung von Microsoft.Identity.Web sowie in den Tutorials zu ASP.NET Core-Web-Apps | Tokencaches in der entsprechenden Phase des Web-App-Tutorials.
Im ASP.NET-Tutorial wird die Abhängigkeitsinjektion verwendet, damit Sie die Tokencacheimplementierung in der Datei Startup.cs für Ihre Anwendung festlegen können. Microsoft.Identity.Web enthält eine Reihe vordefinierter Tokencache-Serialisierungsmodule, die unter Tokencacheserialisierung beschrieben sind. Eine interessante Möglichkeit besteht darin, verteilte Arbeitsspeichercaches von ASP.NET Core auszuwählen:
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";
});
Ausführliche Informationen zu den Tokencacheanbietern finden Sie im Artikel Tokencacheserialisierung von Microsoft.Identity.Web sowie in den Tutorials zu ASP.NET Core-Web-Apps | Tokencaches in der entsprechenden Phase des Web-App-Tutorials.
Ausführliche Informationen finden Sie unter Tokencacheserialisierung für MSAL.NET.
MSAL Java stellt Methoden zum Serialisieren und Deserialisieren des Tokencaches bereit. Das Java-Beispiel behandelt die Serialisierung aus der Sitzung, wie in der getAuthResultBySilentFlow
-Methode in AuthHelper.java#L99-L122 gezeigt:
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;
}
Die Details der SessionManagementHelper
-Klasse werden im MSAL-Beispiel für Java bereitgestellt.
Im Node.js-Beispiel wird die Anwendungssitzung zum Speichern des Tokencache verwendet. Mit den MSAL Node-Cache-Methoden wird der Tokencache in der Sitzung gelesen, bevor eine Tokenanforderung gestellt wird, und dann aktualisiert, sobald die Tokenanforderung erfolgreich abgeschlossen ist. Die Abbildung unten zeigt dies:
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);
}
};
}
Im Python-Beispiel kümmert sich das Identitätspaket um den Tokencache, wobei das globale session
-Objekt für die Speicherung verwendet wird.
Flask besitzt integrierte Unterstützung für Sitzungen, die in einem Cookie gespeichert sind, aber aufgrund der Länge der Identitätscookies verwendet das Beispiel stattdessen das Paket Flask-session. Alles wird in app.py initialisiert:
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"],
)
Aufgrund der Einstellung SESSION_TYPE="filesystem"
in app_config.py
speichert das „Flask-session“-Paket Sitzungen mithilfe des lokalen Dateisystems.
Für die Produktion sollten Sie eine Einstellung verwenden, die über mehrere Instanzen und Bereitstellungen Ihrer App hinweg beibehalten wird, z. B. „sqlachemy“ oder „redis“.
Wenn sich der Benutzer anmeldet, wird zu diesem Zeitpunkt ein Token im Tokencache gespeichert. Sehen wir uns an, wie dieses dann in anderen Teilen der Web-App verwendet wird.