正在运行具有当前凭据的进程

本文关键字:进程 运行 | 更新日期: 2023-09-27 18:11:03

我正在开发一个Umbraco内部网站点,在那里我调用wkhtmltopdf.exe来创建一些pdf。这些pdf使用一个主页作为内容,另外两个页面作为页眉和页脚。只要我的网站没有身份验证,一切都很顺利。我们希望使用我们的Active Directory帐户登录到网站,因此我启用了windows身份验证。运行它的例程是单击一个按钮,该按钮处理页面并在浏览器上显示pdf或下载它。在任何情况下都是相同的过程。在visual studio中,当运行调试时,当涉及到代码的第一部分(var p =…)时,它会抛出一个异常"Message = "No process is associated with this object."因为它无法进行身份验证。当我在执行完代码并使用visual studio检查器暂停代码时,我可以看到这一点。该方法运行到最后,但由于我之前提到的错误,它产生一个空白的pdf。如果我硬编码用户名和密码,那么它工作良好。

站点在iis express中运行在我的本地开发环境中。由于Windows身份验证是启用时,我浏览到网站的第一次我必须登录。Wkhtmltopdf.exe位于本地驱动器-它不在网站上。初始设置是基于这里描述的方法http://icanmakethiswork.blogspot.se/2012/04/making-pdfs-from-html-in-c-using.html只有属于我们的Active Directory域的用户才能访问网站,但由于我们使用相同的帐户登录到windows,那么windows身份验证将会起作用:)

public static void HtmlToPdf(string outputFilename, string[] urls, 
        string[] options = null,
        bool streamPdf = false,
        string pdfHtmlToPdfExePath = "C:''Program Files (x86)''wkhtmltopdf''bin''wkhtmltopdf.exe")
    {
        string urlsSeparatedBySpaces = string.Empty;
        try
        {
            //Determine inputs
            if ((urls == null) || (urls.Length == 0))
            {
                throw new Exception("No input URLs provided for HtmlToPdf");
            }
            urlsSeparatedBySpaces = String.Join(" ", urls); //Concatenate URLs

            var p = new System.Diagnostics.Process()
            {
                StartInfo =
                {
                    FileName = pdfHtmlToPdfExePath,
                    Arguments = ((options == null) ? "" : String.Join(" ", options)) + " "  + urlsSeparatedBySpaces + " -",
                    UseShellExecute = false, // needs to be false in order to redirect output
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true, // redirect all 3, as it should be all 3 or none
                    WorkingDirectory = string.Empty
                }
            };
            p.Start();
            var output = p.StandardOutput.ReadToEnd();
            byte[] buffer = p.StandardOutput.CurrentEncoding.GetBytes(output);
            p.WaitForExit(60000);
            p.Close();
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = "application/pdf";
            if (!streamPdf)
            {
                HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename='" + outputFilename + "'");
            }
            HttpContext.Current.Response.BinaryWrite(buffer);
            HttpContext.Current.Response.End();
        }
        catch (Exception exc)
        {
            throw new Exception("Problem generating PDF from HTML, URLs: " + urlsSeparatedBySpaces + ", outputFilename: " + outputFilename, exc);
        }
    }

我用LoadUserProfile = true测试了这个,但这也没有帮助。在阅读了各种论坛帖子后,我看到的唯一建议的解决方案是通过使用用户名,密码等强制登录。但这很糟糕,因为用户已经登录,我们可以/应该使用像CredentialCache这样的东西。DefaultCredentials .

我来的一个解决方案是在请求中使用DefaultCredentials将html保存在本地,在那里我可以毫无问题地访问它们并创建pdf,但即使这是一个艰苦的过程,因为我需要创建可打印的css和javascript并下载它们等。这是我的最后一个解决方案,我已经实施了80%,但似乎也很讨厌。下面是我抓取网页的另一个代码示例。

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Credentials = CredentialCache.DefaultCredentials;
        var response = (HttpWebResponse)request.GetResponse();
        var stream = response.GetResponseStream();

总结一下。Wkhtmltopdf无法对自己进行身份验证,因此它无法获取所需的页面并将其转换为pdf。是否有一种简洁的方法可以使进程能够使用我登录到站点的当前用户凭据对自己进行身份验证,以便它可以访问页面?

正在运行具有当前凭据的进程

我使用Rotativa包装Wkhtmltopdf.

为了让它在iis上工作,我创建了一个单独的用户帐户,具有足够的访问权限来运行Wkhtmltopdf.exe。然后传递用户名&Wkhtmltopdf密码

public virtual ActionResult PrintInvoice(int id) {
        var invoice = db.Invoices.Single(i => i.InvoiceId == id);
        var viewmodel = Mapper.Map<InvoiceViewModel>(invoice);
        var reportName = string.Format(@"Invoice {0:I-000000}.pdf", invoice.InvoiceNo);
        var switches = String.Format(@" --print-media-type --username {0} --password {1} ", 
                ConfigurationManager.AppSettings["PdfUserName"],
                ConfigurationManager.AppSettings["PdfPassword"]); 
        ViewBag.isPDF = true;
        return new ViewAsPdf("InvoiceDetails", viewmodel) {
            FileName = reportName,
            PageOrientation = Rotativa.Options.Orientation.Portrait,
            PageSize = Rotativa.Options.Size.A4,
            CustomSwitches = switches
        };
    }

在Wkhtmltopdf.exe中运行的页面似乎使用当前用户的凭据运行,但Wkhtmltopdf.exe本身需要在服务器上执行的权限。

这在部署时在iis上工作。在VS2012卡西尼上,它为我工作没有凭证,但在vs2013上的iis express我仍然有麻烦,当它涉及到拾取资源,如css & &;图像。

同样的解决方案在SSL上运行:Rotativa和wkhtmltopdf在iis6上没有CSS或图像,但在HTTP上很好

打开ASP。. NET模拟并在模拟用户的上下文中生成wkhtmltopdf。

注意:打开ASP。. NET模拟很可能会降低性能