我不认为这是可能的。
问题是必须在创建命名管道时提供的安全描述符中指定完整性标签。在标准 NetNamedPipeBinding 中,该调用发生在内部 WCF 类CreateNamedPipe
的私有方法中。我看不到改变它如何为管道指定初始安全描述符的方法。CreatePipe()
System.ServiceModel.Channels.PipeConnectionListener
请参阅此问题和答案,了解我们需要实现的目标。
从头开始编写自定义命名管道传输绑定元素似乎是目前解决此问题的唯一方法,如果失败,我们将不得不等待微软在未来版本的 WCF 中添加一些启用功能。如果您有权访问 Microsoft Connect,则可以将您的声音添加给其他请求此功能的人。
编辑:我太悲观了。我现在找到了一种方法来做到这一点。
关键是事实证明,当创建管道时,您不一定必须在安全描述符中指定完整性标签 - 但您必须在打开侦听器时使用 CreateNamedPipe 返回的句柄修改 SACL - 即管道的第一个服务器端句柄。使用任何其他句柄,添加完整性标签的尝试总是失败,因为dwOpenMode
flag 参数CreateNamedPipe
重载使用其中一个位来表示FILE_FLAG_FIRST_PIPE_INSTANCE
和WRITE_OWNER
。我们需要后一种访问权限才能添加完整性标签,但前者的存在会导致调用在除第一个管道实例之外的任何实例上失败。
抓住第一个管道手柄并非易事。WCF 将它隐藏在 type 的实例中System.ServiceModel.Channels.PipeConnectionListener.PendingAccept
,存储在由管道连接侦听器维护的列表中。连接监听器和通道监听器不是一回事(可以直接通过覆盖BuildChannelListener<>
绑定元素的方法),而且更难理解。它涉及使用反射来定位端点的 TransportManager,它保存对端点连接侦听器的引用,然后沿着连接侦听器链(根据跟踪等的配置而变化)工作,直到找到管道连接侦听器. 如果幸运的话,第一个管道句柄可以在侦听器的待处理接受列表中找到(尽管这里存在竞争条件 - 如果客户端在我们获得句柄之前连接,它将永远消失)。
一旦句柄可用,降低完整性以允许低完整性客户端与服务通信只是调用SetSecurityInfo
句柄以添加完整性标签的问题。
我计划很快在我的博客上介绍这些细节。