11

我有一个正在编码的 WCF 应用程序。我在更改内容时启动和停止它几次,然后再次运行服务调用。

因为我需要会话信息,所以我正在使用wsHttpBinding.

在我搬到之前,wsHttpBinding我正在使用basicHttpBinding,我可以停止服务,进行更改并重新启动它。然后我可以针对端点运行我的 WCF 测试客户端(WCF Storm),它仍然可以正常运行。

现在它告诉我:

无法处理该消息。这很可能是因为操作“ http://tempuri.org/IMyService/MyOperation ”不正确,或者因为消息包含无效或过期的安全上下文令牌,或者因为绑定之间不匹配。如果服务由于不活动而中止通道,则安全上下文令牌将无效。为了防止服务过早中止空闲会话,请增加服务端点绑定的接收超时。

这意味着我必须刷新我的连接并重新设置我的服务调用(数百次后会变得很烦人。)。

我读到安全超时是 10 分钟。我在不到 2 分钟的时间内重新运行,所以我认为这不是超时问题。

我的猜测是令牌过期的明显原因是我已经杀死并重新启动了服务。

问题是我根本不需要安全的东西(我只需要会话的东西,否则我会使用 BasicHttpBinding

反正有没有让我的 WCF 服务不关心安全上下文令牌?

注意:我的测试客户端默认为 wsHttpBinding 并设置了安全性。但我假设它正在设置它,因为我的服务正在发布它需要安全性。

我尝试过的事情:

  • 我尝试了类似于我在这里找到的配置

    <bindings>
        <wsHttpBinding>
            <binding name="WsEventLogBinding">
                <security mode="Message">
                    <message establishSecurityContext="false" />
                </security>
             </binding>
        </wsHttpBinding>
    </bindings>
    

但我真的不知道这意味着什么,或者它是否是我需要的(这根本不安全(目前))。

这并没有消除问题。

  • 设置<security mode="None"> 这没有帮助。
4

4 回答 4

12

首先,您是对的:由于 HTTP 协议的无连接/无状态特性,basicHttpBinding 不支持此功能。

但我认为您对 WCF 的理解有问题。

Session 是 WCF 中的一个通用概念。它可以是基于安全的会话,其中通信的两端都已就特定的安全会话达成一致,也可以是一个可实现的会话,其中消息可以配置为按顺序且仅一次传递,即使消息跨越多个传输,也能确保接收到消息对话期间的节点。

这两种模式都允许您选择 InstanceContextMode.PerSession。这真的是你想要的吗?

WCF 安全依赖于相互身份验证;如果双方都信任对方的凭证(基于声明),那么可以建立一个安全上下文,在该上下文中所有消息都以保密方式进行交换,并且所有消息都经过签名以保护其完整性。安全会话是唯一的,您不能在另一个会话中重复使用它。

这是您的上下文的问题:问题不在Server Side 而是在Client Side。因为必须在客户端和服务上保留某些内容,所以重建服务将刷新服务上的整个 WCF 上下文(所有实例和会话都将被释放)。没有与 WCF 会话关联的通用数据存储(与 asp. net session),因此重新启动将丢弃所有内容。但是,由于其“无效”上下文,客户端仍然认为已通过身份验证。

为了解决这个问题,在默认的 Wcf 测试客户端上有一个用于此场景的复选框:“启动新代理”。在 WCf Storm 上,Under the hood/Miscellaneous “总是创建新代理”中有一个通用配置。

注意:在生产环境中,您永远不会遇到这种情况,因为您的服务将始终处于启动状态。

如果您关注我,您可能想尝试可靠的 Session。你可以测试,但我不确定这会奏效。

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>

重要提示:我不知道您的 WCF 级别,但在 WCF 中,客户端和服务必须具有同步配置(相同的安全性、会话设置......)

于 2013-05-21T19:52:57.800 回答
4

wsHttpBinding默认启用安全性。尝试在绑定配置上使用它来禁用安全性:

<security mode="None">
   <transport clientCredentialType="None" />
    <message establishSecurityContext="false" />
</security>

此外,您的错误与 wsHttpBinding 相关。如果您使用会话并重新启动服务器,则会出现报告的安全错误消息

根据MSDN

可靠会话实现 WS-ReliableMessaging 协议和内存中传输窗口以屏蔽 SOAP 消息级故障并在传输失败的情况下重新建立连接。

可靠会话位于发送方和接收方 SOAP 端点之间,无论它们之间的连接需要多少传输连接。简而言之,TCP 可靠性在传输连接结束的地方结束,而可靠会话提供端到端的可靠性。

听起来像预期的行为。

于 2013-05-21T19:48:22.793 回答
0

您可以使用基本的http绑定TransportCredentialOnly security mode

于 2013-05-21T17:55:18.847 回答
0

安全模式 None 应该做的工作。

<bindings>
    <wsHttpBinding>
        <binding name="WsEventLogBinding">
            <security mode="None" />
         </binding>
    </wsHttpBinding>
</bindings>

不要忘记bindingConfiguration="WsEventLogBinding"在您的端点上应用。

于 2013-05-21T19:13:01.567 回答