2011-11-27 83 views
3

我是新來的WCF和我做的,我需要有一些用戶/密碼模式,以保持每個客戶端的一些自定義設置和日誌誰訪問服務的服務器/客戶端應用程序,但通過網絡的流量中的「安全」並不是真的需要,因爲信息不敏感。 所以考慮到這一點,我正在尋找一個簡單的方法來完成這個,但我找不到它。WCF自定義安全過netTcp

我有幾個制約因素和條件:

  • Windows的安全性是不是一種選擇。
  • 我使用ClickOnce部署,所以一切都應該被包含在安裝包內 。我不知道正在下載的用戶的實際列表 ,所以我沒有辦法將一些 證書分發給所有用戶。
  • 此外,客戶端會在局域網內,並通過幾個 廣域網來accesed。已經得到滿足的另一個要求是服務應該 有很好的表現,因爲大量的數據與每個 響應流,所以問題是:

消息是否安全出了名的疼的表現?

「手工」的方式是通過用戶名作爲每個方法我露出一個參數,但它似乎是一個非常骯髒的解決方案。

在我看來,很多約束條件來設計這個,所以這就是爲什麼我問這個問題。

這將是最簡單的解決方案來完成此?

回答

2

首先,我們必須假設所有用戶消費服務在某種程度上是「登記」使用該服務的。因爲如果它是公開的,匿名的,那麼根本就沒有跟蹤。所以我的假設如下:

  1. 服務是在Windows服務/託管的WinForms支持TCP 端點。 - 與IIS的新版本(> 6)這是不是必需的假設了
  2. 有像「用戶名/密碼」組合來驗證。這 不在活動目錄(不選擇Windows身份驗證) 但可能是xml /數據庫。
  3. 我們不願意有這樣public int Add(string User, string Password, int A, int B)

我有一個TCP端點這確實是這樣的一種服務方式。我會分享這一點。我不認爲這是最佳做法。

應用程序名稱是MYAPP

我在web.config中的

serviceCredentials > userNameAuthentication 

部分提供

customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost" 

MYAPPHost是我的Windows服務的名稱。 Authenticate是從數據庫進行身份驗證的類。

message clientCredentialType="UserName"設置爲TCPBinding。

我的Windows服務的App.Config中:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
      switchValue="Off" propagateActivity="true" > 
     <listeners> 
      <add name="SERVICE_MONITOR" type="System.Diagnostics.XmlWriterTraceListener" 
       initializeData="MYAPP_MONITOR.svclog" /> 
     </listeners> 
     </source>  
     <source name="MYAPP_TRACE" switchValue="All" > 
     <listeners> 
      <add name="MYAPP_TRACE_LISTENER" type="System.Diagnostics.XmlWriterTraceListener"           
       initializeData="MYAPP_TRACE.svclog" /> 
     </listeners> 
     </source> 
    </sources> 
    <trace autoflush="true" /> 
    </system.diagnostics> 

    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="OverAllServiceBehavior"> 
      <serviceSecurityAudit 
      auditLogLocation="Application" 
      serviceAuthorizationAuditLevel="Failure" 
      messageAuthenticationAuditLevel="Failure" 
      suppressAuditFailure="true" />   
      <serviceDebug includeExceptionDetailInFaults="True" /> 
      <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" /> 
      <serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000">  
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
      <serviceCredentials> 
      <userNameAuthentication 
       userNamePasswordValidationMode="Custom" 
       customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost"/> 
      </serviceCredentials>   
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="OverAllEndPointBehavior" /> 
     </endpointBehaviors> 
    </behaviors>   
    <bindings> 
     <netTcpBinding> 
     <binding name="ServiceTCPEndPointBinding" maxBufferSize="2147483647">  
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
maxNameTableCharCount="2147483647" /> 
      <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" /> 
      <message clientCredentialType="UserName" algorithmSuite="TripleDes"/> 
      </security> 
     </binding> 
     </netTcpBinding> 
    </bindings>   
    <services> 
     <service behaviorConfiguration="OverAllServiceBehavior" 
       name="MiddleWare.ServiceClasses.ServiceClass">  
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://127.0.0.1:15010/ServiceTCPEndPointMEX"/>    
      </baseAddresses> 
     </host>  
     <endpoint address="net.tcp://127.0.0.1:15020/ServiceTCPEndPoint" contract="MiddleWare.ServiceContracts.IServiceContract" />   
     <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />  
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

身份驗證類別:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IdentityModel.Selectors; 

namespace MYAPPHost 
{ 
    public class Authenticate : UserNamePasswordValidator 
    { 
     public override void Validate(string UserName, string Password) 
     { 
      if (!CheckFromDB(UserName,Password)) 
       throw new Exception("UNAUTHORIZED ACCESS!!!"); 
     } 
    } 
} 

在客戶端,將參照WCF(SR)

SR.ServiceContractClient obj = new SR.ServiceContractClient("ServiceTCPEndPoint"); 
obj.ClientCredentials.UserName.UserName = "User1"; 
obj.ClientCredentials.UserName.Password = "Password1"; 
int I = obj.Add(1, 2); 

如果後不提供憑據,則會引發消息安全令牌錯誤。對於錯誤憑據UNAUTHORIZED ACCESS發生。