调用 NamedPipeServerStream.SetAccessControl 时“试图执行未经授权的操作”

Tyl*_*rdt 7 .net c# named-pipes

我正在尝试使用PipeSecurity来保护NamedPipeServerStream. 当我调用this.pipeServer.SetAccessControl(pipeSecurity)下面的代码段时,出现以下异常:

Attempted to perform an unauthorized operation.
    at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
    at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
    at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
    at System.IO.Pipes.PipeSecurity.Persist(SafeHandle handle)
Run Code Online (Sandbox Code Playgroud)

代码:

this.pipeServer =
    new NamedPipeServerStream(
        pipeName,
        PipeDirection.InOut,
        1,
        PipeTransmissionMode.Byte,
        PipeOptions.Asynchronous);

PipeSecurity pipeSecurity = new PipeSecurity();

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);

if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
    // Allow the Administrators group full access to the pipe.
    pipeSecurity.AddAccessRule(new PipeAccessRule(
        new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount)),
        PipeAccessRights.FullControl, AccessControlType.Allow));
} else {
    // Allow current user read and write access to the pipe.
    pipeSecurity.AddAccessRule(new PipeAccessRule(
        WindowsIdentity.GetCurrent().User,
        PipeAccessRights.ReadWrite, AccessControlType.Allow));
}

this.pipeServer.SetAccessControl(pipeSecurity);
Run Code Online (Sandbox Code Playgroud)

关于我做错了什么的任何想法?

这发生在 .NET Framework(针对 net451)和 .NET Standard 1.6 中,使用 System.IO.AccessControl nuget 包:

https://www.nuget.org/packages/System.IO.Pipes.AccessControl/

编辑:

我能够使用 #ifdef 来使用以下适用于 .NET Framework 的构造函数

public NamedPipeServerStream (string pipeName, System.IO.Pipes.PipeDirection 方向, int maxNumberOfServerInstances, System.IO.Pipes.PipeTransmissionMode传输模式, System.IO.Pipes.PipeOptions 选项, int inBufferSize, int outBufferSize, System.IO.Pipes.PipeSecurity pipeSecurity )

但是,.NET Standard 中不存在此构造函数。我尝试使用添加到 .NET Core 的这个函数

PipesAclExtensions.SetAccessControl(PipeStream, PipeSecurity)

但这会产生与之前相同的异常。

我创建了一个要点来展示这一点

Ale*_*icu 9

在 NET 5 中,您可以通过如下定义来创建可供所有用户帐户使用的NamedPipeServerStream :

PipeSecurity pipeSecurity = new PipeSecurity();

pipeSecurity.AddAccessRule(
    new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
    PipeAccessRights.ReadWrite, AccessControlType.Allow));

using (var pipe = NamedPipeServerStreamAcl.Create(
    "MyAppPipeName", 
    PipeDirection.InOut, 1, 
    PipeTransmissionMode.Message, 
    PipeOptions.None, 0, 0, 
    pipeSecurity))
    {
        pipe.WaitForConnection();
        // ...
    }
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于 Windows 操作系统。

  • 可以确认此方法也适用于.NET 6 (2认同)

Jen*_*nsG 6

我只是遇到了同样的问题并试图追踪它。

TL; 博士

当前的状态(2月- 2019)是可悲的,但真实的:它只是不工作与在今天的NET标准给出的类。

票证参考

在这种情况下同样有趣的可能是与 *nix 相关的

可能的解决方法

仍然可以使用本机 API 调用来根据需要设置安全性,但这不适合胆小的人。一个基本上需要实现这些步骤:


PS:至少我们现在可以在它撞墙的代码中查找它。试想一下,20 年前有这个问题......