共用方式為


使用 AD FS 2019 風險評估模型建置外掛程式

您現在可以建置自己的外掛程式,以在收到要求、預先驗證和驗證後等各個階段,封鎖驗證要求或指派風險分數。 這可以使用 AD FS 2019 引進的新風險評估模型來完成。

什麼是風險評估模型?

風險評估模型是一組介面和類別,可讓開發人員讀取驗證要求標頭並實作自己的風險評估邏輯。 實作的程式碼 (外掛程式) 接著會按照 AD FS 驗證程序執行。 例如,使用模型隨附的介面和類別,您可以實作程式碼,根據要求標頭中包含的用戶端 IP 位址來封鎖或允許驗證要求。 AD FS 會針對每個驗證要求執行程式碼,並根據實作的邏輯採取適當的動作。

此模型允許在 AD FS 驗證管線三個階段中的任何一個階段建置外掛程式程式碼,如下所示:

Diagram that shows the three stages of A D F S authentication.

  1. 要求接收階段 – 可建置外掛程式,在 AD FS 收到驗證要求時允許或封鎖要求,也就是在使用者輸入認證之前。 您可以使用此階段可用的要求內容 (例如:用戶端 IP、HTTP 方法、Proxy 伺服器 DNS 等) 來執行風險評估。 例如,您可以建置外掛程式,從要求內容讀取 IP,並在 IP 位於預先定義的風險性 IP 清單中時封鎖驗證要求。

  2. 預先驗證階段 – 可建置外掛程式,在使用者提供認證時,但是在 AD FS 評估認證之前,允許或封鎖要求。 在這個階段,除了要求內容之外,您也有安全性內容的相關資訊 (例如:使用者權杖、使用者識別碼等) 和通訊協定內容 (例如:驗證通訊協定、clientID、resourceID 等),以用於風險評估邏輯中。 例如,您可以建置外掛程式以防止密碼噴灑攻擊,方法是從使用者權杖讀取使用者密碼,並在密碼位於預先定義的風險性密碼清單中時封鎖驗證要求。

  3. 驗證後 – 可建置外掛程式,在使用者提供認證且 AD FS 執行驗證之後評估風險。 在這個階段,除了要求內容、安全性內容和通訊協定內容之外,您也有驗證結果的相關資訊 (成功或失敗)。 外掛程式可以根據可用資訊評估風險分數,並將風險分數傳遞至宣告和原則規則以進行進一步評估。

為了進一步了解如何建置風險評估外掛程式,並按照 AD FS 程序執行,讓我們建置範例外掛程式,以封鎖來自特定外部網路 IP (已識別為風險性) 的要求,向 AD FS 註冊外掛程式,最後測試功能。

注意

您也可以建置風險性使用者外掛程式,這個範例外掛程式會根據 Microsoft Entra ID Protection 決定的使用者風險層級,來封鎖驗證或強制執行多重要素驗證 (MFA)。 這裡提供建置風險性使用者外掛程式的步驟。

建置範例外掛程式

注意

本逐步解說只會說明如何建立範例外掛程式。 我們建立的解決方案絕不是企業就緒的解決方案。

必要條件

以下是建置此範例外掛程式所需的必要條件清單:

  • 已安裝並設定 AD FS 2019
  • .NET Framework 4.7 和以上版本
  • Visual Studio

建置外掛程式 dll

