从ASP.NET网站访问拒绝启动过程

时间:2019-04-05 17:18:32

标签: c# asp.net windows-server-2012

我有一个ASP.NET MVC4网站,我试图在该网站上执行服务器上的进程。代码如下:

ProcessStartInfo startInfo = new ProcessStartInfo()
{
    FileName = ExeLocation,
    Arguments = string.Format("\"{0}\"{1}", ScriptLocation, Arguments),
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    WorkingDirectory = AppDir,
    CreateNoWindow = true,
    UserName = ExeUsername,
    Password = ExePassword,
    Domain = ExeDomain
};

using (Process process = Process.Start(startInfo))
{
    using (StreamReader reader = process.StandardOutput)
    {
        output = reader.ReadToEnd();
    }
    using (StreamReader reader = process.StandardError)
    {
        error = reader.ReadToEnd();
    }
    process.WaitForExit();
    if (process.ExitCode != 0)
    {
        throw new Exception(string.IsNullOrEmpty(output) ? error : output);
    }
}

这在Visual Studio中的本地计算机上正常运行,但是当我将其部署到服务器(W2K12)时,出现以下错误:

Access is denied   
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)

我在服务器的管理员 IIS_IUSRS 组中都有ExeUsername引用的帐户。

应用程序池以另一个帐户(因此需要分配一个特定的帐户来运行该进程)运行,该帐户也是服务器上Administrators和IIS_IUSRS的成员。

登录服务器并以ExeUsername身份运行命令提示符时,我能够执行该过程,因此问题必须与从IIS执行有关。

还有什么可能阻止此访问?

3 个答案:

答案 0 :(得分:0)

  1. 右键单击applicationpool
  2. 点击高级设置
  3. 身份
  4. 自定义帐户
  5. 设置用户名和密码

如果您拥有域,请小心使用 domain \ username 作为用户名
 并访问部署文件夹。

答案 1 :(得分:0)

我会尝试另一种方法。首先模拟一个自定义用户(有权运行命令的用户),然后在模拟用户的上下文中启动一个进程:

SafeAccessTokenHandle safeAccessTokenHandle;  
bool returnValue = LogonUser(ExeUsername, ExeDomain, ExePassword,  
        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,  
        out safeAccessTokenHandle);

if (false == returnValue)  
{  
    int ret = Marshal.GetLastWin32Error();  
    throw new System.ComponentModel.Win32Exception(ret);  
}  

WindowsIdentity.RunImpersonated(safeAccessTokenHandle, () =>  
{  
     var startInfo = new ProcessStartInfo()
     {
         FileName = ExeLocation,
         Arguments = string.Format("\"{0}\"{1}", ScriptLocation, Arguments),
         UseShellExecute = false,
         RedirectStandardOutput = true,
         RedirectStandardError = true,
         WorkingDirectory = AppDir,
         CreateNoWindow = true,
         UserName = ExeUsername,
         Password = ExePassword,
         Domain = ExeDomain
     };

     using (Process process = Process.Start(startInfo))
     {
         using (StreamReader reader = process.StandardOutput)
         {
             output = reader.ReadToEnd();
         }

         using (StreamReader reader = process.StandardError)
         {
             error = reader.ReadToEnd();
         }

         process.WaitForExit();
         if (process.ExitCode != 0)
         {
             throw new Exception(string.IsNullOrEmpty(output) ? error : output);
         }
     } 
);  

LogonUser方法如下所示:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]  
public static extern bool LogonUser(String lpszUsername, String lpszDomain, 
String lpszPassword, int dwLogonType, int dwLogonProvider, 
out SafeAccessTokenHandle phToken);

有关在.NET中模拟的更多信息,请访问:https://docs.microsoft.com/en-gb/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=netframework-4.7.2

答案 2 :(得分:0)

也许使用此功能对您有帮助。

ProcessStartInfo startInfo = new ProcessStartInfo()
{
   //...
   UseShellExecute = true,                
   Verb = "runas"
};

如果遇到错误,也可以检查this