我有一个使用 ASP.Net Core 的 gRPC 服务器作为 Windows 服务运行。我还有一个以受限用户身份运行的 gRPC 客户端。如果我以管理员身份运行 gRPC 客户端,他们就可以正常通信。当我以非管理员身份运行它时,出现以下错误:
System.Net.Http.HttpRequestException:对路径的访问被拒绝。 (本地主机:80)
这是一个权限问题。根据这个堆栈溢出问题更改命名管道访问权限如果我使用原始命名管道,我可以在创建NamedPipeServerStream时更改权限。
gRPC 对命名管道的使用不太直接。
builder.WebHost.ConfigureKestrel(serverOption =>
{
serverOption.ListenNamedPipe(HelloWorldInfo.gRpcPipeName,
listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
builder.Services.AddGrpc();
有没有办法配置Kestrel将DACL添加到命名管道,以便受限用户可以通信?
第二个选项是在服务器启动后获取命名管道,并添加 DACL。但 NamedPipes 已经可以处理此配置。这只是如何的问题。
我尝试在像这样配置 Kestrel 时设置 PipeSecurity。
var pipeSecurity = CreateSystemIOPipeSecurity();
builder.WebHost.UseNamedPipes(opts =>
{
opts.PipeSecurity = pipeSecurity;
opts.CurrentUserOnly = false;
});
但是我明白了
System.IO.IOException:无法绑定到地址http://pipe:/HelloWorldPipe:地址已在使用中。
这也给我带来了一些麻烦,底层错误代码没有很好地转换为管道已在使用中的消息。
技巧是服务器进程身份不仅必须具有读写权限,还必须具有创建管道权限。
添加到您的 PipeSecurity 创建方法中
pipeSecurity.AddAccessRule(
new PipeAccessRule(
WindowsIdentity.GetCurrent().Owner!,
PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance,
AccessControlType.Allow
)
);