升級驗證案例

這個案例會介紹同時具有低價值和高價值資源的應用程式或網站,以及存取這些資源的不同需求。 應用程式或網站通常一開始會用低強度驗證方法來驗證使用者,爾後當使用者嘗試存取高價值資源時,才使用高強度驗證方法來驗證使用者。

驗證方法的強度是依應用程式而有所不同,例如有些應用程式會使用密碼驗證來做為低強度驗證方法,而用智慧卡驗證來做為高強度驗證方法。 其他的應用程式可能會使用憑證驗證來做為低強度驗證方法,而用生物指紋驗證來做為高強度驗證方法。 下面列出這個案例的核心層面,無論其使用的驗證方法為何:

  • 應用程式如何向屬於 STS 的簽發者溝通必要驗證方法。

  • 服務如何處理特定驗證方法的要求。

由於 WIF 屬於標準型 (WS-*) 並且支援 WS-Federation 規格 1.2,所以它會支援這些核心層面。

在下圖介紹的常見升級驗證案例中,Fabrikam.com 員工會存取 Contoso.com 應用程式所公開的低價值和高價值資源。

5c0ed8b3-ab7f-4733-b902-5b4bfbf937b4

與這個案例有關的虛構使用者列出如下:

  • Frank:他是 Fabrikam 的員工,擔任 IT 系統管理員。他將嘗試存取 Contoso 資源。

  • Daniel:他是 Contoso 的應用程式開發人員,負責為應用程式實作必要的變更。

  • Adam:Contoso 的 IT 系統管理員。

與這個案例有關的元件列出如下:

  • web1:具有低價值 (LowValueResourcePage.aspx) 和高價值 (HighValueResourcePage.aspx) 資源的 Web 應用程式,其使用後端 Web 服務自 SQL Server 存放區中擷取資料。

  • sts1:擔任宣告提供者角色的 STS,而且會發出應用程式 (web1) 所預期的宣告。

  • sts2:擔任 Fabrikam.com 身分識別提供者角色的 STS,而且會提供兩個端點;一個是用於低強度驗證方法,一個是用於高強度驗證方法。 它已經與 Contoso.com 建立信任關係,因此允許 Fabrikam 員工存取 Contoso.com 資源。

依據上圖所示,這個案例的流程將為:

  1. Contoso 應用程式會依必要宣告進行設定,以允許 Fabrikam 使用者透過適當的驗證方法來存取受保護的低價值和高價值資源。 Daniel 已經實作這些應用程式變更。

  2. Fabrikam 的使用者 Frank 則可存取 Contoso 的應用程式頁面,而且可依預設地透過低強度驗證方法進行登入。

  3. 當 Fabrikam 使用者 Frank 嘗試存取高價值資源時,系統會要求他用升級驗證以採用高強度驗證方法。

與這個案例相關的基本步驟

請注意,這個範例案例的內容只是為了方便說明。 在生產環境中成功執行這個案例的實際步驟可能有所不同。

設定身分識別提供者 (IP)

Fabrikam.com 系統管理員 Frank 可以執行三種選項:

  1. 購買並安裝像是 Active Directory® Federation Services (AD FS) 2.0 等 STS 產品。

  2. 訂購像是 LiveID STS 等定域機組 STS 產品。

  3. 建立使用 WIF 的自訂 STS。

在這個範例案例中,我們假設 Frank 選取了第 1 個選項,並安裝 AD FS 2.0 成為 IP-STS。 為了同時支援低強度和高強度驗證方法,Frank 公開了自己 STS 上的兩個端點:\windowsauth\smartcardauth。 Frank 藉由參考 AD FS 2.0 產品文件,建立了與 Contoso.com 網域的信任關係。

設定宣告提供者

Contoso.com 系統管理員 Adam 的可用選項,就是前面針對身分識別提供者所介紹的選項。 在這個範例案例中,我們假設 Adam 選取了第 1 個選項,並安裝 AD FS 2.0 成為 RP-STS。 Adam 藉由參閱 AD FS 2.0 文件,建立了與 Fabrikam.com 和應用程式本身的信任關係。 他也會同時設定應用程式要求必須存在才可存取低價值或高價值資源的必要宣告。

