命名管道客户端无法连接到作为网络服务运行的服务器

Posted

技术标签:

【中文标题】命名管道客户端无法连接到作为网络服务运行的服务器【英文标题】:Named pipe client unable to connect to server running as Network Service 【发布时间】:2014-07-14 04:34:14 【问题描述】:

我有一个在网络服务帐户下运行的服务。该服务只是设置一个命名管道并监听连接:

NamedPipeServerStream listeningPipe = new NamedPipeServerStream("ourservicepipe",
    PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, 
    PipeTransmissionMode.Message, PipeOptions.Asynchronous);
listeningPipe.BeginWaitForConnection(OnPipeConnected, listeningPipe);

我有一个应用程序在同一台机器上的标准用户帐户上运行。它尝试连接到服务创建的命名管道:

NamedPipeClientStream pipe = new NamedPipeClientStream(".", "ourservicepipe", 
    PipeDirection.InOut, PipeOptions.Asynchronous);
pipe.Connect(2000);
pipe.ReadMode = PipeTransmissionMode.Message;

当我调用Connect 时,它最终会抛出一个InvalidOperationException。如果我在同一个用户上运行该服务,它可以正常连接。如果我以管理员身份运行客户端,它可以正常连接。这让我相信问题出在权限上,但我不知道在安装过程中需要设置哪些权限。

如何让客户端连接到服务器,而不要求客户端以管理员身份运行?

【问题讨论】:

【参考方案1】:

我不允许发表评论,但我想指出 dvansanth 的答案是否正确取决于操作系统语言。 当操作系统语言不是英语时,“Everyone”组可能不存在。

我已经这样解决了:

PipeSecurity pipeSa = new PipeSecurity();
pipeSa.SetAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), 
                PipeAccessRights.ReadWrite, AccessControlType.Allow)); 
listeningPipe.SetAccessControl(pipeSa);

请注意,这是针对“经过身份验证的用户”而不是“所有人”

【讨论】:

是否需要SecurityIdentifier.ToString()?【参考方案2】:

管道服务器是使用默认服务 DACL 创建的,因此只有管理员或系统用户才能连接到管道。您需要使用适当的访问规则设置管道服务器,以使所有客户端连接成功。下面是设置访问规则以访问每个人访问管道的代码:

    PipeSecurity pipeSa = new PipeSecurity(); 
    pipeSa.SetAccessRule(new PipeAccessRule("Everyone", 
                    PipeAccessRights.ReadWrite, AccessControlType.Allow)); 
    listeningPipe.SetAccessControl(pipeSa);

最好只定义最少量的用户来访问管道服务器以确保其安全。

【讨论】:

试图执行未经授权的操作 - pipe.SetAccessControl(pipeSa);

以上是关于命名管道客户端无法连接到作为网络服务运行的服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何将命名管道c#服务器连接到命名管道php客户端

Android LocalSocket客户端无法连接到抽象命名空间中的本机服务套接字

获取使用 C# 连接到命名管道服务器的客户端的进程 ID

可以连接到命名管道的客户端数量

Rails 应用程序无法通过命名管道/套接字连接到本地 MySQL 服务器 --- Windows 7 x64

我可以拥有多少个命名管道?