共用方式為


條件式存取驗證內容的開發人員指南

適用於帶有白色核取記號符號的綠色圓圈,表示以下內容適用於員工租戶。 員工租戶 帶有白色核取記號符號的綠色圓圈,表示以下內容適用於外部租戶。 外部租戶 (進一步了解

條件式存取是零信任控制平面,讓您針對原則存取所有的應用程式 (無論新舊、私人或公用、內部部署或多雲端)。 使用條件式存取驗證內容,您可以在這些應用程式內套用不同的原則。

條件式存取驗證內容 (驗證內容) 可讓您將細微的原則套用至敏感性資料和動作,而非僅在應用層級上。 您可以針對最低權限存取來精簡零信任原則,同時將使用者的分歧降至最低,讓使用者更具生產力,並讓您的資源更安全。 目前,應用程式會使用 OpenId Connect 來驗證公司開發的驗證,以保護敏感性資源,例如高價值交易或檢視員工個人資料。

若要從應用程式和服務內觸發逐步驗證,請使用 Microsoft Entra 條件式存取引擎的驗證內容功能。 開發人員現在有能力從他們的應用程式內,選擇性地要求增強式驗證,例如從他們的使用者進行 MFA。 這項功能可協助開發人員為應用程式的多數元件建立更順暢的使用者體驗,同時對於更安全作業和資料的存取仍會受到增強式驗證控制項的保護。

問題陳述

IT 系統管理員和監管機構通常難以平衡提示使用者與驗證的額外因素,並達到應用程式的適當安全性和原則遵循。 這可能涉及選擇一個對用戶生產力提升或降低有影響的嚴格政策,或一個在敏感資源方面不夠嚴格的政策。

那麼,如果應用程式能夠混合兩者,該怎麼辦? 在大多數場景中,以較低安全層級運作,並且減少提示次數。 然後在存取更敏感數據時,有條件地加緊安全性需求?

常見場景

例如,雖然使用者可能會使用多重要素驗證登入 SharePoint,但存取包含敏感性文件的 SharePoint 網站集合可能需要相容的裝置,而且只能從受信任的 IP 範圍存取。

必要條件

第一,您的應用程式應該使用 OpenID Connect/ OAuth 2.0 通訊協定與Microsoft 身分識別平台整合,以進行驗證和授權。 建議您使用 Microsoft 身分識別平台驗證程式庫,以整合該應用程式與 Microsoft Entra ID 並保護。 Microsoft 身分識別平台文件 是瞭解如何將應用程式與 Microsoft 身分識別平台整合的好起點。 條件式存取驗證內容功能支援建置於產業標準 OpenID Connect 通訊協定所提供的通訊協定延伸。 開發人員使用條件式存取驗證內容參考搭配 Claims Request 參數,讓應用程式能夠觸發和滿足原則。

第二個條件式存取 需要Microsoft Entra ID P1 授權。 如需授權的詳細資訊,請參閱 Microsoft Entra 價格頁面

第三,目前其僅適用於登入使用者的應用程式。 不支援自我驗證的應用程式。 使用 驗證流程和應用程式案例指南,以瞭解 Microsoft 身分識別平台支援的驗證應用程式類型和流程。

整合步驟

一旦使用支援的驗證通訊協定整合,並在具有條件式存取功能的 Microsoft Entra 租用戶中註冊此功能,您就可以開始在應用程式中整合這項功能。

注意

這項功能的詳細逐步解說也會在應用程式中使用條件式存取驗證內容進行升級驗證時,以記錄的工作階段形式提供。

首先,在您的租用戶中宣告驗證內容並將其提供使用。 如需詳細資訊,請參閱設定驗證內容

C1-C99 的值可用來作為租用戶中的 驗證內容識別碼。 驗證內容的範例可能是:

  • C1 - 需要增強式驗證
  • C2 - 需要相容的裝置
  • C3 - 需要信任的位置

若要使用條件式存取驗證內容,請建立或修改條件式存取原則。 範例原則可以是:

  • 登入此 Web 應用程式的所有使用者都必須順利完成 2FA 以驗證上下文 ID C1
  • 登入此 Web 應用程式的所有使用者都必須順利完成 2FA,而且也必須從已定義的 IP 位址範圍存取應用程式,以進行驗證內容識別碼 C3

注意

條件式存取驗證內容值是與應用程式分開宣告和維護。 不建議讓應用程式對驗證內容識別碼具有硬式相依性。 IT 系統管理員通常會製作條件式存取原則,因為他們更瞭解可用的資源。 同樣地,如果應用程式是在多個租用戶中使用,則使用中的驗證內容識別碼可能會不同,而在某些情況下則無法使用。

第二:針對打算使用條件式存取驗證內容的應用程式開發人員,建議先提供應用程式管理員或 IT 系統管理員一種將潛在的敏感性動作對應至驗證內容識別碼的方法。 步驟大致如下:

  1. 識別程式碼中可讓您對應驗證內容識別碼的動作。
  2. 在應用程式的管理入口網站中建立畫面 (或對等功能),讓 IT 系統管理員可以將敏感性動作對應至可用的驗證內容識別碼。
  3. 如需範例,請參閱程式代碼範例 :使用條件式存取驗證內容來執行逐步驗證

這些步驟是您必須在程式碼基底中執行的變更。 這些步驟包含廣泛的內容

  • 查詢 MS Graph 以列出所有可用的驗證內容
  • 允許 IT 系統管理員選取敏感性/高級權限作業,並使用條件式存取原則針對可用的驗證內容指派這些作業。
  • 將此對應資訊儲存在您的資料庫/本機存放區中。

建立驗證內容的設定流程

第三:在此範例中,我們假設您的應用程式是 Web API,然後需要針對儲存的對應評估呼叫,並據以針對其用戶端應用程式提出宣告挑戰。 若要準備此動作,請採取下列步驟:

  1. 在受驗證內容保護的敏感性作業中,針對稍早儲存的驗證內容識別碼對應評估 acrs 宣告中的值,並觸發 宣告挑戰,如下列程式碼片段所提供。

  2. 下圖顯示使用者、用戶端應用程式和 Web API 之間的互動。

    此圖表顯示使用者、Web 應用程式、API 和 Microsoft Entra ID 的互動

    接下來的程式碼片段來自程式碼範例,請使用條件式存取驗證內容來執行升級驗證。 第一個方法,API 中的 CheckForRequiredAuthContext()

    • 檢查要呼叫的應用程式動作是否需要升級驗證。 這會藉由檢查其資料庫是否有這個方法的儲存對應來執行此動作
    • 如果此動作確實需要較高的驗證內容,則會檢查 acr 宣告中是否有現有的相符驗證內容識別碼。
    • 如果找不到相符的驗證內容識別碼,系統便會提出宣告挑戰
    public void CheckForRequiredAuthContext(string method)
    {
        string authType = _commonDBContext.AuthContext.FirstOrDefault(x => x.Operation == method
                    && x.TenantId == _configuration["AzureAD:TenantId"])?.AuthContextId;
    
        if (!string.IsNullOrEmpty(authType))
        {
            HttpContext context = this.HttpContext;
            string authenticationContextClassReferencesClaim = "acrs";
    
            if (context == null || context.User == null || context.User.Claims == null
                || !context.User.Claims.Any())
            {
                throw new ArgumentNullException("No Usercontext is available to pick claims from");
            }
    
            Claim acrsClaim = context.User.FindAll(authenticationContextClassReferencesClaim).FirstOrDefault(x
                => x.Value == authType);
    
            if (acrsClaim == null || acrsClaim.Value != authType)
            {
                if (IsClientCapableofClaimsChallenge(context))
                {
                    string clientId = _configuration.GetSection("AzureAd").GetSection("ClientId").Value;
                    var base64str = Convert.ToBase64String(Encoding.UTF8.GetBytes("{\"access_token\":{\"acrs\":{\"essential\":true,\"value\":\"" + authType + "\"}}}"));
    
                    context.Response.Headers.Append("WWW-Authenticate", $"Bearer realm=\"\", authorization_uri=\"https://login.microsoftonline.com/common/oauth2/authorize\", client_id=\"" + clientId + "\", error=\"insufficient_claims\", claims=\"" + base64str + "\", cc_type=\"authcontext\"");
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    string message = string.Format(CultureInfo.InvariantCulture, "The presented access tokens had insufficient claims. Please request for claims requested in the WWW-Authentication header and try again.");
                    context.Response.WriteAsync(message);
                    context.Response.CompleteAsync();
                    throw new UnauthorizedAccessException(message);
                }
                else
                {
                    throw new UnauthorizedAccessException("The caller does not meet the authentication  bar to carry our this operation. The service cannot allow this operation");
                }
            }
        }
    }
    

    注意

    宣告挑戰的格式會在 Microsoft 身分識別平台中的宣告挑戰 一文中說明。

  3. 在用戶端應用程式中,攔截宣告挑戰,並將使用者重新導向回 Microsoft Entra ID,以進行進一步的原則評估。 接下來的程式碼片段來自程式碼範例,請使用條件式存取驗證內容來執行升級驗證

    internal static string ExtractHeaderValues(WebApiMsalUiRequiredException response)
    {
        if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized && response.Headers.WwwAuthenticate.Any())
        {
            AuthenticationHeaderValue bearer = response.Headers.WwwAuthenticate.First(v => v.Scheme == "Bearer");
            IEnumerable<string> parameters = bearer.Parameter.Split(',').Select(v => v.Trim()).ToList();
            var errorValue = GetParameterValue(parameters, "error");
    
            try
            {
                // read the header and checks if it contains error with insufficient_claims value.
                if (null != errorValue && "insufficient_claims" == errorValue)
                {
                    var claimChallengeParameter = GetParameterValue(parameters, "claims");
                    if (null != claimChallengeParameter)
                    {
                        var claimChallenge = ConvertBase64String(claimChallengeParameter);
    
                        return claimChallenge;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        return null;
    }
    

    處理對 Web API 呼叫中的例外狀況,如果出現宣告挑戰,則會將使用者重新導向回 Microsoft Entra ID 以進行進一步處理。

    try
    {
        // Call the API
        await _todoListService.AddAsync(todo);
    }
    catch (WebApiMsalUiRequiredException hex)
    {
        // Challenges the user if exception is thrown from Web API.
        try
        {
            var claimChallenge =ExtractHeaderValues(hex);
            _consentHandler.ChallengeUser(new string[] { "user.read" }, claimChallenge);
    
            return new EmptyResult();
        }
        catch (Exception ex)
        {
            _consentHandler.HandleException(ex);
        }
    
        Console.WriteLine(hex.Message);
    }
    return RedirectToAction("Index");
    
  4. (選擇性) 宣告用戶端功能。 用戶端功能可協助資源提供者 (RP)例如 Web API 來偵測用戶端應用程式是否瞭解宣告挑戰,然後可以據此自定義其回應。 這項功能很有用,因為並非所有 API 用戶端都能處理宣告挑戰,有些較舊的用戶端則仍預期會有不同的回應。 如需詳細資訊,請參閱用戶端功能一節。

注意事項及建議

請勿在應用程式程式碼中寫入驗證內容值。 應用程式應該使用 MS Graph 呼叫來讀取和套用驗證內容。 這種做法對於多租用戶應用程式來說很重要。 驗證內容的值會因 Microsoft Entra 租戶而異,無法在 Microsoft Entra ID Free edition 中使用。 如需應用程式在其程式代碼中查詢、設定和使用驗證內容的詳細資訊,請參閱程式碼範例: 使用條件式存取驗證內容來執行逐步驗證

應用程式本身是條件式存取原則的目標時,請勿使用驗證內容。 當應用程式的組件需要使用者符合較高層級的驗證時,此功能的效果最佳。

程式碼範例

條件式存取預期行為的驗證內容 [ACR]

明確符合要求中的驗證內容

用戶端可以透過要求本文的宣告,明確要求包含驗證內容 (ACRS) 的權杖。 如果已要求 ACRS,在完成所有挑戰後,條件式存取允許以所要求的 ACRS 發行令牌。

租用戶的條件式存取未保護驗證內容時的預期行為

當指派給 ACRS 值的所有條件式存取原則都滿足時,條件式存取可以在令牌的宣告中發出 ACRS。 如果未將條件式存取原則指派給 ACRS 值,則宣告可能仍會發出,因為已滿足所有原則需求。

明確要求 ACRS 時預期行為的摘要資料表

已要求 ACRS 套用的原則 滿足的控制項 新增至宣告的 ACRS
沒有以 ACRS 設定的原則

透過隨機評估來滿足的隱含驗證內容

資源提供者可以加入選用的 'acrs' 宣告。 條件式存取會嘗試以機會方式將 ACRS 新增至權杖宣告,以避免往返 Microsoft Entra ID 取得新權杖。 在該評估中,條件式存取會檢查保護驗證內容挑戰的原則是否已滿足,並視需要將 ACRS 新增至權杖宣告。

注意

每種令牌類型都必須單獨選擇加入(ID 令牌、存取令牌)。

如果資源提供者未選擇加入選擇性的『acrs』宣告,唯一在令牌中取得 ACRS 的方式是在令牌請求中明確指定它。 它不會取得機會性評估的優點,因此每當令牌宣告中遺漏必要的 ACRS 時,資源提供者會挑戰用戶端取得包含在宣告中的新令牌。

隱含 ACRS 隨機評估的驗證內容和工作階段預期行為

間隔登入的頻率

條件式存取會將「依間隔登入頻率」視為在登入頻率間隔內,當所有目前驗證因素驗證瞬間都位於登入頻率間隔內時,符合機會性 ACRS 評估。 如果任一驗證因素不再有效,則不滿足指定時間間隔的登入頻率,且 ACRS 不會事機而定地在令牌中發出。

Cloud App Security (CAS)

條件式存取在評估機會式 ACRS 時,若 CAS 會話已在該請求期間建立,則認為 CAS 會話控制已滿足。 例如,當有請求進來時,如果有任何條件式存取原則套用並強制執行 CAS 會話,而還有其他條件式存取原則也需要 CAS 會話,因為 CAS 會話已被強制執行,所以這個 CAS 會話滿足了條件式評估中的機會主義原則。

租用戶包含保護驗證內容之條件式存取原則時的預期行為

下表顯示 ACRS 透過即時評估新增至令牌宣告的所有邊界案例。

原則 A:要求所有使用者的 MFA,但要求 "c1" acrs 時,不包括使用者 "Ariel"。 原則 B:封鎖所有使用者,但要求 "c2" 或 "c3" acrs 時,不包括使用者 "Jay"。

Flow 已要求 ACRS 套用的原則 滿足的控制項 新增至宣告的 ACRS
Ariel 要求存取權杖 “c1” "c1" 為是。 "c2" 和 "c3" 為否 "c1" (已要求)
Ariel 要求存取權杖 “c2” 原則 B 以原則 B 封鎖
Ariel 要求存取權杖 "c1" 為是。 "c2" 和 "c3" 為否 "c1" (隨機從原則 A 新增)
Jay 要求存取權杖 (不透過 MFA) “c1” 原則 A
Jay 要求存取權杖 (透過 MFA) “c1” 原則 A "c1" (已要求)、"c2" (隨機從原則 B 新增)、"c3" (隨機從原則 B 新增)
Jay 要求存取權杖 (不透過 MFA) “c2” "c2" 和 "c3" 為是。 "c1" 為否 "c2" (已要求)、"c3" (隨機從原則 B 新增)
Jay 要求存取權杖 (透過 MFA) “c2” "c1"、"c2" 和 "c3" 為是 "c1"(盡量從 A 原則)、"c2" (已要求)、"c3" (隨機從原則 B 新增)
Jay 要求存取權杖 (透過 MFA) "c1"、"c2" 和 "c3" 為是 "c1"、"c2"、"c3" 全部隨機新增
Jay 要求存取權杖 (不透過 MFA) "c2" 和 "c3" 為是。 "c1" 為否 "c2"、"c3" 全部隨機新增

下一步