Loc*_*eer 2 c# asp.net-mvc impersonation process
我需要从MVC控制器在服务器上运行可执行文件.问题:可执行文件位于Program Files文件夹中,并且还将从注册表中读取值.我已将相应文件夹的执行权限授予我的应用程序池.所以这是我的问题:
只运行exe Process.Start(exe)
将启动可执行文件,然后由于无法读取注册表值(无访问权限)而退出并出现错误.
将本地管理员用户分配为ProcessStartInfo
失败:
var exe = @"C:\Program Files (x86)\[path to exe]";
var secString = new SecureString();
secString.AppendChar('character');
//...
secString.MakeReadOnly();
var procInfo = new ProcessStartInfo(exe, settingsPath)
{
UseShellExecute = false,
UserName = "[username]",
Domain = "[domain]",
Password = secString,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
Verb = "runas"
};
var proc = Process.Start(procInfo);
proc.WaitForExit();
Run Code Online (Sandbox Code Playgroud)
这将导致conhost和可执行文件崩溃.
使用这样的模拟:
var impers = new ImpersonationService();
impers.PerformImpersonatedTask("[user]", "[domain]", "[password]",
ImpersonationService.LOGON32_LOGON_INTERACTIVE, ImpersonationService.LOGON32_PROVIDER_DEFAULT, new Action(RunClient));
Run Code Online (Sandbox Code Playgroud)
...用RunClient()
简单的方法使用Process.Start(exe)
将绝对没有!运行该方法但该过程未启动.我知道该方法是运行的,因为我添加了这一行:
_logger.Debug("Impersonated: {0}", Environment.UserName);
Run Code Online (Sandbox Code Playgroud)
这正确地为我提供了该过程应使用的所需用户名.该用户具有本地管理员权限,因此不存在问题.
我甚至试图从开始我的控制器不同的可执行文件,并有一个使用模拟(两种款式)启动目标可执行文件-相同的结果.
所以现在我走到了尽头.任何人都可以告诉我我做错了什么以及我必须做些什么来使它工作?
PS:登录时直接在服务器上运行目标可执行文件,因为本地管理员用户工作得很好,所以没有exe本身的问题.
编辑:
看来我的描述的一部分是不正确的:与模拟和RunClient方法其实我没有使用Process.Start(exe)
,但这样的:
var procInfo = new ProcessStartInfo(exe, settingsPath)
{
UseShellExecute = false,
};
_logger.Debug("Impersonated: {0}", Environment.UserName);
var proc = Process.Start(procInfo);
Run Code Online (Sandbox Code Playgroud)
出于绝望,我现在已经规避了procInfo
(实际上并不需要它)并且真的打电话给我
var proc = Process.Start(exe, argument);
Run Code Online (Sandbox Code Playgroud)
现在.exe开始了!似乎使用ProcessStartInfo会覆盖进程的模拟?
但仍然不行,因为现在我收到"拒绝访问"错误.尽管是本地管理员.这很奇怪.
编辑2: 这是我最近的尝试:
level="requireAdministrator"
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
从目标过程中的方法之前添加.结果代码:
try
{
var secString = new SecureString();
//...
secString.MakeReadOnly();
var procInfo = new ProcessStartInfo()
{
FileName = Path.GetFileName(exe),
UserName = "[UserName]",
Domain = "[domain]",
Password = secString,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
Arguments = settingsPath,
WorkingDirectory = @"C:\Program Files (x86)\[rest]"
};
var proc = Process.Start(procInfo);
proc.WaitForExit();
if (proc.ExitCode != 0)
{
using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "error.log"), true))
{
sw.WriteLine("Error running process:\r\n{0}", proc.ExitCode.ToString());
}
}
}
catch (Exception ex)
{
using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "error.log"), true))
{
sw.WriteLine("Error running process:\r\n{0}\r\nRunning as: {1}", ex.ToString(), WindowsIdentity.GetCurrent().Name);
}
}
Run Code Online (Sandbox Code Playgroud)
结果输出到error.log:
帮手跑![传递参数]运行错误的进程:System.ComponentModel.Win32Exception(0x80004005):在System.Diagnostics.Process.Start的System.Diagnostics.Process.Start()处的System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)中拒绝访问( ProcessClartInfo startInfo)在RunClient.ImpersonationDemo.RunClient(String settingsPath)运行方式:[管理员组中的正确域用户]
所以,我可以启动辅助exe文件,但认为由于接取否认,尽管在本地管理员帐户运行时无法启动程序文件的真实EXE和所有的文件访问本地,而不是网络驱动器上.
这种逻辑使我望而却步.
编辑3
更新:我已经向目标.exe添加了一个清单,
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
这意味着我现在:
Process.Start(Startinfo)
本地管理员用户集运行目标exe ,同时仍然模拟该用户的Windows身份而且还是错误日志嘴"拒绝访问",而正确地恢复WindowsIdentity.GetCurrent().Name
为本地管理员的.
现在,最重要的是:我在该服务器上创建了一个新的本地用户,将他添加到本地管理员组并使用该用户进行模拟,以防域用户出现问题.你猜怎么着?现在我收到一个错误Access denied to ...\error.log
- 写入效果错误日志.
真?
编辑4
我想我会尝试使用TopShelf将这个shebang转换为服务.希望在周末完成这项工作.
根据这篇文章,你的mvc控制器线程应具有完全信任的权限来运行该进程:
此类包含适用于所有成员的类级别的链接需求.当直接调用方没有完全信任权限时,抛出SecurityException.有关安全性要求的详细信息,请参阅链接要求.
似乎你的问题不是用户而是完全信任.我不知道您使用的是哪个版本的MVC,但您可以阅读文章Trust Levels和Code Access以找出配置应用程序的最佳方法.似乎您只能向特定的.exe文件授予完全信任权限,或者向应用程序池用户授予完全信任权限(不要忘记文件夹权限).
但最好的方法是编写一些Windows服务并运行它而不是直接运行一些.exe文件.