下列程序將會逐步引導您建置範例外掛程式 dll:

  1. 下載範例外掛程式,使用 Git Bash 並輸入下列內容:

    git clone https://github.com/Microsoft/adfs-sample-RiskAssessmentModel-RiskyIPBlock
    
  2. 在您的 AD FS 伺服器上的任何位置建立 .csv 檔案 (在我的案例中,我在 C:\extensions 建立 authconfigdb.csv 檔案),並且將您想要封鎖的 IP 新增至此檔案。

    此範例外掛程式會封鎖來自此檔案中所列出外部網路 IP 的任何驗證要求。

    注意

    如果您有 AD FS 伺服器陣列,您可以在任何或所有 AD FS 伺服器上建立檔案。 任何檔案都可以用來將風險性 IP 匯入 AD FS。 我們會在以下向 AD FS 註冊外掛程式 dll 一節中詳細討論匯入程序。

  3. 使用 Visual Studio 開啟 ThreatDetectionModule.sln 專案。

  4. 從 [方案總管] 移除 Microsoft.IdentityServer.dll,如下所示:
    Screenshot that highlights the Remove menu option.

  5. 新增 AD FS Microsoft.IdentityServer.dll 的參考,如下所示:

    a. 在 [方案總管] 中以滑鼠右鍵按一下 [參考],然後選取 [新增參考…]

    Screenshot that highlights the Add Reference menu option.

    b. 在 [參考管理員] 視窗中,選取 [瀏覽]。 在 [選取要參考的檔案…] 對話方塊中,從您的 AD FS 安裝資料夾中選取 Microsoft.IdentityServer.dll (在我的案例中是 C:\Windows\ADFS),然後按一下 [新增]

    注意

    在我的案例中,我在 AD FS 伺服器本身建置外掛程式。 如果您的開發環境位於不同的伺服器上,請Microsoft.IdentityServer.dll從 AD FS 伺服器上的 AD FS 安裝資料夾複製到您的開發方塊。

    Screenshot that shows the file you should copy.

    c. 在確定已選取 Microsoft.IdentityServer.dll 核取方塊之後,按一下 [參考管理員] 視窗上的 [確定]

    Screenshot that shows the Microsoft dot Identity Server dot d l l checkbox.

  6. 所有類別和參考現在都已就緒可以執行建置。 不過,由於此專案的輸出是 dll,因此必須先將其安裝到 AD FS 伺服器的全域組件快取或 GAC 中,而且 dll 必須先簽署。 以下步驟可以達到此目的:

    a. 在專案名稱 ThreatDetectionModule 上按一下滑鼠右鍵。 從功能表按一下 [屬性]

    Screenshot that highlights the Properties menu option.

    b. 從 [屬性] 頁面上,按一下左側的 [簽署],然後核取標示為 [簽署組件] 的核取方塊。 從 [選擇強式名稱金鑰檔:] 下拉式功能表中,選取 [<新增…>]

    Screenshot that shows the Sign the assembly checkbox.

    c. 在 [建立強式名稱金鑰] 對話方塊中,輸入金鑰的名稱 (您可以選擇任何名稱),取消核取 [使用密碼保護我的金鑰檔案] 核取方塊。 然後按一下 [確定]

    Screenshot that shows Protect my key file with password checkbox.

    d. 儲存專案,如下所示:

    Screenshot that shows where to save your project.

  7. 按一下 [建置] 建置專案,然後按一下 [重建解決方案],如下所示:

    Screenshot that shows the Rebuild Solution menu option.

    檢查畫面底部的輸出視窗,以查看是否發生任何錯誤。

    Screenshot that shows the output from the rebuilt solution.

外掛程式 (dll) 現已就緒可供使用,並且在專案資料夾的 \bin\Debug 資料夾中 (在我的案例中是 C:\extensions\ThreatDetectionModule\bin\Debug\ThreatDetectionModule.dll)。

下一個步驟是向 AD FS 註冊此 dll,使其按照 AD FS 驗證程序執行。

向 AD FS 註冊外掛程式 dll

