ACS 安全性指導方針

更新日期:2015 年 6 月 19 日

適用對象:Azure

套用至

  • Microsoft Azure Active Directory 存取控制服務 (也稱為「存取控制服務」或 ACS)

  • Windows Identity Foundation (WIF)

總結

本主題合併 ACS 的安全性指導方針。 請使用這些指導方針,從安全角度出發來改善實作的品質。 您可以使用這些指導方針來檢閱應用程式的架構、檢閱程式碼和記錄安全性錯誤,以及檢閱生產部署。 這些指導方針會參考有關如何完成特定工作的規範步驟,以及概念性主題,以深入瞭解 ACS 的特定功能或功能的詳細資訊。

目標

  • 解決與 ACS 內容中應用程式程式碼和設定相關的安全性問題。

  • 解決與 ACS 設定相關的安全性問題。

  • 解決 ACS 內容中與 Azure 部署相關的安全性問題。

下列是與應用程式程式碼和設定相關的安全性指導方針。

  • 請考慮將重新執行偵測功能 (DetectReplayedTokens) 設為 True。

  • wsFederationrequireHttps 屬性設為 True。

  • cookieHandlerrequireSsl 屬性設為 True。

  • sessionTokenRequirement 的 lifetime 屬性設定積極值。

  • issuerNameRegistry 中列出信任的安全性權杖服務 (STS) (權杖簽發者)。

  • 您的應用程式必須使用 audienceUri 接受的範圍權杖。

考慮將重新執行偵測功能 (DetectReplayedTokens) 設為 True

WIF 具有專為安全性權杖服務 (STS) 擁有者權杖設計的重新執行偵測快取,它只是先前使用之 STS 權杖的快取。 當用戶端第一次使用安全性權杖服務 (STS) 權杖驗證信賴憑證者時,它會接收到工作階段安全性權杖,後者可用來驗證其他要求的信賴憑證者。 它會透過安全通訊端層 (SSL) 執行這項工作,避免工作階段安全性權杖遭竊。 如果用戶端或攻擊者嘗試使用用戶端已用過的安全性權杖服務 (STS) 權杖來驗證信賴憑證者,信賴憑證者便可在重新執行快取中查詢 STS 權杖並拒絕要求。

此快取不保證權杖絕不會重新執行。 它會根據快取的大小、安全性權杖服務 (STS) 權杖的到期時間,以及信賴憑證者接收之唯一驗證要求的比率來執行最佳偵測。 我們強烈建議您為信賴憑證者設定快取大小和安全性權杖服務 (STS) 權杖到期時間,以便在效能與安全性之間取得適當的平衡。

範例:

<securityTokenHandlers>
  <securityTokenHandlerConfiguration>
    <tokenReplayDetection enabled="true" capacity="1000" expirationPeriod="500"/>
  </securityTokenHandlerConfiguration>
</securityTokenHandlers>

注意

使用此功能將引進伺服器親和性,可能會在負載平衡環境 (包含 Azure) 中導致延展性問題。 為了解決此問題,您可以考慮使用基本抽象類別 Microsoft.IdentityModel.Tokens.TokenReplayCache,然後在設定檔案中參照該類別 (類似於下列程式碼),以實作您自己的權杖重新執行偵測。

<system.identityModel>
  <identityConfiguration>
    <tokenReplayDetection>
      <replayCache type='FQTN of your type' />
    </tokenReplayDetection>
  </identityConfiguration>
</system.identityModel>

將 wsFederation 的 requireHttps 屬性設為 True

requireHttps 屬性可控制模組是否只會重新導向安全性權杖服務 (STS) 的安全 URL。 預設值為 "true"。 這能確保透過乾淨的 HTTPS/SSL 流量來與安全性權杖服務 (STS) 進行安全通訊,減緩透過線路探查認證和權杖的機率。

範例:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

將 cookieHandler 的 requireSsl 屬性設為 True

此值是布林值;預設值為 False。 requireSsl 屬性控制是否為任何撰寫的 Cookie 發出 "Secure" 旗標。 若設定此值,只能透過 HTTPS 使用登入工作階段 Cookie。 這能防止透過乾淨的流量來傳送工作階段 Cookie,減輕透過線路探查權杖的威脅。

範例:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

為 sessionTokenRequirement 的 lifetime 屬性設定積極值

請考慮以積極的存留期限制來簽發權杖。 這將限制攻擊者在偷竊權杖後能重新執行權杖的時間範圍。

範例:

<add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel">
  <sessionTokenRequirement securityTokenCacheType="Microsoft.IdentityModel.MruSecurityTokenCache, Microsoft.IdentityModel"
                           saveBootstrapTokens="true"
                           securityTokenCacheSize="500"
                           useWindowsTokenService="false"
                           lifetime="10:00" />
</add>

在 issuerNameRegistry 中列出信任的 STS (權杖簽發者)