應用程式的特定變更

下面變更會擴充應用程式,以便提供升級驗證支援:

識別低價值和高價值資源所要求的宣告

應用程式可以選擇要求自訂的宣告,或者由架構依預設發出的 authenticationmethod 宣告。 這個宣告的值必須是指出驗證方法強度的值。 在這個範例案例中,authenticationmethod 宣告會標記成必要的宣告。 如果這個宣告的值是 "CertorSmartcard",表示使用者已獲得低價值和高價值資源的存取權限。 另一方面如果這個宣告的值是 "windowsauth",表示使用者只獲得低價值資源的存取權限。

如需 authenticationmethod 宣告的相關資訊和不同權杖類型的可能值,請參閱宣告式身分識別模型

應用程式可以透過已在 WS-Federation 規格中定義的參數 wauth,來為宣告提供者指定必要的驗證方法。 另外,應用程式可以向宣告提供者明確表達驗證的所有層面,並且指定應用程式的特定宣告成為必要宣告 (例如,包含 "lowvalue" 和 "highvalue" 可能值的 privilegelevel 宣告)。

在這個範例案例中,wauth 參數在搭配可能的自訂值 "authstrength1" 時就是針對低價值資源,搭配 "authstrength5" 時就是針對高價值資源。

下面這段程式碼範例會示範如何使用 FederatedPassiveSignIn 控制項,來標記將傳遞給宣告提供者的驗證強度值。 請注意,AuthenticationType 參數會序列化成為網路上的 WS-Federation wauth 參數。

<wif:FederatedPassiveSignIn AuthenticationType=https://WIFSample/authstrength1 ID="FederatedPassiveSignIn1" runat="Server" Issuer="https://sts1.contoso.com/AuthPassive/Default.aspx" SignInButtonType="Link" TitleText="Click the link below to access low value resources" SignInText="Access low value resources" Realm="https://web1.contoso.com/AuthAssuranceRP/Default.aspx" OnSignInError="FederatedPassiveSignIn_SignInError" DisplayRememberMe="false" VisibleWhenSignedIn="false"> </wif:FederatedPassiveSignIn>

Contoso 宣告提供者 (sts1) 會處理 wauth 參數,並根據 Fabrikam 身分識別提供者 (sts2) 上的端點來重新導向使用者。

使用 FedUtil 工具來建立與宣告提供者的信任關係

應用程式必須建立與宣告提供者的信任關係,這樣由該宣告提供者簽發的權杖才能由應用程式進行取用。 使用 FedUtil 建立 ASP.NET 信賴憑證者應用程式與 STS 之間的信任可以用兩個步驟來完成這項工作:

  1. 登錄應用程式:FedUtil 會自 sts1 (即 RP-STS) 和應用程式下載同盟中繼資料,選取必要的宣告,然後更新應用程式的 web.config 檔案。

  2. 發佈應用程式:FedUtil 會產生應用程式的同盟中繼資料 (即 metadata.xml 檔案),並將其放入應用程式資料夾。 RP-STS 透過簡單 HTTP GET 即可存取這項資料。

如需相關資訊,請參閱 使用 FedUtil 建立 ASP.NET 信賴憑證者應用程式與 STS 之間的信任

使應用程式具備宣告感知特性並觸發升級驗證

為了應用宣告來進行升級驗證和其他與身分識別相關的工作,應用程式必須列舉來自 IClaimsPrincipal 的宣告,並檢查必要的宣告 authenticationmethod

如需如何使應用程式具備宣告感知特性的詳細步驟資訊,請參閱建立信賴憑證者應用程式的<ASP.NET>一節。

下面程式碼範例會示範高價值資源頁面會如何檢查 authenticationmethod 宣告,以及如何確定其值為 "CertOrSmartcard" 之後再授與該頁面的存取權限。 這段程式碼也會示範如何將使用者重新導向到會觸發升級驗證的高度保證登入頁面:

