用戶端秘密或客戶端憑證
假設您的 Web 應用程式現在會呼叫下游 Web API,請在 appsettings.json 檔案中提供用戶端密碼或用戶端憑證。 您也可以新增指定:
- 下游 Web API 的 URL
- 呼叫 API 所需的範圍
在下列範例中,區 GraphBeta
段會指定這些設定。
{
"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"]
}
}
注意
您可以建議客戶端認證集合,包括無認證解決方案,例如 Azure Kubernetes 的工作負載身分識別同盟。
舊版的 Microsoft.Identity.Web 在單一屬性 “ClientSecret” 中表示客戶端密碼,而不是 “ClientCredentials”。 這仍支援回溯相容性,但您無法同時使用 「ClientSecret」 屬性和 「ClientCredentials」 集合。
您可以提供客戶端憑證,而不是客戶端密碼。 下列代碼段顯示使用儲存在 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"]
}
}
警告
如果您忘記將 變更 Scopes
為陣列,當您嘗試使用 IDownstreamApi
範圍時,會顯示 null,並 IDownstreamApi
嘗試對下游 API 進行匿名(未驗證)呼叫,這會導致 401/unauthenticated
。
Microsoft.Identity.Web 提供數種方式,可透過組態或程式代碼來描述憑證。 如需詳細資訊,請參閱 Microsoft.Identity.Web - 在 GitHub 上使用憑證 。
Startup.cs
您的 Web 應用程式必須取得下游 API 的令牌。 您可以藉由在 之後.AddMicrosoftIdentityWebApp(Configuration)
新增 行來.EnableTokenAcquisitionToCallDownstreamApi()
指定它。 這一行會 IAuthorizationHeaderProvider
公開您可以在控制器和頁面動作中使用的服務。 不過,如您在下列兩個選項中所見,可以更簡單地完成。 您也需要選擇令牌快取實作,例如 .AddInMemoryTokenCaches()
,在 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();
// ...
}
// ...
}
傳遞至 EnableTokenAcquisitionToCallDownstreamApi
的範圍是選擇性的,並可讓您的 Web 應用程式在登入時要求範圍和使用者同意這些範圍。 如果您未指定範圍, Microsoft.Identity.Web 會啟用累加式同意體驗。
Microsoft.Identity.Web 提供兩種機制,可從 Web 應用程式呼叫 Web API,而不需要取得令牌。 您選擇的選項取決於您要呼叫 Microsoft Graph 或其他 API。
選項 1:呼叫 Microsoft Graph
如果您想要呼叫 Microsoft Graph,Microsoft.Identity.Web 可讓您直接在 API 動作中使用 GraphServiceClient
(由 Microsoft Graph SDK 公開)。 若要公開 Microsoft Graph:
將 Microsoft.Identity.Web.GraphServiceClient NuGet 套件新增至您的專案。
在 Startup.cs 檔案中新增 .AddMicrosoftGraph()
。.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph()
有數個覆寫。 使用採用組態區段做為參數的覆寫,程式代碼會變成:
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();
// ...
}
// ...
}
選項 2:呼叫 Microsoft Graph 以外的下游 Web API
如果您想要呼叫 Microsoft Graph 以外的 API,Microsoft.Identity.Web 可讓您在 API 動作中使用 IDownstreamApi
介面。 若要使用此介面:
將 Microsoft.Identity.Web.DownstreamApi NuGet 套件新增至您的專案。
在 Startup.cs 檔案中新增 .AddDownstreamApi()
。.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamApi()
有兩個自變數,且顯示在下列代碼段中:
- 服務的名稱(API),用於控制器動作以參考對應的組態
- 組態區段,表示用來呼叫下游 Web 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();
// ...
}
// ...
}
摘要
如同 Web API,您可以選擇各種令牌快取實作。 如需詳細資訊,請參閱 GitHub 上的 Microsoft.Identity.Web - 令牌快取串行化 。
下圖顯示 Microsoft.Identity.Web 的各種可能性,以及它們對Startup.cs檔案的影響:
用戶端秘密或客戶端憑證
假設您的 Web 應用程式現在會呼叫下游 Web API,請在 appsettings.json 檔案中提供用戶端密碼或用戶端憑證。 您也可以新增指定:
- 下游 Web API 的 URL
- 呼叫 API 所需的範圍
在下列範例中,區 GraphBeta
段會指定這些設定。
{
"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"]
}
}
注意
您可以建議客戶端認證集合,包括無認證解決方案,例如 Azure Kubernetes 的工作負載身分識別同盟。
舊版的 Microsoft.Identity.Web 在單一屬性 “ClientSecret” 中表示客戶端密碼,而不是 “ClientCredentials”。 這仍支援回溯相容性,但您無法同時使用 「ClientSecret」 屬性和 「ClientCredentials」 集合。
您可以提供客戶端憑證,而不是客戶端密碼。 下列代碼段顯示使用儲存在 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"]
}
}
警告
如果您忘記將 變更 Scopes
為陣列,當您嘗試使用 IDownstreamApi
範圍時,會顯示 null,並 IDownstreamApi
嘗試對下游 API 進行匿名(未驗證)呼叫,這會導致 401/unauthenticated
。
Microsoft.Identity.Web 提供數種方式,可透過組態或程式代碼來描述憑證。 如需詳細資訊,請參閱 Microsoft.Identity.Web - 在 GitHub 上使用憑證 。
Startup.Auth.cs
您的 Web 應用程式需要取得下游 API 的令牌, Microsoft.Identity.Web 提供兩種機制,可從 Web 應用程式呼叫 Web API。 您選擇的選項取決於您要呼叫 Microsoft Graph 或其他 API。
選項 1:呼叫 Microsoft Graph
如果您想要呼叫 Microsoft Graph,Microsoft.Identity.Web 可讓您直接在 API 動作中使用 GraphServiceClient
(由 Microsoft Graph SDK 公開)。 若要公開 Microsoft Graph:
- 將 Microsoft.Identity.Web.GraphServiceClient NuGet 套件新增至您的專案。
- 將 新增
.AddMicrosoftGraph()
至 Startup.Auth.cs 檔案中的服務集合。 .AddMicrosoftGraph()
有數個覆寫。 使用採用組態區段做為參數的覆寫,程式代碼會變成:
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();
}
}
}
選項 2:呼叫 Microsoft Graph 以外的下游 Web API
如果您想要呼叫 Microsoft Graph 以外的 API,Microsoft.Identity.Web 可讓您在 API 動作中使用 IDownstreamApi
介面。 若要使用此介面:
- 將 Microsoft.Identity.Web.DownstreamApi NuGet 套件新增至您的專案。
- 在 Startup.cs 檔案中新增
.AddDownstreamApi()
。.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamApi()
有兩個自變數:
- 服務的名稱(api):您可以在控制器動作中使用這個名稱來參考對應的組態
- 組態區段,表示用來呼叫下游 Web API 的參數。
程式碼如下:
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();
}
}
}
摘要
您可以選擇各種令牌快取實作。 如需詳細資訊,請參閱 GitHub 上的 Microsoft.Identity.Web - 令牌快取串行化 。
下圖顯示 Microsoft.Identity.Web 的各種可能性,以及它們對Startup.cs檔案的影響:
本文中的程式代碼範例和下列範例會從 ASP.NET Web 應用程式範例擷取。 您可能想要參考該範例以取得完整的實作詳細數據。
本文中的程式代碼範例和下列範例是從呼叫 Microsoft Graph 的 Java Web 應用程式擷取,這是使用 MSAL for Java 的 Web 應用程式範例。
此範例目前可讓適用於 Java 的 MSAL 產生授權碼 URL,並處理巡覽至 Microsoft 身分識別平台 的授權端點。 您也可以使用 Sprint 安全性來登入使用者。 您可能想要參考範例以取得完整的實作詳細數據。
本文中的程式代碼範例和下列程式代碼範例是從呼叫 Microsoft Graph 的 Node.js 和 Express.js Web 應用程式擷取,這是使用 MSAL Node 的 Web 應用程式範例。
此範例目前可讓 MSAL 節點產生授權碼 URL,並處理巡覽至 Microsoft 身分識別平台 的授權端點。 如下所示:
/**
* 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);
}
};
}
本文中的代碼段和下列代碼段會從使用身分識別套件呼叫 Microsoft Graph 範例的 Python Web 應用程式擷取(MSAL Python 周圍的包裝函式)。
此範例會使用身分識別套件來產生授權碼 URL,並處理巡覽至 Microsoft 身分識別平台 的授權端點。 您可能想要參考範例以取得完整的實作詳細數據。
Microsoft.Identity.Web.OWIN 藉由設定正確的 OpenID 連線 設定、訂閱收到的程式碼事件,以及兌換程式代碼,來簡化程式代碼。 不需要額外的程式代碼才能兌換授權碼。 如需運作方式的詳細資訊,請參閱 Microsoft.Identity.Web 原始程式碼 。
AuthProvider 類別中的 handleRedirect 方法會處理從 Microsoft Entra ID 收到的授權碼。 如下所示:
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);
}
}
}
請參閱 登入使用者的 Web 應用程式:程式代碼 設定,以瞭解 Java 範例如何取得授權碼。 應用程式收到程式代碼之後, AuthFilter.java#L51-L56:
- AuthHelper.java#L67-L97 中方法的
AuthHelper.processAuthenticationCodeRedirect
委派。
- 呼叫
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
}
}
方法 getAuthResultByAuthCode
定義於 AuthHelper.java#L176 中。 它會建立 MSAL ConfidentialClientApplication
,然後使用從授權碼建立的呼叫acquireToken()
AuthorizationCodeParameters
。
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();
}
請參閱 登入使用者的 Web 應用程式:程式代碼 設定,以瞭解 Python 範例如何取得授權碼。
Microsoft 登入畫面會將授權碼傳送至 /getAToken
應用程式註冊中指定的 URL。 路由會 auth_response
處理該 URL、呼叫 auth.complete_login
以處理授權碼,然後傳回錯誤或重新導向至首頁。
@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"))
如需該程式代碼的完整內容,請參閱 app.py
。
ASP.NET 核心教學課程會使用相依性插入,讓您決定應用程式Startup.cs檔案中的令牌快取實作。 Microsoft.Identity.Web 隨附令牌快取串行化程式,如令牌快取串行化中所述。 有一個有趣的可能性是選擇 ASP.NET 核心 分散式記憶體快取:
// 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";
});
如需令牌快取提供者的詳細資訊,請參閱 Microsoft.Identity.Web 的 令牌快取串行化 一文,以及 ASP.NET Core Web 應用程式教學課程 |Web 應用程式的令牌快取 階段教學課程。
ASP.NET 教學課程會使用相依性插入,讓您決定應用程式Startup.Auth.cs檔案中的令牌快取實作。 Microsoft.Identity.Web 隨附令牌快取串行化程式,如令牌快取串行化中所述。 有一個有趣的可能性是選擇 ASP.NET 核心 分散式記憶體快取:
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";
});
如需令牌快取提供者的詳細資訊,請參閱 Microsoft.Identity.Web 令牌快取串行化一文,以及 ASP.NET Core Web應用程式教學課程 |Web 應用程式教學課程的令牌快取階段。
如需詳細資訊,請參閱 MSAL.NET 的令牌快取串行化。
MSAL Java 提供方法來串行化和還原串行化令牌快取。 Java 範例會處理會話中的串行化,如 AuthHelper.java#L99-L122 中的 方法所示getAuthResultBySilentFlow
:
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;
}
類別的詳細數據是在適用於 Java 的 SessionManagementHelper
MSAL 範例中提供。
在Node.js範例中,應用程式會話會用來儲存令牌快取。 使用 MSAL 節點快取方法時,會話中的令牌快取會在令牌要求提出之前讀取,然後在令牌要求成功完成後更新。 如下所示:
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);
}
};
}
在 Python 範例中,身分識別套件會使用全域 session
對象進行記憶體,負責令牌快取。
Flask 內建支援儲存在 Cookie 中的會話,但由於身分識別 Cookie 的長度,此範例會改用 Flask 會話 套件。 所有專案會在 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"],
)
由於 SESSION_TYPE="filesystem"
中的 app_config.py
設定,Flask 會話套件會使用本機文件系統來儲存會話。
針對生產環境,您應該使用 可在多個實例之間保存並部署應用程式的設定 ,例如 “sqlachemy” 或 “redis”。