在 Microsoft 身分識別平台中簽署金鑰變換
本文討論您對於 Microsoft 身分識別平台用來簽署安全性權杖的公開金鑰需了解哪些事項。 請務必注意這些金鑰會定期變換,且在緊急狀況下可以立即變換。 所有使用 Microsoft 身分識別平台的應用程式,都應能以程式設計的方式處理金鑰變換程序。 您將瞭解金鑰的運作方式、如何評估變換對應用程式的影響。 您也將瞭解如何更新應用程式或建立定期手動變換程式,以在必要時處理密鑰變換。
在 Microsoft 身分識別平台中簽署金鑰的總覽
Microsoft 身分識別平台會使用根據業界標準所建置的公開金鑰加密技術,建立 Azure AD 本身和使用 Azure AD 的應用程式之間的信任。 實際上,其運作方式如下:Microsoft 身分識別平台使用由公開和私密金鑰組所組成的簽署金鑰。 當使用者登入使用 Microsoft 身分識別平台進行驗證的應用程式時,Microsoft 身分識別平台會建立包含使用者相關資訊的安全性權杖。 此令牌會先由 Microsoft 身分識別平台 使用其私鑰進行簽署,再傳送回應用程式。 若要確認該權杖有效且來自 Azure AD,應用程式必須使用由 Microsoft 身分識別平台公開且包含在租用戶 OpenID Connect 探索文件或 SAML/WS-Fed 同盟中繼資料文件中的公開金鑰來驗證權杖簽章。
基於安全考量,Microsoft 身分識別平台的簽署金鑰會定期變換,且在緊急情況下可以立即變換。 這些金鑰變換之間沒有設定或保證的時間。 任何與 Microsoft 身分識別平台整合的應用程式都應該準備好處理密鑰變換事件,無論可能發生的頻率為何。 如果您的應用程式無法處理突然的重新整理,並嘗試使用過期的金鑰來驗證權杖上的簽章,則您的應用程式就會錯誤地拒絕權杖。 建議使用 標準連結庫 ,以確保密鑰元數據已正確重新整理,並保持最新狀態。 如果未使用標準連結庫,請確定實作遵循 最佳做法 一節。
OpenID Connect 探索文件和同盟中繼資料文件中永遠有一個以上的有效金鑰可用。 應用程式應該要已準備好使用文件中指定的任何和全部金鑰,因為某個金鑰可能很快就得要替換,而可能由另一個金鑰,依此類推。 當我們支援新的平台、雲端或驗證通訊協定時,出現的金鑰數目可能會隨著時間而改變,視 Microsoft 身分識別平台的內部架構而定。 JSON 回應中的索引鍵順序和公開金鑰的順序,都不應被視為對您應用程式有意義的順序。 若要深入瞭解 JSON Web 金鑰數據結構,您可以參考 RFC7517。
僅支援單一簽署密鑰的應用程式,或需要手動更新簽署金鑰的應用程式,原本就較不安全且較不可靠。 這些應用程式應該更新為使用標準程式庫 (部分機器翻譯),以確保其一律會使用最新的簽署金鑰,還有其他最佳做法。
金鑰元數據快取和驗證的最佳做法
- 使用租使用者特定端點探索密鑰,如 OpenID Connect (OIDC) 和同盟元數據中所述
- 即使您的應用程式部署在多個租用戶之間,還是建議一律針對應用程式服務的每個租用戶獨立探索和快取密鑰(使用租使用者特定的端點)。 現今在租用戶之間通用的密鑰,在未來的租用戶之間可能會變得不同。
- 使用下列快取演算法來確保快取具有彈性且安全
金鑰元資料快取演算法:
我們的 標準連結庫 會實作密鑰的復原與安全快取。 建議使用它們來避免實作中的細微缺陷。 針對自定義實作,以下是粗略演算法:
一般考慮:
- 驗證令牌的服務應該具有能夠儲存許多不同密鑰的快取(10-1000)。
- 密鑰應該個別快取,使用 OIDC 金鑰元資料規格中的金鑰標識碼 (“kid” 作為快取金鑰。
- 快取中索引鍵的存留時間應該設定為24小時,並每小時進行重新整理。 這可確保系統可以快速回應正在移除的密鑰,但有足夠的快取持續時間,不會受到擷取密鑰問題的影響。
- 金鑰應該重新整理:
- 進程啟動時或快取空白時
- 定期 (建議每 1 小時) 作為背景工作
- 以動態方式,如果收到的令牌是以未知密鑰簽署(標頭中未知 的孩子 或 潮汐 )
KeyRefresh 程式 (IdentityModel 的概念演算法)
初始化
組態管理員是使用特定位址來設定,以擷取組態數據和必要的介面來擷取和驗證此數據。
組態檢查
擷取新數據之前,系統會先根據預先定義的重新整理間隔來檢查現有數據是否仍然有效。
數據擷取 如果數據過期或遺失,系統會鎖定以確保只有一個線程擷取新的數據,以避免重複(以及線程耗盡)。 系統接著會嘗試從指定的端點擷取最新的組態數據。
驗證
擷取新數據之後,即會加以驗證,以確保其符合必要的標準,且未損毀。 只有在使用新金鑰成功驗證傳入要求時,才會接受元數據。
錯誤處理
如果在數據擷取期間發生任何錯誤,則會記錄這些錯誤。 如果無法擷取新數據,系統會繼續使用最後一個已知良好的設定運作
自動更新 系統會根據重新整理間隔定期檢查及更新設定數據(建議使用 12 小時加號或減 1 小時) 的抖動。 此外,也可以視需要手動要求更新,確保數據一律為最新狀態。
使用新金鑰 驗證令牌 如果令牌送達時還未從組態中得知的簽署密鑰,系統會嘗試在經常性路徑上使用同步呼叫來擷取設定,以在一般預期更新之外處理元數據中的新密鑰(但不超過 5 分鐘)
此方法可確保系統一律使用最新的和有效的組態數據,同時正常處理錯誤並避免重複作業。
此演算法的 .NET 實作可從 BaseConfigurationManager 取得。 它可能會根據復原和安全性評估而變更。 另請參閱這裡的說明
KeyRefresh 程式 (虛擬程式代碼):
此程式會使用全域 (lastSuccessfulRefreshTime 時間戳)來防止經常重新整理索引鍵的條件。
KeyRefresh(issuer)
{
// Store cache entries and last successful refresh timestamp per distinct 'issuer'
if (LastSuccessfulRefreshTime is set and more recent than 5 minutes ago)
return // without refreshing
// Load keys URI using the tenant-specific OIDC configuration endpoint ('issuer' is the input parameter)
oidcConfiguration = download JSON from "{issuer}/.well-known/openid-configuration"
// Load list of keys from keys URI
keyList = download JSON from jwks_uri property of oidcConfiguration
foreach (key in keyList)
{
cache entry = lookup in cache by kid property of key
if (cache entry found)
set expiration of cache entry to now + 24h
else
add key to cache with expiration set to now + 24h
}
set LastSuccessfulRefreshTime to now // current timestamp
}
服務啟動程式:
- 用來更新金鑰的 KeyRefresh
- 啟動每小時呼叫 KeyRefresh 的背景工作
驗證金鑰的 TokenValidation 程式(虛擬程式代碼):
ValidateToken(token)
{
kid = token.header.kid // get key id from token header
issuer = token.body.iss // get issuer from 'iss' claim in token body
key = lookup in cache by issuer and kid
if (key found)
{
validate token with key and return
}
else // key is not found in the cache
{
call KeyRefresh(issuer) // to opportunistically refresh the keys for the issuer
key = lookup in cache by issuer and kid
if (key found)
{
validate token with key and return
}
else // key is not found in the cache even after refresh
{
return token validation error
}
}
}
如何評估您的應用程式是否會受到影響,以及如何因應
應用程式處理金鑰變換的方式取決於各種變數,例如應用程式類型或使用的身分識別通訊協定和程式庫。 下列各節會評估最常見的應用程式類型是否會受到金鑰變換所影響,並提供如何更新應用程式以支援自動變換或手動更新金鑰的指引。
- 存取資源的原生用戶端應用程式
- 存取資源的 Web 應用程式 / API
- 保護資源且使用 Azure App Service 建置的 Web 應用程式 / API
- 使用 ASP.NET OWIN OpenID Connect、WS-Fed 或 WindowsAzureActiveDirectoryBearerAuthentication 中介軟體保護資源的 Web 應用程式 / API (部分機器翻譯)
- 使用 ASP.NET Core OpenID Connect 或 JwtBearerAuthentication 中介軟體保護資源的 Web 應用程式/API (部分機器翻譯)
- 使用 Node.js
passport-azure-ad
模組保護資源的 Web 應用程式 / API (部分機器翻譯) - 保護資源且使用 Visual Studio 2015 或更新版本建立的 Web 應用程式/API
- 保護資源且使用 Visual Studio 2013 建立的 Web 應用程式
- 保護資源且使用 Visual Studio 2013 建立的 Web API
- 保護資源且使用 Visual Studio 2012 建立的 Web 應用程式
- 保護資源且使用任何其他程式庫或手動實作任何支援的通訊協定的 Web 應用程式 / API
本指南 不 適用於︰
- 從 Microsoft Entra 應用程式資源庫 (包括自訂) 新增的應用程式有個別的簽署金鑰指引。 更多資訊。
- 透過應用程式 proxy 發佈的內部部署應用程式不需要擔心簽署金鑰。
存取資源的原生用戶端應用程式
只存取資源的應用程式 (例如 Microsoft Graph、KeyVault、Outlook API 和其他 Microsoft API) 只會取得權杖,並將權杖傳遞給資源擁有者。 假設它們並未保護任何資源,它們就不會檢查權杖,因此不需要確定已正確簽署。
原生用戶端應用程式 (不論是桌上型或行動) 屬於此分類,因此不受變換影響。
存取資源的 Web 應用程式 / API
只存取資源的應用程式 (例如 Microsoft Graph、KeyVault、Outlook API 和其他 Microsoft API) 只會取得權杖,並將權杖傳遞給資源擁有者。 假設它們並未保護任何資源,它們就不會檢查權杖,因此不需要確定已正確簽署。
使用應用程式專用流程 (用戶端認證 / 用戶端憑證) 要求權杖的 Web 應用程式和 Web API 屬於此類型,因此不受變換影響。
保護資源且使用 Azure App Service 建置的 Web 應用程式 / API
Azure App Service 的驗證/授權 (EasyAuth) 功能已經具有必要的邏輯可自動處理金鑰變換。
使用 ASP.NET OWIN OpenID Connect、WS-Fed 或 WindowsAzureActiveDirectoryBearerAuthentication 中介軟體保護資源的 Web 應用程式 / API
如果您的應用程式使用 ASP.NET OWIN OpenID Connect、WS-Fed 或 WindowsAzureActiveDirectoryBearerAuthentication 中介軟體,則它已經具有必要的邏輯可自動處理金鑰變換。
您可在應用程式的 Startup.cs 或 Startup.Auth.cs 檔案中尋找下列任何程式碼片段,以確認您的應用程式使用任何這些項目。
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// ...
});
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
// ...
});
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
// ...
});
使用 .NET Core OpenID Connect 或 JwtBearerAuthentication 中介軟體保護資源的 Web 應用程式/API
如果您的應用程式使用 ASP.NET OWIN OpenID Connect 或 JwtBearerAuthentication 中介軟體,則它已經具有自動處理金鑰變換的必要邏輯。
您可以應用程式的 Startup.cs 或 Startup.Auth.cs 中尋找下列任何程式碼片段,以確認您的應用程式使用任何這些項目
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// ...
});
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
// ...
});
使用 Node.js passport-azure-ad
模組保護資源的 Web 應用程式 / API
如果您的應用程式使用 Node.js passport-ad 模組,則它已經具有必要的邏輯可自動處理金鑰變換。
您可以在應用程式的 app.js 中搜尋下列程式碼片段,以確認您的應用程式使用 passport-ad
var OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
passport.use(new OIDCStrategy({
//...
));
保護資源且使用 Visual Studio 2015 或更新版本建立的 Web 應用程式/API
如果應用程式是使用 Visual Studio 2015 或更新版本中的 Web 應用程式範本所建置,而且您已從 [變更驗證] 功能表中選取 [辦公或學校帳戶],則其中已經具有自動處理金鑰變換的必要邏輯。 這個內嵌在 OWIN OpenID Connect 中介軟體中的邏輯會從 OpenID Connect 探索文件擷取並快取金鑰,還會定期重新整理金鑰。
如果您是以手動方式在方案中加入驗證,應用程式可能不會有所需的金鑰變換邏輯。 您可以自行撰寫,或依照 使用任何其他程式庫或手動實作任何支援的通訊協定的 Web 應用程式 / API (部分機器翻譯) 中的步驟進行。
保護資源且使用 Visual Studio 2013 建立的 Web 應用程式
如果應用程式是使用 Visual Studio 2013 中的 Web 應用程式範本所建置,而且您已從 [變更驗證] 功能表中選取 [組織帳戶],則它已經具有自動處理金鑰變換的必要邏輯。 此邏輯會將組織的唯一識別碼和簽署金鑰資訊儲存在兩個與專案相關聯的資料庫資料表中。 您可以在專案的 Web.config 檔案中找到資料庫的連接字串。
如果您是以手動方式在方案中加入驗證,應用程式可能不會有所需的金鑰變換邏輯。 您必須自行撰寫,或遵循使用任何其他連結庫的 Web 應用程式/API 中的步驟,或手動實作任何支援的通訊協定。
下列步驟可協助您確認應用程式中的邏輯能正常運作。
- 在 Visual Studio 2013 中開啟方案,然後選取右側視窗上的 [伺服器總管] 索引標籤。
- 依序展開 [資料連線]、[DefaultConnection]、[資料表]。 找出 [IssuingAuthorityKeys] 資料表並以滑鼠右鍵按一下,然後選取 [顯示資料表資料]。
- [IssuingAuthorityKeys] 資料表中會有至少一個對應至金鑰指紋值的資料列。 刪除資料表中的任何資料列。
- 在 [租用戶] 資料表上按一下滑鼠右鍵,然後選取 [顯示資料表資料]。
- [租用戶] 資料表中會有至少一個對應至唯一目錄租用戶識別碼的資料列。 刪除資料表中的任何資料列。 如果您未刪除 Tenants 數據表和 IssuingAuthorityKeys 數據表中的數據列,您會在運行時間收到錯誤。
- 建置並執行應用程式。 在登入帳戶之後,即可停止應用程式。
- 返回 [伺服器總管],然後查看 [IssuingAuthorityKeys] 和 [租用戶] 資料表中的值。 您會發現它們會自動從同盟元數據檔填入適當的資訊。
保護資源且使用 Visual Studio 2013 建立的 Web API
如果您使用 Web API 範本在 Visual Studio 2013 中建置了 Web API 應用程式,然後從 [變更驗證] 功能表中選取了 [組織帳戶],則應用程式已經具有所需的邏輯。
如果您以手動方式設定了驗證,請依照下列指示來了解如何設定 Web API 以自動更新其金鑰資訊。
下列程式碼片段示範如何從同盟中繼資料文件取得最新的金鑰,然後使用 JWT 權杖處理常式 (英文) 來驗證權杖。 此程式碼片段假設您將會使用自己的快取機制來保留金鑰,以驗證日後來自 Microsoft 身分識別平台的權杖,不論它位於資料庫、組態檔或其他位置。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IdentityModel.Tokens;
using System.Configuration;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.IdentityModel.Metadata;
using System.ServiceModel.Security;
using System.Threading;
namespace JWTValidation
{
public class JWTValidator
{
private string MetadataAddress = "[Your Federation Metadata document address goes here]";
// Validates the JWT Token that's part of the Authorization header in an HTTP request.
public void ValidateJwtToken(string token)
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler()
{
// Do not disable for production code
CertificateValidator = X509CertificateValidator.None
};
TokenValidationParameters validationParams = new TokenValidationParameters()
{
AllowedAudience = "[Your App ID URI goes here]",
ValidIssuer = "[The issuer for the token goes here, such as https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/]",
SigningTokens = GetSigningCertificates(MetadataAddress)
// Cache the signing tokens by your desired mechanism
};
Thread.CurrentPrincipal = tokenHandler.ValidateToken(token, validationParams);
}
// Returns a list of certificates from the specified metadata document.
public List<X509SecurityToken> GetSigningCertificates(string metadataAddress)
{
List<X509SecurityToken> tokens = new List<X509SecurityToken>();
if (metadataAddress == null)
{
throw new ArgumentNullException(metadataAddress);
}
using (XmlReader metadataReader = XmlReader.Create(metadataAddress))
{
MetadataSerializer serializer = new MetadataSerializer()
{
// Do not disable for production code
CertificateValidationMode = X509CertificateValidationMode.None
};
EntityDescriptor metadata = serializer.ReadMetadata(metadataReader) as EntityDescriptor;
if (metadata != null)
{
SecurityTokenServiceDescriptor stsd = metadata.RoleDescriptors.OfType<SecurityTokenServiceDescriptor>().First();
if (stsd != null)
{
IEnumerable<X509RawDataKeyIdentifierClause> x509DataClauses = stsd.Keys.Where(key => key.KeyInfo != null && (key.Use == KeyType.Signing || key.Use == KeyType.Unspecified)).
Select(key => key.KeyInfo.OfType<X509RawDataKeyIdentifierClause>().First());
tokens.AddRange(x509DataClauses.Select(token => new X509SecurityToken(new X509Certificate2(token.GetX509RawData()))));
}
else
{
throw new InvalidOperationException("There is no RoleDescriptor of type SecurityTokenServiceType in the metadata");
}
}
else
{
throw new Exception("Invalid Federation Metadata document");
}
}
return tokens;
}
}
}
保護資源且使用 Visual Studio 2012 建立的 Web 應用程式
如果應用程式是在 Visual Studio 2012 中建置的,您大概是使用身分識別與存取工具來設定應用程式。 您也可能使用 驗證簽發者名稱登入 (VINR) 。 VINR 負責維護信任的識別提供者 (Microsoft 身分識別平台) 相關資訊,以及用來驗證其所簽發權杖的金鑰。 VINR 也可透過下載與目錄相關聯的最新同盟中繼資料文件、使用最新文件檢查組態是否過期,以及視需要讓應用程式更新為使用新金鑰,讓您輕鬆地自動更新 Web.config 檔案中儲存的金鑰資訊。
如果您是使用 Microsoft 所提供的任何程式碼範例或逐步解說文件建立應用程式,則專案中已含有金鑰變換邏輯。 您會發現下列程式代碼已存在於您的專案中。 如果您的應用程式還沒有此邏輯,請遵循下列步驟來新增它,並確認其運作正常。
- 在 [方案總管] 中,針對適當的專案新增對 System.IdentityModel 組件的參考。
- 開啟 Global.asax.cs 檔案,並新增下列 using 指示詞:
using System.Configuration; using System.IdentityModel.Tokens;
- 在 Global.asax.cs 檔案中新增下列方法:
protected void RefreshValidationSettings() { string configPath = AppDomain.CurrentDomain.BaseDirectory + "\\" + "Web.config"; string metadataAddress = ConfigurationManager.AppSettings["ida:FederationMetadataLocation"]; ValidatingIssuerNameRegistry.WriteToConfig(metadataAddress, configPath); }
- 在 Global.asax.cs 的 Application_Start() 方法中,叫用 RefreshValidationSettings() 方法,如下所示︰
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ... RefreshValidationSettings(); }
在遵循這些步驟之後,應用程式的 Web.config 將會以同盟中繼資料文件中的最新資訊進行更新,其中也包括最新的金鑰。 此更新會在每次 IIS 回收應用程式集區時進行;依預設,IIS 設定為每隔 29 小時回收應用程式一次。
請遵循下列步驟來確認金鑰變換邏輯是否能運作。
- 在確認應用程式是使用上述程式碼之後,開啟 Web.config 檔案並瀏覽至 <issuerNameRegistry> 區塊,具體而言,請尋找下列幾行︰
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry"> <authority name="https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/"> <keys> <add thumbprint="AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" /> </keys>
- 在 <add thumbprint=""> 設定中,將任何字元替換為其他字元以變更指紋值。 儲存 Web.config 檔案。
- 建置應用程式,然後加以執行。 如果您可以完成登入程序,則應用程式已從目錄的同盟中繼資料文件下載所需資訊,而成功地更新金鑰。 如果您在登入時遇到問題,請閱讀使用 Microsoft 身分識別平台 將登入新增至 Web 應用程式一文,或下載並檢查下列程式代碼範例:Microsoft Entra ID 的多租使用者雲端應用程式,以確保應用程式中的變更正確無誤。
保護資源且使用任何其他程式庫或手動實作任何支援的通訊協定的 Web 應用程式 / API
如果您使用其他連結庫或手動實作任何支持的通訊協定,您必須檢閱連結庫或實作,以確保密鑰是從 OpenID Connect 探索檔或同盟元數據檔擷取。 檢查的方法之一是在您的程式碼或程式庫的程式碼中,搜尋是否有任何呼叫 OpenID 探索文件或同盟中繼資料文件的情況。
如果金鑰儲存在某處或硬式編碼在您的應用程式中,您可以手動擷取金鑰並根據本指導文件結尾的指示執行手動變換來更新金鑰。 強烈建議您增強應用程式來支援自動變換時使用本文描述的任何方法,以免未來如果 Microsoft 身分識別平台提高變換頻率或臨時需要緊急變換時,造成運作中斷和超出負荷。
如何測試您的應用程式,以判斷其是否會受影響
您可以藉由使用下列 PowerShell 指令碼,驗證您的應用程式是否支援自動金鑰變換。
若要使用 PowerShell 檢查和更新簽署金鑰,您需要 MSIdentityTools (英文) PowerShell 模組。
安裝 MSIdentityTools (英文) PowerShell 模組:
Install-Module -Name MSIdentityTools
搭配系統管理員帳戶使用 Connect-MgGraph 命令來登入,以同意所需的範圍:
Connect-MgGraph -Scope "Application.ReadWrite.All"
取得可用簽署金鑰指紋的清單:
Get-MsIdSigningKeyThumbprint
挑選任何金鑰指紋,並設定 Microsoft Entra ID 以將該金鑰與您的應用程式搭配使用 (從 Microsoft Entra 系統管理中心取得應用程式識別碼):
Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -KeyThumbprint <Thumbprint>
登入以取得新的權杖來測試 Web 應用程式。 密鑰更新變更是即時的,但請確定您使用新的瀏覽器會話(例如,使用 Internet Explorer 的 “InPrivate”、“Chrome 的 ”Incognito“ 或 Firefox 的 ”Private“ 模式),以確保您獲得新的令牌。
針對每個傳回的簽署金鑰指紋,執行
Update-MsIdApplicationSigningKeyThumbprint
Cmdlet 並測試您的 Web 應用程式登入程序。如果 Web 應用程式正確登入,則支援自動變換。 如果未正確登入,請修改您的應用程式以支援手動變換。 如需詳細資訊,請參閱建立手動變換程序。
執行下列指令碼以還原為正常行為:
Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -Default
如果您的應用程式不支援自動變換,如何執行手動變換
如果您的應用程式不支援自動變換,您必須先建立程序,該程序會定期監視 Microsoft 身分識別平台的簽署金鑰,並據此執行手動變換。
若要使用 PowerShell 檢查及更新簽署金鑰,您需要 MSIdentityTools
PowerShell 模組。
安裝
MSIdentityTools
(英文) PowerShell 模組:Install-Module -Name MSIdentityTools
取得最新的簽署金鑰 (從 Microsoft Entra 系統管理中心取得租用戶識別碼):
Get-MsIdSigningKeyThumbprint -Tenant <tenandId> -Latest
比較此金鑰與應用程式目前已硬式編碼或設定為使用的金鑰。
如果最新的金鑰與應用程式所使用的金鑰不同,請下載最新的簽署金鑰:
Get-MsIdSigningKeyThumbprint -Latest -DownloadPath <DownloadFolderPath>
更新應用程式的程式碼或組態,以使用新的金鑰。
設定 Microsoft Entra ID 以將該最新金鑰與您的應用程式搭配使用 (從 Microsoft Entra 系統管理中心取得應用程式識別碼):
Get-MsIdSigningKeyThumbprint -Latest | Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId>
登入以取得新的權杖來測試 Web 應用程式。 密鑰更新變更是即時的,但請確定您使用新的瀏覽器會話,以確保您已發行新的令牌。 例如,使用 Microsoft Edge 的 “InPrivate”、“Chrome 的 ”Incognito“ 或 Firefox 的 ”Private“ 模式。
如果您遇到任何問題,請還原為先前使用的金鑰,並連絡 Azure 支援:
Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -KeyThumbprint <PreviousKeyThumbprint>
更新應用程式以支援手動變換之後,請還原為正常行為:
Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -Default