这是一个很长的帖子,所以这里是我的问题的前提:我想在C#中使用ServiceController类来控制另一台计算机上的服务,但看起来我需要冒充一个帐户服务主机以符合.NET管理安全性的方式。我该怎么做?
细节:
我们在服务器上托管了一些WCF服务,并依赖于它们的客户端应用程序。 (所有内容都是用.NET 4.0 C#编写的。)客户端上有一个仪表板,显示哪些服务正在运行,如果任何服务出现故障,我们希望让用户尝试远程重启它们。经过一些研究,看起来ServiceController可以做我们希望的事情。我已经开始玩它,这是我到目前为止所写的:
/// Called when the user clicks a button in the system health dashboard view
///to restart a broken service
private void RestartService()
{
var servcntrls = ServiceController.GetServices(HostName);
//TODO finish method
}
显然,这实际上并没有重启服务。我想我看到如何使用ServiceController.Start()
和.Stop().
来执行此操作当执行这么多代码时,调用GetServices()
时会抛出异常:
Type = System.InvalidOperationException
Message = Cannot open Service Control Manager on computer '/* computer name snipped */'. This operation might require other privileges.
Data:
System.Object =
Stack Trace:
at System.ServiceProcess.ServiceController.GetDataBaseHandleWithAccess(String machineName, Int32 serviceControlManaqerAccess)
at System.ServiceProcess.ServiceController.GetDataBaseHandleWithEnumerateAccess(String machineName)
at System.ServiceProcess.ServiceController.GetServicesOfType(String machineName, Int32 serviceType)
at System.ServiceProcess.ServiceController.GetServices(String machineName)
at Client.Organizer.SystemHealth.ViewModels.ClientStatusViewModel.RestartService() in C:\Source\X\Trunk\Client\Organizer\SystemHealth\ViewModels\ClientStatusViewModel.cs:line 38
at GalaSoft.MvvmLight.Command.RelayCommand.Execute(Object parameter)
at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at //Snip
==== Inner Exception ====
Type = System.ComponentModel.Win32Exception
Message = Access is denied
我对此做了一些研究并找到了这些主题:
How to remotely control a Windows Service with ServiceController?
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/18c34a5c-8637-4e85-b9ee-d9052bb12a34/
ServiceController permissions in Windows 7
servicecontroller permissions
http://social.msdn.microsoft.com/Forums/en/wcf/thread/c35e75c4-de7d-409d-bc82-4533e4982264
我从他们那里收集到的是,当ServiceController与服务交互时,它需要具有与之交谈的适当权限。我发现的文章建议使用服务器上的相应权限模拟用户帐户。
不幸的是,我对.NET如何管理安全问题完全陌生,所以我不知道我该怎么做。所以这是我的问题:
1.在服务器上冒充帐户是否适合解决此问题?我读过的帖子中有一个人认为它引发了太多的安全漏洞
2.我如何冒充帐户?是否有一篇文章有一个很好的代码示例?
3.有没有办法在不配置服务器和客户端计算机的情况下冒充用户?我们在客户的环境中设置了系统,我不想为安装添加一个模糊的步骤。
编辑:根据AvkashChauhan的回答,我们的WCF服务作为Windows服务托管。
答案 0 :(得分:1)
WCF服务可以托管在1)IIS Web服务器,2)WAS服务器,3)自我主机,最后4)Windows服务,如果您的WCF服务仅托管在 Windows服务上然后您可以使用ServicesController类来控制服务。虽然基于IIS和WAS的WCF服务通过应用程序域和进程提供控制,但Windows Service Hosted WCF服务是通过ServiceController类进行管理的。
我只是想确保您的WCF服务作为Windows服务托管,因为您的问题并不清楚。上面的链接主要是处理Windows服务(而不是WCF服务)。
此外,您可以通过HTTP / netpipe或其他方式将WCF服务作为Windows服务托管,因此取决于您使用的通信渠道,安全设置将基于此,您知道它是什么吗?
使用WCF服务,您可以先尝试使用IP地址而不是机器名来获取托管服务,因为这是一个非常常见的问题。另请参阅以下SO讨论:
答案 1 :(得分:0)
您可以在工具中使用
PsExec Tool,用于在远程计算机上执行命令行进程。