Eri*_* J. 3 wcf ws-security soap
我有一个应用程序通过https连接到实现WS-Security的基于SOAP的Web服务.Web服务是用Java编写的,需要纯文本密码以及正确设置的时间戳.
经过大量的谷歌搜索和实验,我无法弄清楚如何配置我的WCF客户端与此服务进行交互.除了正确答案之外,我还要感谢指向WCF和SOAP的教程的链接.
我当前客户端的app.config如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="MyServiceSoapBinding" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                  <security mode="TransportWithMessageCredential">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                  </security>
                  <!--security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                  </security-->
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://p1.my.com/tx/services/MyService"
                binding="basicHttpBinding" bindingConfiguration="MyServiceSoapBinding"
                contract="My.IMyService" name="MyServiceEndpointPort" />
        </client>
    </system.serviceModel>
</configuration>
并且客户端代码如下所示:
string response;
try
{
    MyService.MyServiceClient svc = new WcfExample.MyService.MyServiceClient();
    svc.ClientCredentials.UserName.UserName = "myUser";
    svc.ClientCredentials.UserName.Password = "myPass";
    response = svc.ping();
    lblPingResponse.Text = response;
}
catch (System.ServiceModel.Security.MessageSecurityException mse)
{
    lblPingResponse.Text = "MessageSecurityException: " + mse.Message;
}
catch (Exception ex)
{
    lblPingResponse.Text = "Exception: " + ex.Message;
}
此代码抛出此异常:
MessageSecurityException"安全处理器无法在消息中找到安全标头.这可能是因为消息是不安全的故障,或者因为通信方之间存在绑定不匹配.如果为安全性和客户端配置了服务,则会发生这种情况.没有使用安全性."
WSE 3版本只需要以下工作:
ServiceUsernameTokenManager.AddUser(userName, password);
UsernameToken token = new UsernameToken(userName, password,
                PasswordOption.SendPlainText);
proxy = new _MyServiceWse();
Policy policy = new Policy();
policy.Assertions.Add(new UsernameOverTransportAssertion());
policy.Assertions.Add(new RequireActionHeaderAssertion());
proxy.SetPolicy(policy);
proxy.SetClientCredential(token);
更新:
请求现在到达服务器,并在app.config中使用此配置从服务器发回响应:
<security mode="TransportWithMessageCredential">
  <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
  <message clientCredentialType="UserName" algorithmSuite="Default" />
</security> 
然后客户端抛出异常
"安全处理器无法在消息中找到安全标头.这可能是因为消息是不安全的故障,或者因为通信方之间存在绑定不匹配.如果服务配置为安全性而客户端是没有使用安全性."
这似乎是因为客户端发送Timestamp标头,但该服务不返回Timestamp标头.这可能是"正确的事情",但它并不是非常有用,因为那里部署了许多期望时间戳但不返回时间戳的Web服务.
如果有办法说服客户接受这种情况,我很想知道.与此同时,我将研究是否可以更改Web服务以返回时间戳.
虽然我意识到您已经将Mark_S的答案标记为正确,但您可能会发现以下内容可以解决您的问题.
您的错误消息在Microsoft Hotfix KB971493中得到解决:.NET Framework 3.5 SP1提供了一个修补程序,该修补程序使WCF能够发送安全的消息并接收不安全的响应,并发送不安全的消息并接收安全的响应.
Windows Communication Foundation(WCF)不具有发送安全消息然后接收不安全响应,或发送不安全消息并接收安全响应的功能.本文中介绍的修补程序添加了一个新的enableUnsecuredResponse属性.
我很想知道这是否能解决您的问题.
| 归档时间: | 
 | 
| 查看次数: | 10471 次 | 
| 最近记录: |