if ( Page.User.Identity.IsAuthenticated == true ) { if ( GetAuthStrengthClaim() != "CertOrSmartcard" ) { // 使用者是透過低度保證進行驗證。 重新導向到高度保證 // 登入頁面。 Response.Redirect( "HighAssuranceSignInPage.aspx" ); } // 否則,使用者可成功以高度保證完成驗證。 // 允許存取高價值資源。 } else { // 使用者未完成驗證。 將他重新導向至 "Default.aspx" Response.Redirect( "Default.aspx" ); }

private string GetAuthStrengthClaim() { IClaimsIdentity claimsIdentity = (IClaimsIdentity)((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0];

// 搜尋驗證宣告。 IEnumerable<Claim> claimCollection = ( from c in claimsIdentity.Claims where c.ClaimType == System.IdentityModel.Claims.ClaimTypes.Authentication select c ); if ( claimCollection.Count<Claim>() > 0 ) { return claimCollection.First<Claim>().Value; }

    return String.Empty; }

HighAssuranceSignInPage.aspx 包含具有對應簽發者端點和 AuthenticationType 參數的 FederatedPassiveSignIn 控制項:

<wif:FederatedPassiveSignIn AuthenticationType=https://WIFSample/authstrength5 ID="FederatedPassiveSignIn1" runat="Server" Issuer="https://sts2.fabrikam.com/AuthPassiveSTSCert/Login.aspx" SignInButtonType="Link" SignInButtonStyle-Height="50px" AutoSignIn="false" SignInText="High Assurance Sign-In" TitleText="Click the below sign-in to authenticate with high assurance" Realm="https://web1.contoso.com/AuthAssuranceRP/HighAssuranceSignInPage.aspx" OnSignInError="FederatedPassiveSignIn1_SignInError" VisibleWhenSignedIn="true" DisplayRememberMe="false"> <SignInButtonStyle Height="50px" /> </wif:FederatedPassiveSignIn>

成功完成升級驗證之後透明地提高到新的宣告集合

在這個案例中所要面臨的挑戰之處,就是當成功完成升級驗證時要透明地附加使用者的提高宣告。

使用者會用一開始的驗證方法 ("windowsauth") 進行登入,並簽發宣告集合 (以下將稱為 ClaimsCollectionA)。 當使用者嘗試存取高價值資源時,您要將使用者重新導向到適當頁面以進行升級驗證,如前段內容所示。 成功完成再次驗證之後,就可簽發新的宣告集合 (以下將稱為 ClaimsCollectionB)。 這個新集合必須以使用者的身分識別重新整理,這樣當應用程式檢查高價值保證時,必要宣告才會存在。

WSFederationAuthenticationModule 處理這個工作的方式,就是重新整理這個包含最新收取之最新宣告的工作階段安全性權杖。 這表示當使用者一開始透過 Windows 驗證進行登入時,WSFAM 會簽發包含適當宣告的工作階段安全性權杖;當使用者對憑證執行升級驗證時,WSFAM 會發現使用者已完成驗證,而且新權杖已經簽發,所以,它會重新整理包含新宣告集合的該工作階段安全性權杖。

當收到新的驗證之後,WSFAM 將依預設地寫出只包含新宣告的新 Cookie。 如果 RP 應用程式另外希望在最初一組的宣告上附加第二組宣告,它就必須處理來自登入頁面之控制項的 SessionSecurityTokenCreated 事件。 這時使用者已經用舊宣告完成驗證 (使用 Thread.CurrentPrincipal),但是應用程式同時可以存取事件引數中的新宣告,所以在設定新的 Thread.CurrentPrincipal 之前,它都可以合併任何想要的宣告。 所設定的任何宣告都會保留在新 Cookie 中。

範例資源

WIF 隨附有範例的完整清單。 若要了解 WIF 支援升級驗證案例的方式,請參閱範例 End-to-end\Authentication Assurance。 請注意,這個範例是設計成搭配兩個自訂 IP-STS 和一個 RP 以運作於單一系統上。