Starting a console application from asp.net using

2019-06-07 00:25发布

问题:

I have the following asynchronous controller actions which allows me to start a console application on a remote server. My issue is with regards to the permissions and authentication. I have tried the following, which in my understanding allows the app.Start(valuationDate) to run as the impersonated user. The reason for this is that the console application needs to access network resources and the user of this web app will have the required access rights. (As a side note, the console app runs as a scheduled task without error)

The issue I suspect is that the console app is still run under the IIS app pool identity which causes network resource "Access Denied" errors. The console application itself starts, but the restricted access of the IIS user account causes the failure.

I have tried changing the AppPool identity to run as an authorised user and the process executes correctly. I am hoping for a solution that does not require me to change the AppPool identity on the server.

How can I do to start the console application using the authenticated users details?

Controller Actions:

[HttpPost]
public void RunAsync(DateTime valuationDate)
{
    AsyncManager.OutstandingOperations.Increment();
    Task.Factory.StartNew(() => RunApp(valuationDate));
}

private void RunApp(DateTime valuationDate)
    {
        ConsoleWrapper app = new ConsoleWrapper();
        WindowsIdentity winId = (WindowsIdentity)HttpContext.User.Identity;           
        WindowsImpersonationContext ctx = null;
        try
        {
            ctx = winId.Impersonate();
            app.Start(valuationDate);
        }
        catch (Exception e)
        {
            throw;
        }
        finally
        {

            if (ctx != null) {ctx.Undo();}

        }
        AsyncManager.Parameters["success"] = app.Success();
        AsyncManager.Parameters["message"] = app.Message();
        AsyncManager.OutstandingOperations.Decrement();
    }

ConsoleWrapper:

public void Start(DateTime valuationDate)
    {
        var appExe = Config.Default.CONSOLE_APP;
        InProgress = true;
        log = String.Empty;
        success = false;
        message = String.Empty;

        try
        {
            var process = new Process();
            process.StartInfo.FileName = appExe;
            process.StartInfo.Arguments = valuationDate.ToString("dd-MMM-yyyy");

            process.EnableRaisingEvents = true;

            process.StartInfo.UseShellExecute = true;
            process.StartInfo.RedirectStandardOutput = true;

            process.Exited += new EventHandler(process_Exited);
            process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
            process.Start();
            process.WaitForExit();

        }
        catch (Exception e){/* snip */}

    }

回答1:

If you are using Windows Authentication and the application you are trying to run is located on a remote server you need delegation and not impersonation:

To access a network resource, you need to delegate-level token. To get this token type, your server needs to be configured as trusted for delegation in Active Directory.

You may also checkout the following KB. And yet another article on MSDN.

Another possibility is to have some generic account that will be always used for running the console application.