使用经过身份验证的用户凭据从 asp.net 启动控制台应用程序

Posted

技术标签:

【中文标题】使用经过身份验证的用户凭据从 asp.net 启动控制台应用程序【英文标题】:Starting a console application from asp.net using authenticated user credentials 【发布时间】:2011-03-09 06:33:27 【问题描述】:

我有以下异步控制器操作,允许我在远程服务器上启动控制台应用程序。我的问题是关于权限和身份验证。我尝试了以下方法,据我了解,它允许app.Start(valuationDate) 以模拟用户身份运行。这样做的原因是控制台应用程序需要访问网络资源,并且此 Web 应用程序的用户将拥有所需的访问权限。 (附带说明,控制台应用程序作为计划任务运行而不会出错)

我怀疑的问题是控制台应用程序仍在 IIS 应用程序池标识下运行,这会导致网络资源“拒绝访问”错误。控制台应用程序本身启动,但 IIS 用户帐户的受限访问导致失败。

我已尝试将 AppPool 身份更改为以授权用户身份运行,并且该过程正确执行。我希望有一个不需要我更改服务器上的 AppPool 身份的解决方案。

如何使用经过身份验证的用户详细信息启动控制台应用程序?

控制器操作:

[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】:

如果您使用的是 Windows 身份验证,并且您尝试运行的应用程序位于远程服务器上,则您需要 delegation 而不是模拟:

要访问网络资源,您 需要委托级别的令牌。要得到 这种令牌类型,您的服务器需要 配置为受信任的 Active Directory 中的委派。

您也可以查看following KB。还有一个article on MSDN。

另一种可能性是拥有一些将始终用于运行控制台应用程序的通用帐户。

【讨论】:

除了委托还有其他方法吗?也许从程序化的角度来看? @Ahmad,您可以通过编程方式执行此操作,但您需要知道客户端的密码,我认为这不是您的情况。如果您不知道您需要设置委托的密码。另一种可能性是拥有一些将始终用于运行控制台应用程序的通用帐户。 谢谢 darin,我也这么想。我可能会坚持使用域帐户/AppPool 组合,因为它目前似乎是最简单的。我将测试委派选项,但担心 IT 部门可能会阻碍进展。 如果您使用评论的第二部分更新您的答案,我可以将其标记为已接受...

以上是关于使用经过身份验证的用户凭据从 asp.net 启动控制台应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 asp.net 中使用 Windows 身份验证获取用户名?

ASP.NET Windows 身份验证仅提示一个用户的凭据

ASP.NET Core Web API 身份验证

从 ASP.NET/Blazor 服务器中的当前经过身份验证的用户获取数据

ASP.NET Web API 身份验证

Asp.net 身份验证方式?