我們需要使用 AD FS 伺服器上的 Register-AdfsThreatDetectionModule PowerShell 命令,在 AD FS 中註冊 dll。 不過,在我們註冊之前,我們需要取得公開金鑰權杖。 當我們建立金鑰並使用該金鑰簽署 dll 時,會建立此公開金鑰權杖。 若要了解 dll 的公開金鑰權杖為何,您可以使用 SN.exe,如下所示:

  1. 將 dll 檔案從 \bin\Debug 資料夾複製到另一個位置 (在我的案例中,將其複製到 C:\extensions)。

  2. 啟動 Visual Studio 的開發人員命令提示字元,並移至包含 sn.exe 的目錄 (在我的案例中,目錄是 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools)。

    Screenshot that shows the Developer Command Prompt for Visual Studio.

  3. 使用 -T 參數和檔案的位置,執行 SN 命令 (在我的案例中為 SN -T "C:\extensions\ThreatDetectionModule.dll")。

    Screenshot that shows how to run the S N command.

    此命令會為您提供公開金鑰權杖 (對我來說,公開金鑰權杖是 714697626ef96b35)

  4. 將 dll 新增至 AD FS 伺服器的全域組件快取,我們的最佳做法是您為專案建立適當的安裝程式,並使用安裝程式將檔案新增至 GAC。 另一個解決方案是在您的開發電腦上使用 Gacutil.exe (Gacutil.exe 的詳細資訊可於此處取得)。 由於我的 Visual Studio 位於與 AD FS 相同的伺服器上,所以我會使用 Gacutil.exe,如下所示:

    a. 在 Visual Studio 的「開發人員命令提示字元」上,移至包含 Gacutil.exe 的目錄 (在我的案例中,目錄是 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools)。

    b. 執行 Gacutil 命令 (在我的案例中為 Gacutil /IF C:\extensions\ThreatDetectionModule.dll):

    Screenshot that shows how to run the Gacutil command.

    注意

    如果您有 AD FS 伺服器陣列,則必須在伺服器陣列中的每部 AD FS 伺服器上執行上述步驟。

  5. 開啟 Windows PowerShell 並且執行下列命令以註冊 dll:

    Register-AdfsThreatDetectionModule -Name "<Add a name>" -TypeName "<class name that implements interface>, <dll name>, Version=10.0.0.0, Culture=neutral, PublicKeyToken=< Add the Public Key Token from Step 2. above>" -ConfigurationFilePath "<path of the .csv file>"
    

    在我的案例中,命令為:

    Register-AdfsThreatDetectionModule -Name "IPBlockPlugin" -TypeName "ThreatDetectionModule.UserRiskAnalyzer, ThreatDetectionModule, Version=10.0.0.0, Culture=neutral, PublicKeyToken=714697626ef96b35" -ConfigurationFilePath "C:\extensions\authconfigdb.csv"
    

    注意

    即使您有 AD FS 伺服器陣列,您只需要註冊 dll 一次。

  6. 註冊 dll 之後,重新啟動 AD FS 服務。

就是這樣,dll 現在已向 AD FS 註冊並可供使用!

注意

如果對外掛程式進行任何變更並重建專案,則必須再次註冊更新的 dll。 註冊之前,您必須使用下列命令取消註冊目前的 dll:

UnRegister-AdfsThreatDetectionModule -Name "<name used while registering the dll in 5. above>"



在我的案例中,命令為:

UnRegister-AdfsThreatDetectionModule -Name "IPBlockPlugin"

測試外掛程式

  1. 開啟我們稍早建立的 authconfig.csv 檔案 (在我的案例中是位於 C:\extensions),並且新增您想要封鎖的外部網路 IP。 每個 IP 都應該位於個別行上,且結尾應該沒有空格。

    Screenshot that shows how to add the extranet I P lines.

  2. 儲存並關閉檔案。

  3. 執行下列 PowerShell 命令,在 AD FS 中匯入更新的檔案:

    Import-AdfsThreatDetectionModuleConfiguration -name "<name given while registering the dll>" -ConfigurationFilePath "<path of the .csv file>"
    

    在我的案例中,命令為:

    Import-AdfsThreatDetectionModuleConfiguration -name "IPBlockPlugin" -ConfigurationFilePath "C:\extensions\authconfigdb.csv")
    
  4. 使用您在 authconfig.csv 中新增的相同 IP,從伺服器起始驗證要求。

    在此示範中,我將會使用 AD FS 說明宣告 X 光工具來起始要求。 如果您想要使用 X 光工具,請遵循指示

    輸入同盟伺服器執行個體,然後按 [測試驗證] 按鈕。

    Screenshot that shows the Test Authentication button.

  5. 驗證遭到封鎖,如下所示。

    Screenshot that shows that authentication is blocked.

