Welcome Guest Search | Active Topics | Sign In | Register

HTML to PDF conversion returning 401.2 unauthorized Options
Canvas Tech
Posted: Wednesday, February 13, 2019 1:29:02 PM
Rank: Newbie
Groups: Member

Joined: 7/23/2018
Posts: 6
Hi Team,

we recently created two new Windows Servers to host EO library to convert html to PDF. We are getting 401.2 unauthorized error when trying to convert html to PDF when using any URL that requires windows authentication. We currently have 4 servers where the library is working as expected.

We moved the code to a test class to be shared to isolate the problem. We only see an issue when we are trying to access a website that requires windows authentication.



This apps are installed under IIS8, using integrated app pool. We have been comparing the settings between working env vs non working and we haven't been able to pinpoint the issue.

Working machine is running under OS Windows Server 12, non working machine is running on Windows Server 2016. We've been working with our networking team and we haven't yet found the root cause of the problem. IIS settings ( App pool, Website and web app) are the same for the new servers.


We wanted to understand further what settings do we need to have enabled to make windows authentication work internally once chromium launches and tries to connect to the URL. Another interesting fact is , running this code as a test class (logging in to the server and executing) works fine. I believe it's because it's taking the credentials from the logged in user.

Please let us know if you have any thoughts on what we can verify.



Sample code ( Removed license settings). This can be called by passing a url as parameter. Like : Test.aspx?url=http://www.google.com


Code: HTML/ASPX
<%@ Page Language="c#" AutoEventWireup="true"  %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Net.Mail" %>
<%@ Import Namespace="System.Net.Mime" %>
<%@ Import Namespace="System.Windows" %>

<%@ Import Namespace="System.Windows.Forms" %>
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Threading.Tasks" %>
<%@ Import Namespace="EO.Pdf" %>

<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Threading" %>
<%@ Import Namespace="System.Net" %>



<script runat="server">

  public string ss2(){
  
	 var url = Request.QueryString["url"] ;
	 var mode = String.IsNullOrEmpty(Request.QueryString["both"]) ? "" : Request.QueryString["both"] ;
	 
	 WebRequest request = WebRequest.Create (url);  
	// Set the Method property of the request to POST.  
	request.Method = "GET";  
	 request.Credentials = CredentialCache.DefaultCredentials;
	 // Get the response.
	 HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
	 
	 string responseText = "";
	 var encoding = ASCIIEncoding.ASCII;
	 using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
	 {
					 responseText = reader.ReadToEnd();
	 }

	 return response.StatusDescription + " : " + responseText;
  
  }


  public string ServerSideFunction()
  {
   
                if(!String.IsNullOrEmpty(Request.QueryString["web"])) {
                                return ss2();
                }
   
				var url = Request.QueryString["url"] ;
				var mode = String.IsNullOrEmpty(Request.QueryString["both"]) ? "" : Request.QueryString["both"] ;
                
				EO.Pdf.Runtime.AddLicense("Add License here");
	
				EO.WebBrowser.Runtime.AddLicense("Add License here");
                                
                //Creates new HTML options used by EO
                HtmlToPdfOptions op = new HtmlToPdfOptions();
                //Printing in 8.5 inch by 11 inch. Later on we will change the width and height according to landscape or portrait.
                //This is an alternative to calling the library multiple times based on page orientation and merge pages.
                op.PageSize = new SizeF(8.5f, 11.69f);
                // Output area for printing should be 8.5 by 11.69
                op.OutputArea = new RectangleF(0, 0, 8.5f, 11.69f);
                //We will manually execute the rendering once all network calls are done. This is controlled in the url we are calling on the javascript.(eopdf.convert())
                if(!String.IsNullOrEmpty(mode)) {
                                op.TriggerMode = HtmlToPdfTriggerMode.Dual;
                }
                
                //Prevent use of cache
                HtmlToPdf.Options.NoCache = true;
				
                //Lowering quality of images so that conversion will be faster
                HtmlToPdf.Options.JpegQualityLevel = 100;

                //1 min until conversion returns if no success
                HtmlToPdf.Options.MaxLoadWaitTime = 60000;

                //Improve performance by not returning node content.
                HtmlToPdf.Options.RetrieveNodeText = false;

                MemoryStream ms = new MemoryStream();

                HtmlToPdf.ConvertUrl(url, ms, op);
                
                HtmlToPdf.ClearResult();
                
                HttpResponse response = HttpContext.Current.Response;
                Response.Clear();
                Response.ContentType = "application/pdf";
                ms.WriteTo(Response.OutputStream); //works too
                Response.Flush();
                Response.Close();
                
                return "success";
                    
  }
</script>


<script language="CS" runat="server"> 
protected override void OnLoad(System.EventArgs e)  
{      
   //ServerSideFunction(url, triggermode);
   // do some stuff in addition to the original Page_Load method 
} 
</script> 

<% string pageVariable = "world"; %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title>ASP.NET inline</title>
</head>
<body>
Running
<%=ServerSideFunction()%>

</body>
</html>
eo_support
Posted: Wednesday, February 13, 2019 3:47:54 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

Please check the calling thread's identity --- that's the identity of the converter use. For example, you can check the result of WindowsIdentity.GetCurrent() immediately before calling HtmlToPdf.ConvertUrl in your code. The user returned by WindowsIdentity.GetCurrent() immediately before HtmlToPdf.ConvertUrl is the user the HTML to PDF converter uses to authenticate with your web server.

Thanks!
Canvas Tech
Posted: Wednesday, February 13, 2019 5:33:42 PM
Rank: Newbie
Groups: Member

Joined: 7/23/2018
Posts: 6
Hi,

thank you for your reply.

We do have both WindowsIdentity.GetCurrent().Name and Thread.CurrentPrincipal.Identity.Name authenticated. The code I added above looks to be working fine on our other boxes but not on the new servers.

Once the conversion starts, we lose trace of the http call, we can see from the iis logs on the other side that the userid is coming as empty.

Is there any other settings on the iis level or server that we need to set for this to work with windows auth?

Thank you!
eo_support
Posted: Thursday, February 14, 2019 11:14:18 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

I am not sure what else we can tell you since we are not Windows security experts. The only thing we can tell you is we use WindowsIdentity.GetCurrent().Token to get the current user token, then everything is based on this user token when accessing network resources. We do not know exactly what options would affect whether this user token has access to the actual resource or how it controls it. You will have to consult your network administrator on such matters.

Thanks!
Canvas Tech
Posted: Wednesday, March 13, 2019 1:53:23 PM
Rank: Newbie
Groups: Member

Joined: 7/23/2018
Posts: 6
Hi how are you? We were able to bypass this problem by setting the user and password on the options of HTMLToPDF. Definitely there is something off in the IIS settings because we have the same code working in 2 servers but doesn't work in recently created servers.

Solution is not ideal but we were able to get it working like this.

Thanks.
eo_support
Posted: Friday, March 15, 2019 11:06:58 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Glad that you got it working. Setting HtmlToPdf.Options.UserName and Password uses the basic HTTP authentication, not Windows authentication. So this probably means that basic Authentication is working with your IIS but not Windows authentication. As such that might be where you want to look should you want to investigate this issue further.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.