保护 WCF 使用的命名管道

Posted

技术标签:

【中文标题】保护 WCF 使用的命名管道【英文标题】:Securing the named pipe used by WCF 【发布时间】:2011-07-04 14:39:47 【问题描述】:

我是 WCF 和命名管道的新手。

我需要一种方法在同一台机器上的 UI 应用程序和 Windows 服务之间进行安全通信。这是我需要的: - 客户端 UI 应用程序需要向 Windows 服务发送(推送)各种消息类型。 - 客户端 UI 应用需要从服务接收各种类型的消息(推送或拉取)。

(这里的消息只是一个结构化的序列化数据)。

现在所有这些交换都应该只在授权用户帐户下进行(可能与服务帐户不同)。所以我正在考虑为服务和用户帐户创建一个命名管道。

但是,命名管道仅支持流。我有多种类型的消息需要通过命名管道进行交换,这意味着我需要定义它们并序列化/反序列化它们。

为了避免这种情况,我想到了在命名管道上使用 WCF(用于序列化和 RPC 支持)。还在 Windows 服务中托管 WCF 服务。

问题 1) 这是一个好方法吗?我在使用 WCF 下的 http 或 tcp 时犹豫不决,因为通信必须保持在机器内。

问题 2) 如果以及如何 ACL WCF 将使用的命名管道?这是我能控制的吗? 我觉得使用特定 SID 对名称管道进行 ACL 可以为我提供更好的安全性,而不是在客户端和服务器之间实施身份验证方案。

感谢您的任何指点,建议! 萨米尔

【问题讨论】:

【参考方案1】:

1) 我认为这是一个很好的方法。你的想法是正确的。

2) 正如您似乎已经发现的那样,my blog post here shows you one way to set the ACL on the pipe 由 WCF NetNamedPipe 绑定创建。它涉及使用反射来填补微软实现中的空白,这显然是为了支持设置 ACL 的直接机制,但没有正确完成。

CustomBinding 派生一个AclSecuredNamedPipeBinding,从NamedPipeTransportBindingElement 派生一个对应的AclSecuredNamedPipeTransportBindingElement。绑定元素有一个SecurityIdentifier的列表:

internal List<SecurityIdentifier> AllowedUsers  get  return _allowedUsers;  
private List<SecurityIdentifier> _allowedUsers = new List<SecurityIdentifier>();

BuildChannelListener&lt;TChannel&gt;(BindingContext)-method 被覆盖以设置私有属性AllowedUsers

public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)

  private static Type namedPipeChannelListenerType 
          = Type.GetType("System.ServiceModel.Channels.NamedPipeChannelListener, System.ServiceModel", false);
  IChannelListener<TChannel> listener = base.BuildChannelListener<TChannel>(context);
  PropertyInfo p = namedPipeChannelListenerType.GetProperty(
          "AllowedUsers", BindingFlags.Instance|BindingFlags.NonPublic);
  p.SetValue(listener, _allowedUsers, null);
  return listener;

如果你走这条路,请务必按照a later post 中的说明修补“蹲坑漏洞”。

【讨论】:

很遗憾,此博客不再可用。有人记得是谁做的吗?我尝试使用反射来设置允许的用户,但这并没有达到我的预期。任何帮助都会很好。【参考方案2】:

看到这些非常有帮助的帖子: Exploring the WCF Named Pipe Binding - Part 3 - Chris Dickson's Blog

【讨论】:

通过添加链接指向的内容和更新链接来改进。【参考方案3】:

我尝试了上面“Chris Disson 的博客”中的建议,但在以管理员权限运行服务代码后,出现以下异常。 “StudentService 存在问题 部分或全部身份参考无法翻译。” 这是我托管服务的代码

AclSecuredNamedPipeBinding binding = new AclSecuredNamedPipeBinding();
SecurityIdentifier allowedGroup = (SecurityIdentifier)(new 
NTAccount("NPServiceUsers").Translate(typeof(SecurityIdentifier)));
binding.AddUserOrGroup(allowedGroup);
studentServiceHost = new ServiceHost(typeof(StudentService.StudentService));
Uri httpBaseAddress = new 
Uri("net.pipe://localhost/ServiceHost/ServiceHost");

studentServiceHost.AddServiceEndpoint(
typeof(StudentService.IStudentService),binding, httpBaseAddress); 
studentServiceHost.Open();

然后我尝试将 nTAccount 从“NPServiceUsers”更改为“Administrators”,然后出现以下异常。

“StudentService 对象引用未设置为对象实例存在问题。”

studentService 是实现 IStudentService 接口的类。

public class StudentService : IStudentService

public void DoWork()



【讨论】:

以上是关于保护 WCF 使用的命名管道的主要内容,如果未能解决你的问题,请参考以下文章

使用命名管道 WCF 服务时通信对象出错

WCF 服务命名管道故障

带有命名管道的 WCF:如何允许并行调用?

从 VB6 到 WCF 的命名管道

当 2 个进程尝试同时在不同管道上相互通信时,使用命名管道的 WCF IPC 会崩溃

创建命名管道 (WCF) 所需的最低操作系统权限