所有簽發者權杖都會使用 IssuerNameRegistry 予以驗證。 IssuerNameRegistry 的目的是將簽發者權杖對應至字串名稱。 若驗證失敗,則不會接受權杖。 這能減緩接受不信任權杖的威脅。 任何自訂類型都可以使用 issuerNameRegistry > 專案的type屬性 < 來註冊。 <issuerNameRegistry 可以有一個子項目,做為 IssuerNameRegistry > 的自訂群組態。 提供一個全新的 IssuerNameRegistry 類型 (ConfigurationBasedIssuerNameRegistry),可在設定中設定一組信任的簽發者憑證。 此類型需要已設定受信任簽發者憑證的子組態專案 < trustedIssuers > 。 <trustedIssuers > 組態會使用憑證指紋的 ASN.1 編碼形式新增受信任的憑證。

範例:

<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel">
  <trustedIssuers>
    <add thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" name="contoso.com" />
    <remove thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" />
    <clear/>
  </trustedIssuers>
</issuerNameRegistry>

僅使用 audienceUri 之應用程式的範圍權杖

<audienceUris > 會指定可接受的 URI 集合,以識別此信賴憑證者。 除非權杖屬於其中一個允許的 Audience URI,否則不接受這些權杖。 這能減緩重新執行已針對其他信賴憑證者簽發之有效權杖的威脅。 依預設,不會將 URI 新增至集合。 SAML 1.1 和 SAML 2.0 權杖類型的 SecurityTokenHandler 將使用此集合中的值,在 SamlSecurityTokenRequirement 物件中設定任何允許的 Audience URI 限制。

範例:

<audienceUris>
  <clear/>
  <add value="http://www.example.com/myapp/" />
  <remove value="http://www.example.com/myapp/" />
</audienceUris>

以下是與 ACS 管理入口網站設定相關的安全性指導方針。

  • 為安全性權杖服務 (STS) 權杖設定積極的到期日

  • 使用錯誤 URL 功能時提供適當的資料驗證

  • 考慮針對高度敏感的情況加密權杖

為安全性權杖服務 (STS) 權杖設定積極的到期日

Token Lifetime 屬性可控制權杖的存留期。 當您使用 ACS 入口網站或管理服務建立或設定信賴憑證者時,就會指定它。 您可以使用權杖存留期屬性來指定 ACS 簽發給信賴憑證者應用程式的安全性權杖保持有效時間量。 根據預設,在 ACS 中,此值會設定為 10 分鐘, (600 秒) 。 在 ACS 中,此值必須大於零,但小於或等於 24 小時, (86400 秒) 。

使用錯誤 URL 功能時提供適當的資料驗證

您可以使用錯誤 URL 來指定 URL,如果登入程式期間發生錯誤,ACS 會將使用者重新導向至該 URL。 它可以是裝載于信賴憑證者應用程式的自訂頁面,例如 http://www.fabrikam.com/billing/error.aspx 。 在重新導向過程中,ACS 會將錯誤的詳細資料提供給信賴憑證者應用程式做為 JSON 編碼的 HTTP URL 參數。 您可以製作自訂錯誤頁面,以利用 JSON 編碼的錯誤資訊來呈現收到的實際錯誤訊息或顯示靜態說明文字。 如果頁面需要授權,則結果會在 ACS 嘗試存取它並傳送 JSON 編碼錯誤的情況下,是無限重新導向迴圈。 因此,必須針對匿名存取進行設定。 由於可匿名存取頁面,且該頁面可能包含回應 HTML 或將資料寫入資料庫的程式碼,因此您應該執行步驟,防止跨網站指令碼處理和 SQL 插入式攻擊。

考慮針對高度敏感的情況加密權杖

對於高度敏感的情況,請針對被動同盟考慮加密權杖。 如需加密和解密權杖的詳細資訊,請參閱 憑證和金鑰 主題。

以下是與使用 ACS 且部署至 Azure 的應用程式相關的安全性考慮。

  • 使用 RSA 加密 Cookie

使用 RSA 加密 Cookie

在 Azure 中,預設的 Cookie 加密機制 (使用資料保護應用程式發展介面 (DPAPI)) 並不適用,因為每一個執行個體都有一個不同的金鑰。 這表示某個 Web 角色執行個體所建立的 Cookie,將無法被另一個 Web 角色執行個體讀取。 這可能導致服務失敗,從而實際造成拒絕服務。 以下是使用預設 Cookie 加密機制時將出現的錯誤訊息:

[CryptographicException: Key not valid for use in specified state.
]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +577
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +80
[InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ]
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +189
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +862
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) +109
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) +356
Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +123
Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270

若要解決此問題,請使用 Cookie 加密機制,且此機制必須使用所有 Web 角色執行個體所共用的金鑰。 下列程式碼顯示如何取代預設的 SessionSecurityHandler 物件,並設定它以使用 RsaEncryptionCookieTransform 類別。

private void OnServiceConfigurationCreated(object sender, 
    ServiceConfigurationCreatedEventArgs e)
{
    List<CookieTransform> sessionTransforms =
        new List<CookieTransform>(
            new CookieTransform[] 
            {
                new DeflateCookieTransform(), 
                new RsaEncryptionCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate),
                new RsaSignatureCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate)  
            });
   SessionSecurityTokenHandler sessionHandler = 
    new
     SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());

    e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
        sessionHandler);
}

void Application_Start(object sender, EventArgs e)
{
    FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;
}

其他資源