简体   繁体   English

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

[英]Access Denied starting process from ASP.NET website

I have an ASP.NET MVC4 website where I'm trying to execute a process on the server. 我有一个ASP.NET MVC4网站,我正在尝试在服务器上执行一个进程。 The code is as follows: 代码如下:

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

This works fine on my local machine in Visual Studio, but when I deployed to my server (W2K12) I get the following error: 这在Visual Studio中的本地计算机上工作正常,但是当我部署到我的服务器(W2K12)时,我收到以下错误:

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

I have the account referenced by ExeUsername in both the Administrators and IIS_IUSRS groups on the server. 我在服务器上的AdministratorsIIS_IUSRS组中都有ExeUsername引用的帐户。

The application pool is running as a different account (hence the need to assign a specific account to run the process) which is also a member of Administrators and IIS_IUSRS on the server. 应用程序池作为另一个帐户运行(因此需要分配特定帐户来运行该进程),该帐户也是服务器上Administrators和IIS_IUSRS的成员。

When I log into the server and run a command prompt as ExeUsername , I am able to execute the process, so the issue must be related to executing from IIS. 当我登录服务器并以ExeUsername运行命令提示符时,我能够执行该过程,因此该问题必须与从IIS执行相关。

What else could be blocking this access? 还有什么可以阻止这种访问?

  1. Right click on applicationpool 右键单击applicationpool
  2. Click on advanced setting 单击高级设置
  3. Identity 身分
  4. Custom Account 自定义帐户
  5. Set username and password 设置用户名和密码

If you have domain be careful use domain\\username for username 如果您有域名,请小心使用domain \\ username作为用户名
and also access to folder of deployment. 并且还可以访问部署文件夹。

I'd try a different approach. 我会尝试不同的方法。 Firstly impersonate a custom user (the one that has permission to run a command) and then start a process within the context of impersonated user: 首先模拟自定义用户(具有运行命令权限的用户),然后在模拟用户的上下文中启动进程:

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

And the LogonUser method looks like this: 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);

More info about impersonating in .NET is here: https://docs.microsoft.com/en-gb/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=netframework-4.7.2 有关在.NET中进行模拟的更多信息,请访问: https//docs.microsoft.com/en-gb/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view = networkframe-4.7.2

Maybe using this helps you. 也许使用它可以帮助你。

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

If you get an error you can check this also. 如果你得到一个错误,你可以检查也。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM