API 保護

當您身為開發人員,保護您的 API 時,您的重點是授權。 若要呼叫資源的 API,應用程式必須 取得應用程式授權。 資源本身必須強制執行授權。 在本文中,您將瞭解透過註冊、定義許可權和同意來保護 API 的最佳做法,以及強制執行存取以達成您的 零信任 目標。

註冊受保護的 API

若要 使用 Microsoft Entra ID 保護 API(Microsoft Entra ID),您必須先 註冊 API,之後您可以 管理已註冊的 API。 在 Microsoft Entra ID 中,API 是具有特定應用程式註冊設定的應用程式,可將它定義為資源或 API,讓另一個應用程式獲得授權才能存取。 在 Microsoft Entra 系統管理中心,Microsoft 身分識別開發人員,應用程式註冊,是租使用者中的 API,可以是企業營運 API,或是來自具有 Microsoft Entra ID 保護之 API 的 SaaS 提供者的服務。

在註冊期間,您會定義呼叫應用程式如何參考 API 及其 委派應用程式許可權。 應用程式註冊可以代表同時具有用戶端應用程式和 API 的解決方案。 不過,在本文中,我們會解決獨立資源公開 API 的案例。

一般而言,API 不會執行驗證或直接要求授權。 API 會驗證呼叫端應用程式所呈現的令牌。 API 沒有互動式登入,因此您不需要註冊重新導向 URI 或應用程式類型等設定。 API 會從呼叫這些 API 的應用程式取得其令牌,而不是透過與 Microsoft Entra 標識符互動。 針對 Web API,請使用 OAuth2 存取令牌 進行授權。 Web API 會驗證持有人令牌以授權呼叫端。 不接受 標識碼令牌 作為許可權證明。

根據預設,Microsoft Entra ID 會新增 User.Read 至任何新應用程式註冊的 API 許可權。 您可以針對大部分 的 Web API 移除此許可權。 只有在 API 呼叫另一個 API 時,Microsoft Entra ID 才需要 API 許可權。 如果您的 API 未呼叫另一個 API,請在註冊 API 時移除 User.Read 許可權。

您需要 API 的唯一識別碼,稱為 應用程式識別碼 URI,而需要存取 API 的用戶端應用程式會要求呼叫 API 的許可權。 應用程式識別碼 URI 在所有 Microsoft Entra 租使用者中都必須是唯一的。 您可以使用 api://<clientId> (入口網站中的預設建議),其中 <clientId> 是已註冊 API 的應用程式識別碼。

若要為呼叫 API 的開發人員提供更方便使用的名稱,您可以使用 API 的地址作為應用程式識別碼 URI。 例如,您可以使用 https://API.yourdomain.com ,其中 yourdomain.com 必須是 Microsoft Entra 租用戶中設定的發行者網域。 Microsoft 會驗證您擁有網域的擁有權,以便將其作為 API 的唯一標識碼。 您不需要在此位址有程式代碼。 API 可以是您想要的位置,但最好是使用 API 的 HTTPS 位址作為應用程式識別碼 URI。

使用最低許可權定義委派的許可權

如果您的 API 將由具有使用者的應用程式呼叫,您必須定義至少一個委派的許可權(請參閱在應用程式註冊上新增範圍公開 API)。

提供組織數據存放區存取權的 API 可以吸引想要存取該數據的攻擊者的注意。 您不必只擁有一個委派的許可權,而是使用 零信任 最低許可權存取原則來設計許可權。 如果所有用戶端應用程式都以完整許可權存取開始,稍後可能會很難進入最低許可權模型。

開發人員通常會陷入使用單一許可權的模式,例如「以使用者身分存取」或「用戶模擬」(這是技術上不正確的常見片語)。 這類單一許可權只允許完整且具特殊許可權的 API 存取。

宣告最低許可權範圍,讓您的應用程式不會容易受到入侵或用來執行您從未預期的工作。 在 API 許可權定義多個範圍。 例如,將範圍與讀取和更新數據分開,並考慮提供唯讀許可權。 「寫入存取權」包含建立、更新和刪除作業的許可權。 客戶端絕對不需要寫入許可權才能讀取數據。

