2011-02-25 132 views
5

是WCF和命名管道的新手。保护WCF使用的命名管道

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

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

现在所有这些交换只能在授权用户帐户(可能与服务帐户不同)下发生。所以我正在考虑为服务和用户帐户ACL命名管道。

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

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

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

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

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

回答

8

1)我认为这是一个不错的办法。你的想法是现货。

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

CustomBinding导出AclSecuredNamedPipeBinding和从NamedPipeTransportBindingElement对应的AclSecuredNamedPipeTransportBindingElement。结合元件具有的SecurityIdentifier列表:

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

BuildChannelListener<TChannel>(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中所述。

+3

很抱歉,此博客已不存在。任何人都记得该做什么?我尝试使用反射设置允许的用户,但没有做到我所希望的。你能帮忙的话,我会很高兴。 – mageos 2014-06-18 16:38:17

0

我尝试了上面“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’到‘管理员’,然后我得到的异常以下。

”有是StudentService对象引用的一个问题不设置为一个对象的一个​​实例。”

studentService是类实现的IStudentService接口。

public class StudentService : IStudentService 
{ 
public void DoWork() 
{ 
} 
}