2011-11-07 53 views
7

我负责创建将由外部客户端使用的WCF服务。客户端正在使用WSSE安全性,特别是他们通过SOAP头传递用户名令牌。WCF客户端将mustUnderstand设置为true传递用户名令牌

WCF服务托管在启用了SSL的IIS服务器上。

在这一点上,我有一个半工作原型。我现在处理的问题是,SOAP头的mustUnderstand属性设置为1,这会导致进程失败。

我想要一些建议(或更好的代码示例微笑)如何处理用户名令牌,以便在mustUnderstand属性为true时返回正确的响应。

这里是一个的失败的SOAP请求的例子:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
     <soapenv:Header> 
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken> 
       <wsse:Username>TestUser</wsse:Username> 
       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPWD</wsse:Password> 
       <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">NzU3MjFhN2YtYTlmYS00ZWZjLTkxNjktY2ExZjlkZDEwNzE5</wsse:Nonce> 
       <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-10-26T03:04:39Z</wsu:Created> 
      </wsse:UsernameToken> 
      </wsse:Security> 
     </soapenv:Header> 
     <soapenv:Body> 
      <tem:Getstuff> 
      <tem:Arg1>Arg1</tem:Arg1> 
      <tem:Arg2>Arg2</tem:Arg2> 
      </tem:Getstuff> 
     </soapenv:Body> 
    </soapenv:Envelope> 

如果soapenv:mustUnderstand属性= “1” 改变为soapenv:mustUnderstand属性= “0”,则该过程的工作原理。


PS:这里的一个修订后的样品请求客户机发送:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
     <s:Header> 
     <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/WService/Getstuff</Action> 
     <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="removed" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:Username>TestUser</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPass</wsse:Password> 
      <wsse:Nonce>2Udx78sh2y2xRJYJpZZ9+w==</wsse:Nonce> 
      <wsu:Created>2011-09-26T19:12:48Z</wsu:Created> 
      </wsse:UsernameToken> 
     </Security> 
     </s:Header> 
     <s:Body> 
     <Getstuff xmlns="http://tempuri.org/"> 
     <Arg1>Arg1</Arg1> 
     <Arg2>Arg2</Arg2> 
     </Getstuff> 
     </s:Body> 
    </s:Envelope> 

,收到以下响应于上述请求:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
     <s:Body> 
      <s:Fault> 
      <faultcode>s:MustUnderstand</faultcode> 
      <faultstring xml:lang="en-US">The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.</faultstring> 
      </s:Fault> 
     </s:Body> 
    </s:Envelope> 

这里的结合:

<bindings> 
    <basicHttpBinding> 
    <binding name="TransportBind" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
     maxReceivedMessageSize="2147483647"> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     <security mode="Transport"> 
     <transport clientCredentialType="None" /> 
     </security> 
    </binding> 
    <binding name="basic" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
     maxReceivedMessageSize="2147483647"> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
+0

你确定它使用WSE(Web Service Extensions)吗? –

+0

不,我不积极。我在上面的示例中添加了客户端发送的修改后的示例请求。 –

+0

究竟是什么“失败”。究竟是什么让你相信失败是由'mustUnderstand'造成的? –

回答

0

+1 @JohnSaunder因为他很可能在这里吠叫正确的树。

是你的客户端.NET/WCF吗?如果没有,它可能不会实现WS-Security,或者至少不是WCF想要的方式。

如果客户端是.NET,这只是客户端上不匹配的绑定。

mustUnderstand标志表示必须确认并处理WS-Security标头。一个非WS-Security客户端,不管是因为它没有说WS-Security还是没有配置为WS-Security,都会忽略头,试图使用这个消息并且服务器会抛出。

您的其他选择是在服务器上拒绝拒绝。它将停止发送WS-Security标题。当然,那么你不会得到否认。

+0

我很确定它是一个Java客户端,但我不知道是哪一种。 –

2

您的约束是basicHttpBinding。您需要使用wsHttpBinding

0

我通过在WCF配置中不使用生成的WS-Security头(当您添加服务引用时)解决了此问题,而是将其注释掉,而是让.NET使用Client Credentials生成头本身并指定“TransportWithMessageCredential”的安全模式:

client.ClientCredentials.UserName.UserName = "UserName"; 
client.ClientCredentials.UserName.Password = "Password"; 

<basicHttpBinding> 
    <binding name="Binding"> 
     <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 
</basicHttpBinding> 

(我们正在使用SSL,所以此安全设置)。

注释掉生成的头:

<client> 
     <endpoint ...> 
      <!--<headers> 
       <wsse:Security...> 
       </wsse:Security> 
      </headers>--> 
     </endpoint> 
</client> 

不幸的是我不知道够不够WCF捕获原始SOAP请求/响应比较差,看看为什么ClientCredentials不会导致“无法理解“错误,而生成的标题。

另外,according to the MSDN文档中,如果您只使用“传输”,它将不知道使用WS-Security:“将此属性保留为默认值,即System.ServiceModel.SecurityMode.Transport不使用WS-Security的“。

相关问题