2011-01-26 78 views
4

我有一個WCF服務,託管在IIS中。在服務上,我有大約20種服務方法。我想用這些用戶名/密碼來保護其中的一些方法。我無法控制調用該服務的客戶端,因此我無法在客戶端上安裝證書。我們的服務充當平臺,持有所有用戶資料信息,包括登錄信息。沒有客戶端證書的WCF消息/方法安全

我認爲,我想客戶端驗證一次到身份驗證(用戶名,密碼)方法對WCF服務,獲得授權令牌回來,並傳遞令牌的後續調用。 (有些像Asp.net會員提供者使用表單認證會話)。如果可能的話,我不希望客戶端必須爲每個方法調用傳遞用戶名/密碼。這是正確的模式嗎?有沒有更好的方式使這個功能使用標準的WCF功能?有沒有人有任何示例配置/代碼來顯示正確的方式來實現它的工作?

回答

4

WCF不按操作驗證提供開箱即用。如果您需要安全和不安全的操作,最簡單的方法是將它們分成兩個服務合同,並將每個安全設置公開。

您授權令牌的想法是在WCF已實施,但在你的情況下,你必須使用的wsHttpBinding,用戶名客戶端憑據,SecurityContext的服務證書。

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="securedService"> 
      <serviceCredentials> 
      <serviceCertificate x509FindType="FindBySubjectName" findValue="ServerCert" 
           storeLocation="LocalMachine" storeName="My"/> 
      </serviceCredentials> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="Secured"> 
      <security mode="Message"> 
      <message clientCredentialType="UserName" establishSecurityContext="true" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service name="MessageSecurity.Service" behaviorConfiguration="securedService"> 
     <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Secured" 
        contract="MessageSecurity.IService"> 
     </endpoint> 
     </service> 
    </services> 
    </system.serviceModel> 

SecurityContext是基於WS-SecureConversation的可互操作功能。它只需要在來自服務代理實例的第一次調用中傳遞用戶名和密碼(在WCF中,這是完全透明的 - 客戶端代理實例維護安全上下文)。以下呼叫僅使用首次呼叫期間發出的安全令牌。 SecurityContext在wsHttpBinding中默認打開。

這種結構也將進行加密和簽名的消息 - 這是全功率的WS-Security。任何其他方法都取決於你。你必須自己完全實現它。

您提到您無法控制客戶端。這並不意味着你不能使用證書。如果您使用證書,則客戶有責任在他們想要致電您的服務時獲得該證書。它與控制客戶關於證書的信任無關 - 對於公共Web服務,它意味着從可信任的證書頒發機構購買證書。

此外,可以在不安裝服務證書的情況下獲得服務證書。第一種可能性是使用證書作爲端點身份。在這種情況下,編碼的證書是WSDL的一部分:

<wsdl:service name="Service"> 
    <wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService"> 
    <soap12:address location="http://localhost:1432/Service.svc" /> 
    <wsa10:EndpointReference> 
     <wsa10:Address>http://localhost:1432/Service.svc</wsa10:Address> 
     <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"> 
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <X509Data> 
      <X509Certificate>MIICmzCCAYegAwI....<X509Certificate> 
      </X509Data> 
     </KeyInfo> 
     </Identity> 
    </wsa10:EndpointReference> 
    </wsdl:port> 
</wsdl:service> 

如果指定與配置服務證書的wsHttpBinding終點,你不設置其身份這是自動完成的。這種方法的缺點是證書到期。如果更改過期證書,則必須更新所有客戶端。

第二種可能性是使服務憑據談判:

<bindings> 
    <wsHttpBinding> 
    <binding name="Secured"> 
     <security mode="Message"> 
     <message clientCredentialType="UserName" negotiateServiceCredential="true"/> 
     </security> 
    </binding> 
    </wsHttpBinding> 
</bindings> 

協商默認情況下開啓。它使用TLSNego協議在安全通信開始之前交換服務憑證(證書)。這種方法的缺點是TLSNego不被所有平臺支持。

+1

我可以用`netTCPBinding`來做到這一點嗎? – Sreekumar 2012-06-29 06:23:35

1

FYI:如果你想使用內置的WCF自定義用戶名/密碼子系統,WCF 4.0中引入的一個Allow Insecure Transport property。這允許您在沒有證書等的情況下使用WCF安全子系統......這在您認爲即使WCF認爲消息仍然安全的情況下也很有用(例如,在設備級別完成SSL而不是一個網絡服務器級別,或者當使用IP過濾時)。

相關問題