2014-01-15 45 views
0

我有一個使用IPC通道和多個客戶端的.NET Remoting服務器。我需要設置服務器端,以便只有管理員才能訪問管道。我知道服務器頻道有「authorizedGroup」屬性。IPC通道授權組

當我沒有設置它時,只有當服務器和客戶端在同一個帳戶下(太陽),我纔可以進行通信。如果我將它設置爲「用戶」(我使用Windows的英文版),那麼服務器可以在LocalSystem下運行,並且客戶端可以像任何其他用戶可以連接一樣運行(ok)。當我創建一個專門的組時,它也可以正常工作。但我想配置它,以便只有本地管理員組的成員才能連接。我嘗試將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); 

任何想法,可我是做錯了什麼?或者至少我該如何開始調試這個問題。

+0

你可以發佈你的頻道服務器和客戶端的配置代碼嗎?你確定你是以LocalSystem運行而不是LocalService嗎? – csaam

+0

該服務以本地系統的身份運行 - 任務管理器將其顯示爲SYSTEM。 –

回答

0

我知道我們都討厭這個答案,但它爲我工作。

我用一個方法Ping做了一個接口IMyService。然後,我實現了它,並添加你的客戶端代碼給它的構造函數,因爲我看到你註冊這個作爲元帥的呼叫服務:

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; 
    } 
} 

我構建了成員變量的MyService在NT服務OnStart方法。

安裝服務爲本地系統並啓動它後,我跑了客戶端代碼:

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是真的很回聲和Console.WriteLine輸出的「Hello World」。

是否有可能用戶真的不在本地計算機的管理員組中,或者MyService是否有可能正在做一些本身沒有權限執行的操作,以及您看到的是服務器端異常?例如LocalServer不能訪問網絡資源。

+0

「用戶確實不在本地計算機的管理員組中」 - 它肯定是(至少在我登錄控制面板 - >管理工具 - >計算機管理 - >本地用戶和組時)。但是,看起來UAC在這裏扮演着一個角色:如果我將它關閉(在註冊表中將EnableLUA設置爲0),那麼它將按預期工作(但顯然這不是解決方案)。 –