【发布时间】:2010-03-03 01:04:46
【问题描述】:
我有一个通过 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 服务更改为返回时间戳。
【问题讨论】:
标签: wcf soap ws-security