當您的 API 與敏感數據搭配使用時,請考慮「標準」和「完整」訪問許可權。 限制敏感性屬性,讓標準許可權不允許存取 (例如 , Resource.Read)。 然後實作傳回屬性和敏感性資訊的「完整」訪問許可權(例如 Resource.ReadFull)。

請一律評估您要求的許可權,以確保您尋求絕對最低許可權集以完成作業。 避免要求較高的許可權許可權。 相反地,請為每個核心案例建立個別許可權。 如需此方法的良好範例,請參閱 Microsoft Graph 許可權參考。 找出並使用正確的許可權數目來因應您的需求。

在您的範圍定義中,決定是否可以使用特定範圍 執行的作業範圍需要系統管理員同意

身為 API 設計工具,您可以提供哪些範圍可以安全地要求使用者同意的指引。 不過,租使用者管理員可以設定租使用者,讓所有許可權都需要管理員同意。 如果您將範圍定義為需要管理員同意,許可權一律需要管理員同意。

決定使用者或系統管理員同意時,您有兩個主要考慮:

  1. 許可權背後的作業範圍是否影響超過單一使用者。 如果許可權允許用戶選擇哪些應用程式只能存取自己的資訊,則使用者同意可能適用。 例如,使用者可以同意選擇他們慣用的電子郵件應用程式。 不過,如果許可權背後的作業涉及多個單一使用者(例如,檢視其他使用者的完整使用者配置檔),則請將該許可權定義為需要系統管理員同意。

  2. 許可權背後的作業範圍是否具有廣泛的範圍。 例如,廣泛的範圍是當許可權可讓應用程式變更租使用者中的所有內容,或執行可能無法復原的動作時。 廣泛的範圍表示您需要系統管理員同意,而不是使用者同意。

Err 在保守方面, 如果你懷疑, 需要管理員同意。 清楚且簡潔地描述您許可權字串中同意的後果。 假設個別讀取您的描述字串並不熟悉您的 API 或產品。

請避免以變更許可權語意的方式,將 API 新增至現有的許可權。 超載現有的許可權會淡化先前授與用戶端同意的原因。

定義應用程式許可權

當您建置 非使用者應用程式時,您沒有可以提示使用者輸入使用者名稱和密碼或多重要素驗證 (MFA) 的使用者。 如果沒有使用者的應用程式(例如工作負載、服務和精靈)呼叫您的 API,您必須為 API 定義 應用程式許可權 。 當您定義應用程式許可權時,您會使用 應用程式角色 ,而不是使用範圍。

如同委派的許可權,您可以提供細微的應用程式許可權,讓呼叫 API 的工作負載可以遵循最低許可權存取權,並符合 零信任 原則。 請避免只發佈一個應用程式角色(應用程式許可權)和一個範圍(委派許可權),或向每個客戶端公開所有作業。

工作負載會使用客戶端認證進行驗證,.default並使用範圍要求令牌,如下列範例程式代碼所示。

// With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the 
// application permissions need to be set statically (in the portal or by PowerShell), 
// and then granted by a tenant administrator
string[] scopes = new string[] { "https://kkaad.onmicrosoft.com/webapi/.default" };
 
AuthenticationResult result = null;
try
{
  result = await app.AcquireTokenForClient(scopes)
    .ExecuteAsync();
  Console.WriteLine("Token acquired \n");
}
catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
{
  // Invalid scope. The scope has to be of the form "https://resourceurl/.default"
  // Mitigation: change the scope to be as expected
  Console.WriteLine("Scope provided is not supported");
}

當應用程式前面沒有使用者,且應用程式許可權啟用廣泛的作業時,許可權需要系統管理員同意。

強制存取

藉由驗證和解譯呼叫應用程式的存取令牌,以在 HTTPS 要求的授權標頭中提供做為持有人令牌,以確保您的 API 強制執行存取。 您可以驗證令牌、管理元數據重新整理,以及強制執行範圍和角色,以強制執行存取權,如下列各節所述。

驗證令牌

