2013-08-28 37 views
0

我已經創建的服務與這樣的綁定配置:WCF WS-Security服務器

<bindings> 
    <customBinding> 
    <binding name="DefaultBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpTransport /> 
    </binding> 
    </customBinding> 
</bindings> 

而當我的服務接收消息開始是這樣的:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
    <Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <UsernameToken> 
     <Username> 
     </Username> 
     <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">...</Password> 
     <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">KWVa4abCrEemOMT55VEZkgIAAAAAAA==</Nonce> 
     <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-08-28T13:29:05.966Z</Created> 
     </UsernameToken> 
    </Security> 
    ... 

它產生錯誤:

的名字空間'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'的標題'安全'未被理解...

我也試過:

<wsHttpBinding> 
    <binding name="DefaultBinding"> 
     <security mode="Message" /> 
    </binding> 
</wsHttpBinding> 

我如何處理這個頭或忽略它?


更新

我的理解,我需要在不安全的傳輸用戶名,所以我嘗試:

<customBinding> 
    <binding 
     name="DefaultBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <security authenticationMode="UserNameOverTransport" allowInsecureTransport="True"> 
     </security> 
     <httpTransport> 

     </httpTransport> 
    </binding> 
</customBinding> 

我也試過CUB

<bindings> 
    <clearUsernameBinding> 
    <binding name="myClearUsernameBinding" messageVersion="Soap12"> 
    </binding> 
    </clearUsernameBinding> 
</bindings> 

兩個錯誤結束在客戶端上:驗證消息安全性時發生錯誤。但它適用於測試CUB的客戶端。什麼可能是錯的?

CUB的信封的header。測試客戶端header

回答

1

解決方案很簡單:

  1. 創建服務行爲
  2. 創建調度消息檢查
  3. 添加創建的服務行爲,服務器

然後就是分析或直接刪除未使用「的mustUnderstand」頭。

第1步:

public class WSSecurityBehavior : IServiceBehavior { 
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, 
     Collection<ServiceEndpoint> endpoints, 
     BindingParameterCollection bindingParameters) { 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 
     var endpoints = serviceHostBase 
      .ChannelDispatchers 
      .Cast<ChannelDispatcher>() 
      .SelectMany(dispatcher => dispatcher.Endpoints); 

     foreach (var endpoint in endpoints) 
      endpoint.DispatchRuntime.MessageInspectors.Add(new WSSecurityInspector()); 
    } 
} 

第2步:

public class WSSecurityInspector : IDispatchMessageInspector { 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { 
     var headerPosition = request.Headers.FindHeader("Security", 
      "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 

     if (headerPosition > -1) 
      request.Headers.RemoveAt(headerPosition); 

     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) { 
    } 
} 

第3步:

Host.Description.Behaviors.Add(new WSSecurityBehavior()); 
0

您在客戶端和主機之間交換的soap結構/合同中存在不匹配。客戶端與主機(包括名稱空間)之間交換的消息結構必須完全匹配。如果他們不這樣做,你會得到這個錯誤。

你想要做的是讓主持人在你的主機上運行Fiddler。然後,將Fiddler作爲中間人代理運行,重新發送來自客戶機器的請求。當請求/響應完成時,檢查Fiddler中的消息,特別是請求和響應之間的命名空間和結構差異,那裏你應該找到問題。

0

客戶端正嘗試使用用戶/通過消息級別向您的服務器進行身份驗證。您需要確定這是否是預期的行爲,在這種情況下,您需要配置您的服務以進行用戶名認證。這不僅僅是設置綁定的問題,您需要決定如何對用戶進行身份驗證(例如,通過數據庫,Windows憑據等)。一旦你知道,你應該能夠使用這樣的結合:

 <customBinding> 
      <binding name="NewBinding0"> 
       <textMessageEncoding /> 
       <security authenticationMode="UserNameOverTransport"> 
        <secureConversationBootstrap /> 
       </security> 
       <httpsTransport /> 
      </binding> 
     </customBinding> 

我不能肯定這是你所需要的,因爲你沒有發佈完整的SOAP信封。您可能需要在文本編碼元素上設置messageVersion屬性,或者在沒有SSL的情況下使用CUB。 然後你需要配置你將如何驗證用戶名。一個示例is here

+0

是的,這是對的Valide客戶端發送用戶名後/越過HTTP不使用SSL。此時服務應該接受它而不檢查。我試過CUB,它與測試客戶端一起工作,但是與現有客戶端失敗:{「驗證郵件安全性時發生錯誤。」} 我比較了evelope的標頭: CUB包含以下元素: 時間戳,過期,UsernameToken,用戶名,密碼 礦有: 用戶名,密碼,現時,創建 – therg

+0

請發佈工作和fialing消息的樣本 –

+0

現在我看到你發佈它。您應該打開服務器上的wcf trace來查看確切的錯誤。 http://blogs.msdn.com/b/madhuponduru/archive/2006/05/18/601458.aspx –

0

可以使用basicHttpBinding的,從這個帖子下載project and sample code密碼消化WCF PasswordDigest Auth這是我的配置這個實現(我編輯了一些代碼的習慣米需要,但這種解決方案工作正常)。

新建綁定:

<bindings> 
    <basicHttpBinding> 
    <binding name="securityBinding"> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

,並設置一個行爲

<behavior name="securityBehavior"> 
     <DataMessageTracer/>  
     <serviceCredentials type="WCF.SecurityExtensions.ServiceCredentialsEx, WCF.SecurityExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
     <serviceCertificate findValue="hypori2.zed.pa" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/> 
     <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyService.Utils.PassValidator, MyService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </serviceCredentials> 
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
    </behavior> 
    </serviceBehaviors>