【问题标题】:WCF configuration for SOAP plain text password authentication over SSL通过 SSL 进行 SOAP 纯文本密码身份验证的 WCF 配置
【发布时间】: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


    【解决方案1】:

    虽然我知道您已经将 Mark_S 的答案标记为正确,但您可能会发现以下解决了您的问题。

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

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

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

    【讨论】:

    • 所有人都认为这正是我所追求的。我想知道如何将 BasicHttpBinding 用作 CustomHttpBinding 但将 enableUnsecuredResponse 设置为 true?由于 BasicHttpBinding 中没有 enableUnsecuredResponse 开关。
    • @Junto:谢谢,这是一个更好的答案,所以我接受了。不幸的是,我不再能够验证该问题,但它似乎确实直接解决了我最初的问题,并且其他人似乎得到了帮助。
    【解决方案2】:

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

    非常详细地解释 WCF 的有用教程和屏幕截图的链接:MSDN WCF Developer Center 包含从初学者教程到文章和示例代码的所有内容。

    另外,我建议您看看Pluralsight screen casts on WCF - 这是一个从“Creating your first WCF service”和“Creating your first WCF client”一直到相当高级主题的优秀系列。 Aaron Skonnard 在 10-15 分钟的截屏视频中很好地解释了所有内容 - 强烈推荐!

    【讨论】:

    • @marc_s:感谢您的回复。但是,SO 问题似乎暗示您必须手动定制 SOAP 标头。这真的是唯一的解决方案吗? Wordpress 链接讨论了配置服务器,而不是客户端。 Plurlasight 视频需要订阅/付款,并且似乎涵盖了一般 WCF,而不是据我所知的具体问题。
    • @Eric J:Pluralsight 截屏视频绝对不需要任何订阅——这些都是完全免费的,值得您花时间!至于 SOAP 标头 - 如果您需要发送自定义 SOAP 标头,您可以使用定义消息的标头和正文元素的消息契约,或者您必须创建一些逻辑来将这些 SOAP 标头注入到消息中
    • 看起来其中一些在一段时间内是免费的“我们提供限时访客通行证,让您可以访问 Pluralsight On-Demand! 库中每个模块的一些剪辑。”我去看看。我还用其他发现更新了这个问题。非常感谢您的帮助!
    • @Eric J:嗯,好吧,是的,有屏幕投射(免费),但当然,Pluralsight 也有他们的 WCF On-Demand 库,这是收费的 - 他们可能会提供一些位作为预告片:-) 但是仅截屏视频就已经非常有用了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2018-09-03
    • 2012-02-10
    • 2012-09-13
    • 1970-01-01
    相关资源
    最近更新 更多