3

我有一个通过 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 服务更改为返回时间戳。

4

2 回答 2

5

尽管我意识到您已经将 Mark_S 的答案标记为正确,但您可能会发现以下解决了您的问题。

您的错误消息已在Microsoft 修补程序 KB971493中得到解决: .NET Framework 3.5 SP1 提供了一个使 WCF 能够发送安全消息和接收不安全响应以及发送不安全消息和接收安全响应的修补程序。

Windows Communication Foundation (WCF) 没有发送安全消息然后接收不安全响应或发送不安全消息并接收安全响应的功能。本文中描述的修复程序添加了一个新的 enableUnsecuredResponse 属性。

我很想知道这是否能解决您的问题。

于 2010-06-23T11:32:23.857 回答
3

至于您的具体问题,请查看 Stackoverflow 和其他地方的一些类似问题:

链接到有用的教程和非常详细地解释 WCF 的屏幕截图:有MSDN WCF 开发人员中心,其中包含从初学者教程到文章和示例代码的所有内容。

另外,我建议您看一下WCF 上的 Pluralsight 屏幕投射- 这是一个出色的系列,从“创建您的第一个 WCF 服务”和“创建您的第一个 WCF 客户端”一直到相当高级的主题。Aaron Skonnard 在 10-15 分钟的截屏视频中很好地解释了所有内容 - 强烈推荐!

于 2010-03-03T06:03:58.027 回答