既然我們已經知道如何建置和註冊外掛程式,讓我們逐步解說外掛程式程式碼,了解使用模型引進的新介面和類別進行實作。

外掛程式程式碼的逐步解說

使用 Visual Studio 開啟專案 ThreatDetectionModule.sln,然後從畫面右側的 [方案總管] 開啟主要檔案 UserRiskAnalyzer.cs

model

檔案包含主要類別 UserRiskAnalyzer,其會實作抽象類別 ThreatDetectionModule 和介面 IRequestReceivedThreatDetectionModule,以從要求內容讀取 IP、比較取得的 IP 與從 AD FS DB 載入的 IP,並在 IP 相符時封鎖要求。 讓我們更詳細地探討這些類型

ThreatDetectionModule 抽象類別

這個抽象類別會將外掛程式載入 AD FS 管線,使其能夠按照 AD FS 程序執行外掛程式程式碼。

public abstract class ThreatDetectionModule
{
    protected ThreatDetectionModule();

    public abstract string VendorName { get; }
    public abstract string ModuleIdentifier { get; }

    public abstract void OnAuthenticationPipelineLoad(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
    public abstract void OnAuthenticationPipelineUnload(ThreatDetectionLogger logger);
    public abstract void OnConfigurationUpdate(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
}

類別包含下列方法和屬性:

方法 類型 定義
OnAuthenticationPipelineLoad Void 當外掛程式載入至其管線時,由 AD FS 呼叫
OnAuthenticationPipelineUnload Void 當外掛程式從其管線中卸載時,由 AD FS 呼叫
OnConfigurationUpdate Void 設定更新時由 AD FS 呼叫
屬性 型別 [定義]
VendorName String 取得擁有外掛程式的廠商名稱
ModuleIdentifier String 取得外掛程式的識別碼

在我們的範例外掛程式中,我們會使用 OnAuthenticationPipelineLoadOnConfigurationUpdate 方法,從 AD FS DB 讀取預先定義的 IP。 向 AD FS 註冊外掛程式時,會呼叫 OnAuthenticationPipelineLoad,而在使用 Import-AdfsThreatDetectionModuleConfiguration Cmdlet 匯入 .csv 時,會呼叫 OnConfigurationUpdate

IRequestReceivedThreatDetectionModule 介面

介面可讓您在 AD FS 收到驗證要求時,但是在使用者輸入認證之前,實作風險評估,也就是在驗證程序的「已接收要求」階段。

public interface IRequestReceivedThreatDetectionModule
{
    Task<ThrottleStatus> EvaluateRequest (
    ThreatDetectionLogger logger,
    RequestContext requestContext );
}

介面包含 EvaluateRequest 方法,可讓您使用在 requestCoNtext 輸入參數中傳遞的驗證要求內容來撰寫風險評估邏輯。 requestContext 參數的類型是 RequestContext

傳遞的另一個輸入參數是記錄器,其類型為 ThreatDetectionLogger。 參數可用來將錯誤、稽核和/或偵錯訊息寫入 AD FS 記錄。

方法會將 ThrottleStatus (如果 NotEvaluated 則為 0、1 為「封鎖」,2 為「允許」) 傳回 AD FS,接著封鎖或允許要求。

在我們的範例外掛程式中,EvaluateRequest 方法實作會從 requestCoNtext 參數剖析 clientIpAddress,並將其與從 AD FS DB 載入的所有 IP 進行比較。 如果找到相符項目,方法會傳回 2 以封鎖,否則會傳回 1 以允許。 根據傳回的值,AD FS 會封鎖或允許要求。

注意

上述範例外掛程式只會實作 IRequestReceivedThreatDetectionModule 介面。 不過,風險評估模型會提供兩個額外的介面 –IPreAuthenticationThreatDetectionModule (在預先驗證階段實作風險評估邏輯) 和 IPostAuthenticationThreatDetectionModule (在驗證後階段實作風險評估邏輯)。 以下提供這兩個介面的詳細資料。

IPreAuthenticationThreatDetectionModule 介面

介面可讓您在使用者提供認證時,但是在 AD FS 評估認證之前實作風險評估邏輯,也就是預先驗證階段。

public interface IPreAuthenticationThreatDetectionModule
{
    Task<ThrottleStatus> EvaluatePreAuthentication (
    ThreatDetectionLogger logger,
    RequestContext requestContext,
    SecurityContext securityContext,
    ProtocolContext protocolContext,
    IList<Claim> additionalClams
  );
}

介面包含 EvaluatePreAuthentication 方法,可讓您使用在 RequestContext requestContextSecurityContext securityContextProtocolContext protocolContextIList<Claim> additionalClams 輸入參數中傳遞的資訊,撰寫您的預先驗證風險評估邏輯。

注意

如需與每個內容類型一起傳遞的屬性清單,請造訪 RequestContextSecurityContextProtocolContext 類別定義。

傳遞的另一個輸入參數是記錄器,其類型為 ThreatDetectionLogger。 參數可用來將錯誤、稽核和/或偵錯訊息寫入 AD FS 記錄。

方法會將 ThrottleStatus (如果 NotEvaluated 則為 0、1 為「封鎖」,2 為「允許」) 傳回 AD FS,接著封鎖或允許要求。

IPostAuthenticationThreatDetectionModule 介面

介面可讓您在使用者提供認證且 AD FS 已執行驗證之後實作風險評估邏輯,也就是驗證後階段。

public interface IPostAuthenticationThreatDetectionModule
{
    Task<RiskScore> EvaluatePostAuthentication (
    ThreatDetectionLogger logger,
    RequestContext requestContext,
    SecurityContext securityContext,
    ProtocolContext protocolContext,
    AuthenticationResult authenticationResult,
    IList<Claim> additionalClams
  );
}

介面包含 EvaluatePostAuthentication 方法,可讓您使用在 RequestContext requestContextSecurityContext securityContextProtocolContext protocolContextIList<Claim> additionalClams 輸入參數中傳遞的資訊,撰寫您的驗證後風險評估邏輯。

注意

如需與每個內容類型一起傳遞的完整屬性清單,請參閱 RequestContextSecurityContextProtocolContext 類別定義。

傳遞的另一個輸入參數是記錄器,其類型為 ThreatDetectionLogger。 參數可用來將錯誤、稽核和/或偵錯訊息寫入 AD FS 記錄。

方法會傳回可在 AD FS 原則和宣告規則中使用的風險分數

注意

若要讓外掛程式能夠運作,主要類別 (在此案例中為 UserRiskAnalyzer) 必須衍生 ThreatDetectionModule 抽象類別,而且應該至少實作上述三個介面的其中一個。 註冊 dll 之後,AD FS 會檢查管線中適當階段實作哪些介面並加以呼叫。

常見問題集

為何應該建置這些外掛程式?
答:這些外掛程式不僅提供額外的功能,保護您的環境免於遭受密碼噴灑攻擊之類的攻擊,還能讓您根據需求彈性建置自己的風險評估邏輯。

擷取記錄的位置?
答:您可以使用 WriteAdminLogErrorMessage 方法將錯誤記錄寫入「AD FS/Admin」事件記錄檔、使用 WriteAuditMessage 方法將稽核記錄寫入「AD FS Auditing」安全性記錄檔,以及使用 WriteDebugMessage 方法將偵錯記錄寫入「AD FS Tracing」偵錯記錄。

新增這些外掛程式會增加 AD FS 驗證程序延遲嗎?
答:延遲影響將取決於您實作的風險評估邏輯執行所花費的時間。 建議您先評估延遲影響,再於實際執行環境中部署外掛程式。

為什麼 AD FS 無法建議風險性 IP、使用者等項目的清單?
答:雖然目前無法使用,但是我們正努力在插入式風險評估模型中建置情報來建議風險性 IP、使用者等。 我們很快就會分享上市日期。

有哪些其他範例外掛程式可供使用?
答:下列範例外掛程式可用:

名稱 描述
風險性使用者外掛程式 範例外掛程式,會根據 Microsoft Entra ID Protection 決定的使用者風險層級來封鎖驗證或強制執行 MFA。