作法:建立 WSFederationHttpBinding

在 Windows Communication Foundation (WCF) 中,WSFederationHttpBinding 類別 (位於組態中的 <wsFederationHttpBinding>) 會提供一個機制來公開同盟服務。 也就是,要求用戶端使用由安全性權杖服務發出的安全性權杖進行驗證的一種服務。 這個主題會表示如何在程式碼和組態中設定 WSFederationHttpBinding。 一旦建立了繫結,就可以設定端點以使用該繫結。

以下將粗略說明基本步驟:

  1. 選取安全性模式。 WSFederationHttpBinding 支援 Message,而這會在訊息層級中提供端對端安全性 (甚至於在多重躍點中);也支援 TransportWithMessageCredential,而這會在用戶端和服務可直接透過 HTTPS 連線的狀況下提供較好的效能。

    注意

    WSFederationHttpBinding 也支援 None 做為安全性模式。 這個模式並不安全,主要目的僅用於偵錯。 若使用其安全性模式設定為 NoneWSFederationHttpBinding 來部署服務端點,則產生的用戶端繫結 (由 ServiceModel 中繼資料公用程式工具 (Svcutil.exe) 產生) 會是安全性模式為 NoneWSHttpBinding

    和其他系統提供的繫結程序不一樣,在您使用 WSFederationHttpBinding 時不需要選取用戶端認證類型。 這是因為用戶端認證類型一律為已發行的權杖。 WCF 會從指定的簽發者取得權杖,並對服務呈現該權杖以驗證用戶端。

  2. 在聯合用戶端上,請將 IssuerAddress 屬性設定為安全性權杖服務的 URL。 將 IssuerBinding 設定為繫結,以用來與安全性權杖服務進行通訊。

  3. 選擇性。 將 IssuedTokenType 屬性設定成權杖型別統一資源識別元 (URI)。 在聯合服務上,指定服務預期的權杖型別。 在聯合用戶端上,指定用戶端從安全性權杖服務中所要求的權杖型別。

    如果沒有指定權杖型別,用戶端會產生不具權杖型別 URI 的 WS-Trust 要求安全性權杖 (Request Security Token,RST),而根據預設,服務會預期使用安全性判斷提示標記語言 (Security Assertions Markup Language,SAML) 1.1 權杖來進行用戶端驗證。

    SAML 1.1 權杖的 URI 為 http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1

  4. 選擇性。 在聯合服務上,請將 IssuerMetadataAddress 屬性設定為安全性權杖服務的中繼資料 URL。 中繼資料端點可讓服務的用戶端選取適當的繫結/端點組 (如果已將服務設定為發行中繼資料)。 如需發佈中繼資料的詳細資訊,請參閱發佈中繼資料

您也可以設定其他屬性,包括在發行的權杖中當做證明金鑰使用的金鑰類型、在用戶端和服務之間使用的演算法套件、是否交涉或明確指定服務認證、服務預期發行的權杖要包含的任何特定宣告,以及必須新增至要求 (這些是用戶端傳送至安全性權杖服務的要求) 的其他 XML 項目。

注意

只有當 NegotiateServiceCredential 設定為 SecurityModeMessage 屬性才有關聯。 如果 SecurityMode 設定為 TransportWithMessageCredential,則會忽略 NegotiateServiceCredential 屬性。

