確保用戶端的安全
在 Windows Communication Foundation (WCF) 中,服務會規定用戶端的安全性需求。 也就是說,服務會指定使用哪一個安全性模式,以及用戶端是否必須提供認證。 因此,保護用戶端安全的程序便十分簡單,只要使用從服務 (如果已發行) 取得的中繼資料並建立用戶端即可。 中繼資料指定如何設定用戶端。 如果服務要求用戶端提供認證,則您必須取得符合要求的認證。 本主題將進一步探討此程序。 如需建立安全服務的詳細資訊,請參閱保護服務。
指定安全性的服務
根據預設值,WCF 繫結已啟用安全性功能。 (例外狀況是 BasicHttpBinding。)因此,如果服務是以 WCF 建立,則服務較有可能實作安全性以確保驗證、機密性和完整性。 在該情況下,服務提供的中繼資料將指示它需要什麼來建立安全的通訊通道。 如果服務中繼資料沒有任何安全性需要,那麼就沒有方法強制服務採用安全性配置 (例如透過 HTTP 的 Secure Sockets Layer (SSL))。 如果服務要求用戶端提供認證,則用戶端開發人員、部署人員或管理員必須提供用戶端用來向服務驗證的實際認證。
取得中繼資料
建立用戶端時,第一個步驟是取得與用戶端通訊的服務中繼資料。 有兩種方法可以達到這個目的: 首先,如果服務發佈中繼資料交換 (MEX) 端點,或透過 HTTP 或 HTTPS 提供其中繼資料,您可以使用服務模式中繼資料公用程式工具 (Svcutil.exe) 下載中繼資料,如此會為用戶端產生程式碼檔案以及組態檔。 (如需使用此工具的詳細資訊,請參閱使用 WCF 用戶端存取服務。)如果服務未發行 MEX 端點,而且也沒有透過 HTTP 或 HTTPS 提供它的中繼資料,您必須向服務建立者要求描述安全性需求與中繼資料的文件。
重要
建議使用來自受信任來源且不可竄改的中繼資料。 使用 HTTP 通訊協定擷取的中繼資料會以純文字傳送出去且可以竄改。 如果服務使用 HttpsGetEnabled 和 HttpsGetUrl 屬性,請以服務建立者提供的 URL 來使用 HTTPS 通訊協定下載資料。
驗證安全性
中繼來源可以區分成兩大類別:信任來源與不受信任的來源。 如果您信任來源,而且已從該來源的安全 MEX 端點下載用戶端程式碼和其他中繼資料,那麼您可以建立用戶端,提供用戶端正確的認證,並且毫無後顧之憂地執行它。
如果您選擇從您對它幾乎一無所知的來源下載用戶端和中繼資料,請務必驗證程式碼使用的安全性措施。 例如,您不可以只建立傳送您的個人資料或財務資料到服務的用戶端,除非該服務僅要求機密性和完整性。 您對服務擁有者的信任程度,應可到達您願意公開這類資訊的程度,因為服務擁有者將會看到這些資訊。
因此,通常在使用來自不受信任來源的程式碼和中繼資料時,請檢查程式碼和中繼資料,以確保其符合您要求的安全性等級。
設定用戶端認證
在用戶端上設定用戶端認證是由兩個步驟所組成:
判斷服務所需的「用戶端認證類型」。 這可以由兩個方法的其中之一完成。 首先,如果您有來自服務建立者的文件,文件中應指出服務需要的用戶端認證類型 (如果有的話)。 再者,如果您只有 Svcutil.exe 工具產生的組態檔,您可以檢查個別的繫結來判斷需要哪一種認證類型。
指定實際的用戶端認證。 實際的用戶端認證稱為「用戶端認證值」,以區別它與類型之不同。 例如,如果用戶端認證類型指定憑證,您必須提供由服務信任的憑證授權單位核發的 X.509 憑證。
判斷用戶端認證類型
如果您有 Svcutil.exe 工具所產生的組態檔,請查看<bindings> 區段,來判斷所需的用戶端認證類型。 在該部分內有指定安全性需要的繫結項目。 請特別查看每個繫結的 <security> 元素。 該項目包括 mode
屬性,您可以將該屬性設定為三個可能值 (Message
、Transport
或 TransportWithMessageCredential
) 的其中之一。 屬性的值決定模式,而模式決定哪一個子項目是重要的。
<security>
元素可包含 <transport>
或 <message>
元素,或同時包含這兩個元素。 重要的項目就是符合安全性模式的項目。 例如,下列程式碼指定安全性模式為 "Message"
,而且 <message>
項目的用戶端認證類型是 "Certificate"
。 在這個情況中,可以忽略 <transport>
項目。 但 <message>
項目指定必須提供 X.509 憑證。
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator">
<security mode="Message">
<transport clientCredentialType="Windows"
realm="" />
<message clientCredentialType="Certificate"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
請注意,如果 clientCredentialType
屬性已設定為 "Windows"
,如下列範例所示,您不需要提供實際的認證值。 這是因為 Windows 整合式安全性已提供執行用戶端之人員的實際認證 (Kerberos 權杖)。
<security mode="Message">
<transport clientCredentialType="Windows "
realm="" />
</security>
設定用戶端認證值
如果用戶端必須提供認證,請使用適當方法設定用戶端。 例如,使用 SetCertificate 方法設定用戶端憑證。
常見的認證形式是 X.509 憑證。 您可以用兩種方式提供認證:
- 以程式設計方式將它編寫在您的用戶端程式碼中 (使用
SetCertificate
方法)。
為用戶端組態檔新增 <behaviors> 區段,並使用 clientCredentials
元素 (如下所示)。
在程式碼中設定 <clientCredentials> 值
若要在程式碼中設定 <clientCredentials> 值,您必須存取 ClientBase<TChannel> 類別的 ClientCredentials 屬性。 該屬性傳回允許存取各種認證類型的 ClientCredentials 物件,如下表所示。
ClientCredential 屬性 | 描述 | 附註 |
---|---|---|
ClientCertificate | 傳回 X509CertificateInitiatorClientCredential | 代表用戶端向服務進行驗證時提供的 X.509 憑證。 |
HttpDigest | 傳回 HttpDigestClientCredential | 代表 HTTP 摘要式認證。 此認證是使用者名稱與密碼的雜湊。 |
IssuedToken | 傳回 IssuedTokenClientCredential | 代表安全性權杖服務核發的自訂安全性權杖,常使用於聯合案例中。 |
Peer | 傳回 PeerCredential | 代表用在 Windows 網域上參與對等網狀結構的對等認證。 |
ServiceCertificate | 傳回 X509CertificateRecipientClientCredential | 代表超出範圍交涉中的服務所提供的 X.509 憑證。 |
UserName | 傳回 UserNamePasswordClientCredential | 代表使用者名稱和密碼組。 |
Windows | 傳回 WindowsClientCredential | 代表 Windows 用戶端認證 (Kerberos 認證)。 類別的屬性是唯讀屬性。 |
在組態中設定 <clientCredentials> 值
使用作為 <clientCredentials> 元素子項目的端點行為,可以指定認證值。 使用的項目視用戶端認證類型而定。 例如,下列範例顯示組態如何使用 <<clientCertificate>,設定 X.509 憑證。
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="myEndpointBehavior">
<clientCredentials>
<clientCertificate findvalue="myMachineName"
storeLocation="Current" X509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
若要在組態中設定用戶端認證,請將 <endpointBehaviors> 元素新增到組態檔中。 此外,新增的行為元素必須連結到服務端點,方法是使用 <client> 之 <endpoint> 元素的 behaviorConfiguration
屬性,如下列範例所示。 behaviorConfiguration
屬性的值必須與 name
屬性的值相符。
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost/servicemodelsamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="myEndpointBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</client>
</system.serviceModel>
</configuration>
注意
使用應用程式組態檔無法設定某些用戶端認證值,例如使用者名稱和密碼,或者 Windows 使用者和密碼值。 這類認證值只能在程式碼中指定。
如需設定用戶端認證的詳細資訊,請參閱操作說明:指定用戶端認證值。
注意
ClientCredentialType
當 設定為 "TransportWithMessageCredential"
時SecurityMode
,會忽略 ,如下列範例組態所示。
<wsHttpBinding>
<binding name="PingBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"
establishSecurityContext="false"
negotiateServiceCredential="false" />
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>