.net 调试重启后运行时“无效或过期的安全上下文令牌”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16575799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:15:13  来源:igfitidea点击:

"Invalid or expired security context token" when running after a debugging restart

.netwcfwshttpbinding

提问by Vaccano

I have a WCF App that I am coding. I start and stop it several times as I change things and then run the service call again.

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

Since I need session info I am using wsHttpBinding.

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

Before I moved to wsHttpBindingI was using basicHttpBindingand I could stop the service, make changes and re-start it. Then I could run my WCF test client (WCF Storm) against the endpoint and it would still run fine.

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

Now it tells me:

现在它告诉我:

The message could not be processed. This is most likely because the action 'http://tempuri.org/IMyService/MyOperation' is incorrect or because the message contains an invalid or expired security context tokenor because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.

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

This means I have to refresh my connection and re-setup my service call (which gets annoying after several hundred times.).

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

I read that the security timeout is 10 minutes. I am re-running in less that 2 minutes, so I don't think it is a time out issue.

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

My guess is that the token expires for the obvious reason that I have killed and restarted the service.

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

The thing is that I don't need the security stuff at all(I only need the session stuff or I would be using BasicHttpBinding

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

Is there anyway to make my WCF Service not care about Security Context Tokens?

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

Note:My test client defaults to wsHttpBinding and has security set. But I assume that it is setting this because my service is publishing that it needs security.

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

Things I have tried:

我尝试过的事情:

  • I have tried a configuration similar to what I found Here

    <bindings>
        <wsHttpBinding>
            <binding name="WsEventLogBinding">
                <security mode="Message">
                    <message establishSecurityContext="false" />
                </security>
             </binding>
        </wsHttpBinding>
    </bindings>
    
  • 我尝试了类似于我在这里找到的配置

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

But I don't really know what this means or if it is what I need (which is no security at all (for now)).

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

This did not remove the issue.

这并没有消除这个问题。

  • Setting <security mode="None">This did not help.
  • 设置<security mode="None">这没有帮助。

回答by Cybermaxs

At first, you're true : basicHttpBinding does not support this due to the connectionless /stateless nature of the HTTP protocol.

起初,您是对的:由于 HTTP 协议的无连接/无状态特性,basicHttpBinding 不支持这一点。

But I think there is something wrong in your WCF understanding.

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

Session is a generic concept in WCF. It can be security-based session, in which both ends of communication have agreed upon a specific secure conversation or a realiable sessionin which messages can be configured to be delivered in order and exactly once, ensuring messages are received even when messages travel across multiple nodes during the conversation.

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

Both modes allow you to select InstanceContextMode.PerSession. Is this really what do you want ?

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

WCF security relies on mutual authentication ; If both parties trust the other's credentials (based upon claims), then a secure context can be established in which all messages are exchanged in confidentiality, and all messages are signed to protect their integrity. The security session is uniqueand you can't reuse it in another conversation.

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

Here is the problem with your context: the problem is not on Server Sidebut on Client Side. Because something have to be kept on client and on service, rebuilding the service will flush the whole WCF context on the service (all instances & sessions will be disposed) .There is no general data store associated with WCF sessions (one difference with asp.net session), so a restart will drop everything. However, the client still believe to be authenticated because of its "invalid" context.

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

To solve this, there is a checkbox for this scenario on the default Wcf Test Client: "Start a new proxy". On WCf Storm, there is a general config in Under the hood/Miscellaneous "always create new proxy".

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

Note : On production, you will never have this scenario because your service will always be up.

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

If you follow me you may want to try reliable Session. You can test but I'm not sure this will work.

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

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

Important Note: I don't know your WCF level, but in WCF, Clients and Services must have synchronized configurations (same security, session settings, ...)

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

回答by lstern

wsHttpBinding has security enabled by default. Try using this on your binding configuration to disable security:

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

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

Also, you error is wsHttpBinding related. If you use sessions and restart the server, the reported security error message will appear.

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

According to MSDN:

根据MSDN

A reliable session implements the WS-ReliableMessaging protocol and an in-memory transfer window to mask SOAP message-level failures and re-establishes connections in the case of transport failures.

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

and

The reliable session is between the sender and receiver SOAP endpoints, regardless of the number of transport connections required for connectivity between them. In short, TCP reliability ends where the transport connection ends, whereas a reliable session provides end-to-end reliability.

可靠会话发生在发送方和接收方 SOAP 端点之间,而不管它们之间的连接所需的传输连接数是多少。简而言之,TCP 可靠性在传输连接结束的地方结束,而可靠会话提供端到端的可靠性。

Sounds like the expected behaviour.

听起来像预期的行为。

回答by Damith

You can use basic http binding with TransportCredentialOnly security mode

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

回答by YK1

Security mode None should do the job.

安全模式 None 应该可以完成这项工作。

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

Dont forget to apply the bindingConfiguration="WsEventLogBinding"on your endpoint.

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