【问题标题】:Can a WebServiceHost be changed to avoid the use of HttpListener?是否可以更改 WebServiceHost 以避免使用 HttpListener?
【发布时间】:2010-03-10 14:22:58
【问题描述】:

我正在寻找一种方法来使用 WCF WebServiceHost 而不必依赖 HttpListener 类及其相关的权限问题(有关详细信息,请参阅this question)。

我正在开发一个应用程序,该应用程序通过其 REST API 与另一个(第三方)应用程序进行本地通信。

目前我们使用 WCF 作为嵌入式 HTTP 服务器。我们创建一个 WebServiceHost 如下:

String hostPath = "http://localhost:" + portNo;
WebServiceHost host = new WebServiceHost(typeof(IntegrationService), new Uri(hostPath));

// create a webhttpbinding for rest/pox and enable cookie support for session management
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.AllowCookies = true;

ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IIntegrationService), webHttpBinding, "");

host.Open()

ChannelFactory<IIntegrationService> cf = new ChannelFactory<IIntegrationService>(webHttpBinding, hostPath);
IIntegrationService channel = cf.CreateChannel();

只要我们的应用程序以管理员身份运行,一切都会运行良好。如果我们在没有管理权限的机器上运行我们的应用程序,host.Open() 将抛出一个 ErrorCode == 5 (ERROR_ACCESS_DENIED) 的 HttpListenerException。

我们可以通过从命令行运行 httpcfg.exe 来解决这个问题,但这是一个一键式桌面应用程序,这对我们来说并不是真正的长期解决方案。

我们可以放弃 WCF 并编写自己的 HTTP 服务器,但如果可能的话,我想避免这种情况。

在仍然使用 WCF 提供的所有剩余 HTTP 脚手架的同时,用标准 TCP 套接字替换 HttpListener 的最简单方法是什么?

【问题讨论】:

  • ErrorCode == 5 (ERROR_ACCESS_DENIED): "netsh http urlacl" 是您授予自己访问 HTTP 侦听器保留地址的方式。

标签: c# wcf httplistener


【解决方案1】:

您的问题与 HttpListener 无关。

你的问题是: * 您有一个具有有限权限的 oneClick 应用程序 * 尝试打开一个服务器端口。

这是一个矛盾。不受信任的受限权限应用程序不应打开服务器端口。这就是为什么每个定义都不允许这样做的原因。

你试过打开一个普通的套接字端口吗?它也不应该工作。

一般而言,有限信任的最终用户应用程序不应托管 Web 服务;)

也就是说,我在尝试在驱动程序通信场景中使用 WCF 时遇到过类似的情况 - 谢天谢地,我的应用程序在完全许可的情况下运行。

【讨论】:

  • 我很欣赏你所说的,但我只是仔细检查了这一点,在这些情况下可以打开一个正常的监听套接字。问题特别在于 HttpListener - 可能是因为它可能允许恶意应用程序在与其他端口相同的端口上运行(因此流量可能会进入防火墙 - 有关更多详细信息,请参阅 leastprivilege.com/HttpCfgACLHelper.aspx)。事实是,无论我们如何部署应用程序,作为受限用户运行时我们都会遇到同样的问题,并且有很多真正的理由想要这样做。
【解决方案2】:

您可以通过 CustomBinding 轻松构建自己的堆栈,“按原样”使用更高级别的协议内容,并滚动您自己的不受 HttpListener 或 IIS 支持的 HttpTransport 版本。可以,当然,但这是很多工作。将现有的 HttpTransport 位与 Reflector 分开 - 那里有很多活动部件。如果您不需要像 HTTPS 或分块这样的花哨的东西,您可能在一两天内通过 Socket 破解一个简单的 PoC,但使其健壮将是棘手的。 Here 很好地总结了一堆资源(现在可能有点过时了)。

【讨论】:

  • 感谢您的链接 - 这几乎是我得出的结论。不幸的是,几乎所有我想派生的类(HttpChannelListener、HttpTransportManager 等)都被标记为内部的,所以你是对的,需要大量的重新实现。哼哼。
  • 我们不需要任何花哨的东西,所以我最终推出了自己的小型 HTTP 服务器,它能够理解我们预先存在的服务合同。大量的内部类和私有方法使得 WCF 实现过于耗时,可耻。
  • 同意——我做过类似的事情,WCF REST 的东西落在了我们身上,我们必须改变的一件小事在 HttpTransport 中太深了,不值得。我什至可以通过调整内部成员使其在调试器中工作,但没有办法真正做到。
【解决方案3】:

您还可以考虑拆分足够多的 Cassini 以使其可在您的应用程序中托管,并在其中加载 WCF 管道(通过 .svc 文件和服务激活处理程序)——它只需要编写很少的新内容以这种方式编写代码,但仍然为您提供了一个相当健壮且经过测试的网络服务器。

【讨论】:

    猜你喜欢
    • 2018-10-04
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多