在 API 收到令牌之後,它必須 驗證令牌。 驗證可確保令牌來自適當的簽發者,如未取樣且未修改。 檢查簽章,因為您不會像使用標識符令牌一樣直接從 Microsoft Entra ID 取得令牌。 在 API 收到來自網路上不受信任來源的令牌之後,驗證簽章。

由於 JSON Web 令牌簽章驗證有已知的弱點,因此請使用妥善維護且已建立的標準令牌驗證連結庫。 驗證連結庫 (例如 Microsoft.Identity.Web) 會使用適當的步驟,並降低已知弱點的風險。

選擇性地 擴充令牌驗證。 使用租使用者識別碼 (tid) 宣告來限制 API 可以取得令牌的租使用者。 azp使用和 appid 宣告來篩選可呼叫 API 的應用程式。 使用物件標識碼 (oid) 宣告,進一步縮小個別使用者的存取範圍。

管理元數據重新整理

請務必確定您的令牌驗證連結庫能有效地管理所需的元數據。 在此情況下,元數據是公鑰、私鑰組,Microsoft 用來簽署 Microsoft Entra 令牌。 當您的連結庫驗證這些令牌時,他們會從已知的因特網位址取得我們發佈的公開簽署密鑰清單。 請確定裝載環境有正確的時機可取得這些金鑰。

例如,較舊的連結庫偶爾會硬式編碼,每隔 24 小時更新這些公開簽署密鑰。 請考慮當 Microsoft Entra ID 必須快速輪替這些密鑰,且您下載的金鑰不包含新的輪替密鑰時。 您的 API 可能會在等候其元數據重新整理週期時脫機一天。 參考 特定的元數據重新整理指引 ,以確保您已正確取得元數據。 如果您使用連結庫,請確定它會在合理的時間內處理該元數據。

強制執行範圍和角色

驗證令牌之後,您的 API 會查看令牌中的宣告,以判斷其運作方式。

若為委派的許可權令牌,請讓 API 檢查範圍 (scp) 宣告,以查看應用程式同意執行什麼動作。 檢查物件識別碼 (oid) 或主旨索引鍵 (sub) 宣告,以查看代表應用程式運作的使用者。

然後,請進行 API 檢查,以確保使用者也可以存取要求的作業。 如果您的 API 定義 要指派給使用者和群組的角色,請讓 API 檢查令牌中的任何角色宣告,並據以運作。 應用程式許可權令牌沒有範圍 (scp) 宣告。 相反地,請讓 API 檢查角色宣告,以判斷工作負載收到的應用程式許可權。

在 API 驗證令牌和範圍,並處理物件識別碼 ()、主體金鑰 (oidsub) 和角色宣告之後,您的 API 可以傳回結果。

下一步

  • 受 Microsoft 身分識別同意架構 保護的 API 範例可協助您設計最低許可權的應用程式許可權策略,以獲得最佳用戶體驗。
  • 從另一個 API 呼叫 API 可協助您確保有一個 API 需要呼叫另一個 API,並在應用程式代表使用者運作時安全地開發應用程式時,零信任。
  • 自定義令牌 描述您可以在 Microsoft Entra 令牌中接收的資訊。 它說明如何自定義令牌,以改善彈性和控制,同時提高應用程式零信任安全性與最低許可權。
  • 在令牌 中設定群組宣告和應用程式角色會示範如何使用應用程式角色定義來設定應用程式,並將安全組指派給應用程式角色。 這些方法有助於改善彈性和控制,同時以最低許可權增加應用程式零信任安全性。
  • 取得存取資源的授權可協助您瞭解如何在取得應用程式的資源訪問許可權時,最好確保 零信任。
  • 要求需要系統管理同意 的許可權描述應用程式許可權需要系統管理同意時的許可權和同意體驗。
  • 在本快速入門中:使用 Microsoft 身分識別平台 保護 Web API,瞭解如何藉由將資源的存取限制為僅限授權帳戶來保護 ASP.NET Web API。
  • 在本教學課程 - 在 Azure API 管理 中轉換和保護 API,瞭解如何設定通用原則以隱藏 API HTTP 回應中的技術堆疊資訊或原始 URL。