IPC渠道授权组

时间:2014-01-15 23:15:00

标签: .net ipc named-pipes .net-remoting

我有一个使用IPC通道和多个客户端的.NET Remoting服务器。我需要设置服务器端,以便只有管理员才能访问管道。我知道服务器频道有“authorizedGroup”属性。

当我没有设置它时,我只能在服务器和客户端是同一帐户下的sun(ok)时进行通信。如果我将其设置为“用户”(我使用英文版的Windows),则服务器可以在LocalSystem下运行,客户端可以像任何其他用户一样运行(ok)。当我创建一个专用组时,它也可以正常工作。但我想配置它,以便只有本地Administrators组的成员才能连接。我尝试将authorizedGroup设置为“Administrators”或“BUILTIN \ Administrators”,但我在客户端上得到一个例外,基本上说“拒绝访问”,即使运行客户端的用户是Administrators组的成员。

服务器配置:

var clientProv = new BinaryClientFormatterSinkProvider();
var serverProv = new BinaryServerFormatterSinkProvider() { TypeFilterLevel = TypeFilterLevel.Full };
Hashtable channelProperties = new Hashtable();
channelProperties.Add("portName", "MyService");
channelProperties.Add("authorizedGroup", "Administrators");
channelProperties.Add("secure", "true");
channelProperties.Add("exclusiveAddressUse", false);
channel = new IpcChannel(channelProperties, clientProv, serverProv);
ChannelServices.RegisterChannel(channel, false);
RemotingServices.Marshal(this, "MyService.rem");

客户端配置:

var clientProv = new BinaryClientFormatterSinkProvider();
var serverProv = new BinaryServerFormatterSinkProvider() { TypeFilterLevel = TypeFilterLevel.Full };
Hashtable channelProperties = new Hashtable();
channelProperties.Add("portName", "remotingClient_" + Guid.NewGuid().ToString("N"));
channelProperties.Add("authorizedGroup", GetNameForSid(WellKnownSidType.LocalSystemSid));
channelProperties.Add("exclusiveAddressUse", false);
channelProperties.Add("secure", "true");
channelProperties.Add("tokenImpersonationLevel", "identification");
channel = new IpcChannel(channelProperties, clientProv, serverProv);
ChannelServices.RegisterChannel(channel, false);

var uri = "ipc://" + "MyService/MyService.rem";
RemotingConfiguration.RegisterWellKnownClientType(new WellKnownClientTypeEntry(typeof(IMyService), uri));
remoteServer = (IMyService)Activator.GetObject(typeof(IMyService), uri);

知道我可能做错了什么吗?或者至少如何开始调试此问题。

1 个答案:

答案 0 :(得分:0)

我知道我们都讨厌这个答案,但它对我有用。

我使用单个方法Ping创建了一个IMyService接口。然后我实现了它并将你的客户端代码添加到它的构造函数中,因为我看到你将它注册为Marshal调用中的服务:

public class MyService : MarshalByRefObject, IMyService
{
    private IpcChannel channel;
    public MyService()
    {
        var clientProv = new BinaryClientFormatterSinkProvider();
        var serverProv = new BinaryServerFormatterSinkProvider() { TypeFilterLevel = TypeFilterLevel.Full };
        Hashtable channelProperties = new Hashtable();
        channelProperties.Add("portName", "MyService");
        channelProperties.Add("authorizedGroup", "Administrators");
        channelProperties.Add("secure", "true");
        channelProperties.Add("exclusiveAddressUse", false);
        channel = new IpcChannel(channelProperties, clientProv, serverProv);
        ChannelServices.RegisterChannel(channel, false);
        RemotingServices.Marshal(this, "MyService.rem");
    }
    public string Ping(string value)
    {
        return value;
    }
}

我在NT服务OnStart方法中构造了成员变量MyService。

将服务作为LocalSystem安装并启动后,我运行了客户端代码:

class Program
{
    static void Main(string[] args)
    {
        var clientProv = new BinaryClientFormatterSinkProvider();
        var serverProv = new BinaryServerFormatterSinkProvider() { TypeFilterLevel = TypeFilterLevel.Full };
        Hashtable channelProperties = new Hashtable();
        channelProperties.Add("portName", "remotingClient_" + Guid.NewGuid().ToString("N"));
        channelProperties.Add("authorizedGroup", GetNameForSid(WellKnownSidType.LocalSystemSid));
        channelProperties.Add("exclusiveAddressUse", false);
        channelProperties.Add("secure", "true");
        channelProperties.Add("tokenImpersonationLevel", "identification");
        IpcChannel channel = new IpcChannel(channelProperties, clientProv, serverProv);
        ChannelServices.RegisterChannel(channel, false);

        var uri = "ipc://" + "MyService/MyService.rem";
        RemotingConfiguration.RegisterWellKnownClientType(new WellKnownClientTypeEntry(typeof(IMyService), uri));
        IMyService remoteServer = (IMyService)Activator.GetObject(typeof(IMyService), uri);
        Console.WriteLine(remoteServer.Ping("Hello World"));
    }
    private static string GetNameForSid(WellKnownSidType wellKnownSidType)
    {
        SecurityIdentifier id = new SecurityIdentifier(wellKnownSidType, null);
        return id.Translate(typeof(NTAccount)).Value;

    }
}

Ping只是一个echo而且Console.WriteLine输出“Hello World”。

用户是否可能真的不在本地计算机的管理员组中,或者MyService是否可能正在做一些本身没有权限的事情,以及您看到的是服务器端异常?例如,LocalServer无权访问网络资源。