我有一个使用ASP.NET Core的GRPC服务器作为Windows服务运行.我还有一个以受限用户身份运行的GRPC客户端.如果我以管理员身份运行GRPC客户端,他们可以很好地通信.当我以非管理员身份运行它时,我收到以下错误:

System.Net.Http.HttpRequestException:对路径的访问被拒绝.(本地主机:80)

这是一个权限问题.根据这个堆栈溢出问题Change Named Pipe Access Permissions,如果我使用原始命名管道,我可以在创建NamedPipeServerStream时更改权限.

GRPC对命名管道的使用不那么直接.

builder.WebHost.ConfigureKestrel(serverOption =>
    {
        serverOption.ListenNamedPipe(HelloWorldInfo.gRpcPipeName,
            listenOptions =>
            {
                listenOptions.Protocols = HttpProtocols.Http2;
            });
    });
builder.Services.AddGrpc();

有没有办法将Kestrel配置为将DACL添加到命名管道中,以便受限用户可以通信?

第二种 Select 是在服务器启动后获取命名管道,并添加DACL.但NamedPipes已经可以处理这种配置.这只是一个如何实现的问题.

我try 在配置Kestrel时设置PipeSecurity,如下所示.

var pipeSecurity = CreateSystemIOPipeSecurity();
builder.WebHost.UseNamedPipes(opts =>
{
    opts.PipeSecurity = pipeSecurity;
    opts.CurrentUserOnly = false;
});

但我得到了

System.IO.IO异常:未能绑定到已在使用的地址http://pipe:/HelloWorldPipe:地址.

推荐答案

这也给我带来了一些麻烦,潜在的错误代码没有很好地转换为管道已在使用的消息.

诀窍在于,服务器进程标识不仅必须具有读写权限,还必须具有创建管道权限.

仅具有读写权限且初始管道创建成功,但后续池连接创建因ACL限制而失败.

添加到您的PipeSecurity创建方法如下

pipeSecurity.AddAccessRule(
    new PipeAccessRule(
        WindowsIdentity.GetCurrent().Owner!,
        PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance,
        AccessControlType.Allow
    )
);

Csharp相关问答推荐

Regex在c#中完全匹配

C#将参数传递给具有变化引用的变量

下拉图片点击MudBlazor

为什么将鼠标悬停在DateTimeOffset上只显示Hour值?

C#-从基类更新子类

在EF Core中,有没有什么方法可以防止在查询中写入相同的条件,而代之以表达式?

NET8 Maui&;iOS:AppCenter崩溃错误

将字节转换为 struct 并返回

.NET 6:如何防止系统生成的日志(log)?

在使用StringBuilder时,如何根据 colored颜色 设置为richTextBox中的特定行着色?

在C#中,是否有与变量DISARD对应的C++类似功能?

当空判断结果赋给变量时,为什么会出现可能空异常警告的解引用?

.NET8->;并发词典总是比普通词典快...怎么回事?[包含基准结果和代码]

正在从最小API-InvocationConext.Arguments中检索参数的FromBodyAttribute

两个DateTimeOffset之间的差异返回意外的负值

如何在C#中正确类型化带有泛型的嵌套类

Blazor服务器项目中的Blazor/.NET 8/Web API不工作

将J数组转换为列表,只保留一个嵌套的JToken

如何在一次数据库调用中为ASP.NET核心身份用户加载角色

如何根据分割文本的块数来计算文本的大小?