在程式碼中設定 WSFederationHttpBinding

  1. 建立 WSFederationHttpBinding的執行個體。

  2. 依需求將 Mode 屬性設定為 WSFederationHttpSecurityModeMessage。 若需要 Basic256 以外的演算法套件,請將 AlgorithmSuite 屬性設定為從 SecurityAlgorithmSuite 中取得的值。

  3. 適當地設定 NegotiateServiceCredential 屬性。

  4. IssuedKeyType 屬性設定為 SecurityKeyTypeSymmetricKey。必要時設定為 AsymmetricKey

  5. IssuedTokenType 屬性設定為適當值。 若未設定任何值,則 WCF 預設為 http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1,表示 SAML 1.1 權杖。

  6. 如果未指定本機簽發者,則在用戶端上為必要項;在服務上則為選擇項。 建立其中包含安全性權杖服務之位址和身分識別資訊的 EndpointAddress,並將 EndpointAddress 執行個體指派給 IssuerAddress 屬性。

  7. 如果未指定本機簽發者,則在用戶端上為必要項;在服務上則不要使用。 為 SecurityTokenService 建立 Binding,並將 Binding 執行個體指派給 IssuerBinding 屬性。

  8. 在用戶端上不要使用,在服務上則為選擇項。 對安全性權杖服務的中繼資料建立 EndpointAddress 執行個體,並將它指派給 IssuerMetadataAddress 屬性。

  9. 在用戶端和服務上都是選擇項。 建立一或多個 ClaimTypeRequirement 執行個體,並將這些執行個體新增至 ClaimTypeRequirements 屬性所傳回的集合。

  10. 在用戶端和服務上都是選擇項。 建立一或多個 XmlElement 執行個體,並將這些執行個體新增至 TokenRequestParameters 屬性所傳回的集合。

在組態中建立聯合端點

  1. <wsFederationHttpBinding> 建立為應用程式組態檔中 <bindings> 元素的子系。

  2. <binding> 元素建立為 <wsFederationHttpBinding> 的子系,並將 name 屬性設定為適當的值。

  3. <security> 元素建立為 <binding> 元素的子系。

  4. 依照需求,將 mode 項目上的 <security> 屬性設定為 MessageTransportWithMessageCredential 的值。

  5. 建立 <message> 項目做為 <security> 項目的子項。

  6. 選擇性。 以適當的值設定 algorithmSuite 項目上的 <message> 屬性。 預設值為 Basic256

  7. 選擇性。 如果需要非對稱證明金鑰,請將 issuedKeyType 項目的 <message> 屬性設定為 AsymmetricKey。 預設值為 SymmetricKey

  8. 選擇性。 設定 issuedTokenType 項目上的 <message> 屬性。

  9. 如果未指定本機簽發者,則在用戶端上為必要項;在服務上則為選擇項。 建立 <issuer> 項目以做為 <message> 項目的子項。

  10. address 屬性設定為 <issuer> 項目,並指定安全性權杖服務會接受權杖要求的位址。

  11. 選擇性。 加入 <identity> 子項目,並指定安全性權杖服務的識別。

  12. 如需詳細資訊,請參閱服務識別與驗證

  13. 如果未指定本機簽發者,則在用戶端上為必要項;在服務上則不要使用。 在繫結區段中建立 <binding> 元素,而您可以使用此繫結區段與安全性權杖服務進行通訊。 如需建立繫結的詳細資訊,請參閱操作說明:指定組態中的服務繫結

  14. 藉由設定 binding 項目的 bindingConfiguration<issuer> 屬性,指定在前面的步驟中所建立的繫結。

  15. 在用戶端上不要使用,在服務上則為選擇項。 建立 <issuerMetadata> 項目以做為 <message> 項目的子項。 接著,在 address 項目的 <issuerMetadata> 屬性上,指定安全性權杖服務要發行其中繼資料的位址。 您也可以選擇性地新增 <identity> 子項目,並指定安全性權杖服務的身分識別。

  16. 在用戶端和服務上都是選擇項。 新增 <claimTypeRequirements> 項目以做為 <message> 項目的子項。 藉由將 <add> 元素新增至 <claimTypeRequirements> 元素,並以 claimType 屬性指定宣告類型,以指定服務所需要的必要宣告與選擇性宣告。 透過設定 isOptional 屬性,指定提供的宣告為必要項或選擇項。

範例

下列程式碼範例會顯示以命令方式設定 WSFederationHttpBinding 的程式碼。

