gpt4 book ai didi

.net - 第 3 方应用程序破坏了我们的 WCF 应用程序

转载 作者:行者123 更新时间:2023-12-03 11:25:00 26 4
gpt4 key购买 nike

我们的应用程序使用 WCF 通过命名管道在两个进程之间进行通信(注意:这两个进程都不是 Windows 服务。)我们的应用程序已经在现场运行几年了,没有发生任何事故。

我们现在收到报告称第三方应用程序(特别是 Garmin Express)的存在正在破坏我们的应用程序。我已经在家里安装了 Garmin Express 并确认了这种行为。特别是“Garmin 核心更新服务”在运行时会导致我们的应用程序失败。

当 Garmin 服务运行时,我们应用程序的“服务”端启动并且创建 WCF 端点没有问题。但是当客户端启动并尝试连接到服务时,它会失败并显示 EndpointNotFoundException,就好像该服务甚至没有运行一样。

此时,我可以从“服务”控制面板中停止 Garmin 服务,然后成功重新运行客户端,甚至无需重新启动我们自己的服务。如果我再次启动 Garmin 服务,进一步尝试启动客户端将失败。所以这至少证明我们的 WCF 服务一直在运行,并且 Garmin 软件以某种方式阻止了我们的客户端连接到它的能力。

我们使用自己的名称作为端点地址(例如“net.pipe://localhost/MyPrivateApplication”)。我尝试将此地址更改为其他各种名称,但这对问题没有影响。

另一个应用程序如何仅仅通过运行来破坏我们自己的应用程序使用 WCF 的能力?

更新:根据请求,这里是来自服务端的代码片段。我已经从我们的原始代码中简化了它,以试图隔离问题。到目前为止,我所做的任何更改都没有对这个问题产生任何影响。

MyService service = new MyService();
ServiceHost host = new ServiceHost(service);
string hostAddress = new Uri("net.pipe://localhost/MyWCFConnection");
host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), hostAddress);
host.Open();

最佳答案

您的问题“另一个应用程序如何通过运行来破坏我们自己的应用程序......”的一个可能答案:

  • 另一个应用程序也使用 WCF NetNamedPipeBinding。
  • 这两个应用程序都使用基本 URL + 相对 URL 创建服务端点。
  • 应用程序对基地址和HostNameComparisonMode 的选择使得one of the URL variants used by the client-side WCF stack to locate the metadata for the service 上的应用程序之间存在名称冲突。 .

  • 我不知道 Garmin 服务是否真的使用 WCF NetNamedPipeBinding,但这是您应该调查的一种可能性。始终可以避免该问题 using absolute URLs for NetNamedPipe endpoints .

    好的,随着问题的更新,我们现在知道 Garmin 服务正在使用 WCF NetNamedPipeBinding,并且我们知道您的应用程序使用绝对地址注册其服务,因此上述解释不是完整的故事。

    这是另一个假设:
  • 假设 Garmin 服务在具有安全权限 SeCreateGlobalPrivilege 的进程中运行(Windows 服务将拥有该权限,除非经过特殊编码以禁用该权限)。
  • 假设它还使用 net.pipe://localhost 基地址和相对端点地址注册其 WCF 命名管道端点。
  • 现在,它的服务元数据将使用在全局命名空间中具有名称的共享内存映射对象发布。
  • 您的服务应用程序不是 Windows 服务。我的假设是它的进程没有安全权限 SeCreateGlobalPrivilege。如果是这种情况,其服务元数据将仅使用其本地 session 命名空间中的共享内存映射对象进行发布。
  • 现在,您的客户端进程尝试在 Garmin 服务运行时启动连接... WCF 客户端 channel 堆栈 NetNamedPipeBinding 元素尝试根据您的服务 URL net.pipe://localhost/MyWCFConnection 为您的服务定位服务元数据.正如上面链接中所解释的,它将依次使用服务 URL 的各种变体执行搜索,从而为包含元数据的共享内存对象派生一个名称。在查看 Local 命名空间之前,它首先在 Global 命名空间中查找变体的完整列表。
  • 在这种情况下,第一次尝试将针对从“net.pipe://+/MyWCFConnection”派生的名称,并且可能无法在 Global 命名空间中找到具有此名称的对象。
  • 然而,第二次尝试将基于变体“net.pipe://+/”,这将匹配在 Global 命名空间中发布的 Garmin 服务的共享内存映射的名称。 由于搜索顺序,它永远不会到达在本地 session 命名空间中发布的服务的元数据。
  • 您的客户端尝试连接到 Garmin 服务的管道。让我们假设 Garmin 服务实现了一些安全措施,这会导致您的客户端被拒绝访问(例如它可能是 set an ACL on its pipe )。结果很可能表现为 EndpointNotFoundException。 [ 后期编辑:实际上,最有可能发生的事情是您的客户端实际上正在连接到 Garmin 服务,启动帧协议(protocol)的前导握手,并收到帧协议(protocol)错误 ( http://schemas.microsoft.com/ws/2006/05/framing/faults/EndpointNotFound ),因为 Via 记录中请求的 URL 不匹配Garmin 服务期待什么。然后绑定(bind)会丢弃连接并将此错误作为 EndpointNotFoundException 显示给您的客户端代码。]

  • 你能为这个做什么?我会建议:
  • 如果上述假设或类似的东西可以得到证实,并且 Garmin 正在使用基址+相对寻址,基址仅为 net.pipe://localhost,那么最好让他们拥有这个问题:他们可以非常好地解决这样的问题通过将它们的基地址更改为更可能是唯一的地址来轻松实现。
  • 您或许可以通过找到某种方式让您的服务应用程序以安全特权 SeCreateGlobalPrivilege 运行来解决这个问题:如果不使其成为 Windows 服务或以管理员身份运行,这并不容易,但也许并非不可能。然后您的元数据也将发布在 Global 命名空间中,并且客户的搜索会在 Garmin 之前找到它。
  • [后期编辑] 也许有一种解决方法,包括将绑定(bind)的 HostNameComparisonMode 属性设置为 Exact,并使用 localhost 的同义词作为服务 URL 的主机部分(例如 net.pipe://127.0.0.1/MyWCFConnection)。这可能会引导围绕 Garmin 变体的搜索,以便您的客户有机会考虑本地 session 命名空间中的名称。我不知道它会起作用,但值得一试,我会想。
  • 还有一个很长的问题:贵公司是否与 Microsoft 有产品支持关系?可以说这是 WCF 中的一个严重设计缺陷:如果你对此大惊小怪,你可能会让微软为它发布一个 QFE 补丁,例如提供一个绑定(bind)属性来告诉客户端堆栈只尝试本地命名空间。
  • 关于.net - 第 3 方应用程序破坏了我们的 WCF 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15981392/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com