// This method creates a WSFederationHttpBinding.
public static WSFederationHttpBinding
    CreateWSFederationHttpBinding(bool isClient)
{
  // Create an instance of the WSFederationHttpBinding.
  WSFederationHttpBinding b = new WSFederationHttpBinding();

  // Set the security mode to Message.
  b.Security.Mode = WSFederationHttpSecurityMode.Message;

  // Set the Algorithm Suite to Basic256Rsa15.
  b.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256Rsa15;

  // Set NegotiateServiceCredential to true.
  b.Security.Message.NegotiateServiceCredential = true;

  // Set IssuedKeyType to Symmetric.
  b.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;

  // Set IssuedTokenType to SAML 1.1
  b.Security.Message.IssuedTokenType =
      "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#samlv1.1";
    
  // Extract the STS certificate from the certificate store.
  X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
  store.Open(OpenFlags.ReadOnly);
  X509Certificate2Collection certs = store.Certificates.Find(
      X509FindType.FindByThumbprint, "0000000000000000000000000000000000000000", false);
  store.Close();

  // Create an EndpointIdentity from the STS certificate.
  EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity ( certs[0] );

  // Set the IssuerAddress using the address of the STS and the previously created
  // EndpointIdentity.
  b.Security.Message.IssuerAddress =
      new EndpointAddress(new Uri("http://localhost:8000/sts/x509"), identity);

  // Set the IssuerBinding to a WSHttpBinding loaded from configuration.
  // The IssuerBinding is only used on federated clients.
  if (isClient)
  {
      b.Security.Message.IssuerBinding = new WSHttpBinding("Issuer");
  }

  // Set the IssuerMetadataAddress using the metadata address of the STS and the
  // previously created EndpointIdentity. The IssuerMetadataAddress is only used
  // on federated services.
  else
  {
      b.Security.Message.IssuerMetadataAddress =
          new EndpointAddress(new Uri("http://localhost:8001/sts/mex"), identity);
  }
  // Create a ClaimTypeRequirement.
  ClaimTypeRequirement ctr = new ClaimTypeRequirement
      ("http://example.org/claim/c1", false);

  // Add the ClaimTypeRequirement to ClaimTypeRequirements
  b.Security.Message.ClaimTypeRequirements.Add(ctr);

  // Return the created binding
  return b;
}
' This method creates a WSFederationHttpBinding.
Public Shared Function CreateWSFederationHttpBinding(ByVal isClient As Boolean) As WSFederationHttpBinding
    ' Create an instance of the WSFederationHttpBinding.
    Dim b As New WSFederationHttpBinding()
    With b.Security
        ' Set the security mode to Message.
        .Mode = WSFederationHttpSecurityMode.Message

        With .Message
            ' Set the Algorithm Suite to Basic256Rsa15.
            .AlgorithmSuite = SecurityAlgorithmSuite.Basic256Rsa15

            ' Set NegotiateServiceCredential to true.
            .NegotiateServiceCredential = True

            ' Set IssuedKeyType to Symmetric.
            .IssuedKeyType = SecurityKeyType.SymmetricKey

            ' Set IssuedTokenType to SAML 1.1
            .IssuedTokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#samlv1.1"
        End With
    End With

    ' Extract the STS certificate from the certificate store.
    Dim store As New X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser)
    store.Open(OpenFlags.ReadOnly)
    Dim certs = store.Certificates.Find(X509FindType.FindByThumbprint, _
                                        "0000000000000000000000000000000000000000", _
                                        False)
    store.Close()

    ' Create an EndpointIdentity from the STS certificate.
    Dim identity = EndpointIdentity.CreateX509CertificateIdentity(certs(0))

    ' Set the IssuerAddress using the address of the STS and the previously created 
    ' EndpointIdentity.
    With b.Security.Message
        .IssuerAddress = New EndpointAddress(New Uri("http://localhost:8000/sts/x509"), _
                                                                           identity)

        ' Set the IssuerBinding to a WSHttpBinding loaded from configuration. 
        ' The IssuerBinding is only used on federated clients.
        If isClient Then
            .IssuerBinding = New WSHttpBinding("Issuer")

            ' Set the IssuerMetadataAddress using the metadata address of the STS and the
            ' previously created EndpointIdentity. The IssuerMetadataAddress is only used 
            ' on federated services.
        Else
            .IssuerMetadataAddress = New EndpointAddress(New Uri("http://localhost:8001/sts/mex"), _
                                                                           identity)
        End If
        ' Create a ClaimTypeRequirement.
        Dim ctr As New ClaimTypeRequirement("http://example.org/claim/c1", _
                                            False)

        ' Add the ClaimTypeRequirement to ClaimTypeRequirements
        .ClaimTypeRequirements.Add(ctr)
    End With

    ' Return the created binding
    Return b
End Function

另請參閱