Welcome Guest Search | Active Topics | Sign In | Register

Error 401.2 with windows integrated authentication Options
lostfish
Posted: Wednesday, June 7, 2017 11:30:44 AM
Rank: Member
Groups: Member

Joined: 6/7/2017
Posts: 13
Hi! EO.Pdf solves almost all my problems, however one showstopper remains:

I need to be able to run EO.Pdf on a server that has Windows Integrated Authentication enabled, and EO.Pdf needs to be able to call an html file locally on that server, and authenticate.

From the documentation this should be possible, however I haven't been able to make it work.

I'm running in an ashx file, the following code can get the html file in question:


Code: C#
using (WebClient client = new WebClient())
            {
                client.UseDefaultCredentials = true;
                string htmlCode = client.DownloadString(url);
            }


So the basic overall access is there, however when I run:


Code: C#
HtmlToPdf.ConvertUrl(url, doc, options);


I get a pdf of the IIS 401.2 error page, instead of the html file.

Any help or pointer or tips would be greatly appreciated, I'm a bit stuck, Cheers!
eo_support
Posted: Wednesday, June 7, 2017 4:22:19 PM
Rank: Administration
Groups: Administration

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

Please check if you have impersonation turned on for your ASP.NET application. The difference between UseDefaultCredentials and our HTML to PDF converter is UseDefaultCredentials uses the credentials for your process (which is the user account under your application pool runs). However HTML to PDF uses the credentials of the calling thread. These two are usually the same unless the code explicitly switches security context, which is what occurs when impersonation is on for an ASP.NET application. In that case ASP.NET will automatically switch to the client user's security context before calling any of your code. You can try to turn it off and see if it works.

If you must have impersonation turned on, try to use the following code and see if it works for you:

Code: C#
//Switch to current security context to the process's security context
WindowsImpersonationContext context = WindowsIdentity.Impersonate(IntPtr.Zero);

//Run the HTML to PDF converter
HtmlToPdf.ConvertUrl(...);

//Undo the previous context switch
context.Undo();


Please let us know if this works for you.

Thanks!
lostfish
Posted: Thursday, June 8, 2017 3:21:35 AM
Rank: Member
Groups: Member

Joined: 6/7/2017
Posts: 13
Thanks for getting back to me!

No luck getting it to work yet unfortunately.

If I enable anonymous access, it works.

I've tried the code as you wrote it, as well as any combination I can think of with impersonation enabled / disabled in IIS, I was running with it disabled originally.

I've tried to go through options with the following code as basis (adding the "ids" string to a header so I can see it in the resulting pdf):

// "c" is the HttpContext for the ashx file
WindowsIdentity wid = (WindowsIdentity)c.User.Identity;

var ids = "," + wid + ", ";
ids += WindowsIdentity.GetCurrent().Name + " ,";

using (WindowsImpersonationContext wic = wid.Impersonate())
{
ids += WindowsIdentity.GetCurrent().Name + " ,";
HtmlToPdf.ConvertUrl(url, doc, options);
}

So I have a HttpContext that's always the client user identity, Thread.CurrentPrincipal.Identity is also the client user identity.

Then there's the WindowsIdentity that can be AppPool user with impersonation disabled, or the client user with impersonation disabled.

I've tried with/without impersonation disabled, and with/without impersonating the HttpContext user, I can see in the header that WindowsIdentity.GetCurrent() is different with impersonation (either through IIS or code).

I'd like to be able to have HtmlToPdf run as the client user. It doesn't seem to make any difference to HtmlToPdf what the current WindowsIdentity is.

Is there something I need to do differently? Do you have a complete example that should "just work" against windows integrated authentication? Or I can cut my own code down to a simple example only with things I can share?

Is threre a way I can "see" what user HtmlToPdf is making the request with, a log or fiddler or debug somewhere, something?
lostfish
Posted: Thursday, June 8, 2017 5:33:36 AM
Rank: Member
Groups: Member

Joined: 6/7/2017
Posts: 13
I made a test setup just to isolate things a bit, I guess it's something simple I'm doing wrong or misunderstanding.

I'm running IIS 8.5 on windows 2012 server

I set up a new website with only windows integrated authentication enabled, no web.config, and only the EO dll's in bin, with the following files:

pdf.ashx

Code: C#
<%@ WebHandler Language="C#" Class="pdf" %>
using System.IO;
using System.Web;
using EO.Pdf;

public class pdf : IHttpHandler
{
    public void ProcessRequest(HttpContext c)
    {
        var doc = new PdfDocument();

        HtmlToPdf.ConvertUrl("http://localhost/pdf.html", doc);

        var memoryStream = new MemoryStream();
        doc.Save(memoryStream);
        c.Response.AddHeader("Content-Type", "application/pdf");
        c.Response.BinaryWrite(memoryStream.ToArray());
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}


and the html pdf.html:

Code: HTML/ASPX
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>pdf document</p>
</body>
</html>


That doesn't work, when opening pdf.ashx in a browser, I get a pdf with the 401.2 error page.

When opening pdf.html in a browser, I see the html, no error, so authentication is working, and it's all running locally.

What do I need to do to get HtmlToPdf to authenticate with the user from the HttpContext?

c.User.Identity.Name is the client user

WindowsIdentity.GetCurrent().Name is the app pool user

Thread.CurrentPrincipal.Identity.Name is the client user

should any of that be different?
eo_support
Posted: Thursday, June 8, 2017 6:20:23 PM
Rank: Administration
Groups: Administration

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

First please check which version you are using. Our early versions did not support integrated authentication.

In the current build, we use WindowsIdentity.GetCurrent. You can verify this by using our EOPdfDemo application on your client machine to convert pdf.html directly. It should work for you because EOPdfDemo automatically uses your current login user's identity.

When you call it from a Web application, you have to make sure WindowsIdentity.GetCurrent returns the desired user, which usually means you should have impersonating on.

Thanks!
lostfish
Posted: Friday, June 9, 2017 11:12:49 AM
Rank: Member
Groups: Member

Joined: 6/7/2017
Posts: 13
Hi,

Thanks for your help!

I can get it to work in the test environment using (code) impersonation!

I can't get it to work on my development machine, but that's less of an issue as long as it works in test/production.

On the development machine with webapp running on localhost, integrated authentication turned on, the webapp making a request to itself (localhost), it just doesn't work.

I've tried with your example (the c# web htmltopdf samples), and with my own code, with any combination of impersonation or not, it doesn't work for me :/

If you have an idea why it doesn't work on localhost, I'd love to hear, but as long as it works as it does now in test, I'm ok.

Thanks again for the support!
eo_support
Posted: Wednesday, June 14, 2017 4:02:10 PM
Rank: Administration
Groups: Administration

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

We have done some research on this and it seems that this behavior is by design. Microsoft implemented a "loopback check" that is meant to prevent reflection attack. As a result, challenge/response will not occur over a loop back address localhost. You can find more information here:

https://blogs.msdn.microsoft.com/drnick/2008/03/24/getting-caught-by-loopback/

Note that we are not security expert. So if you still have problems with this issue, you may want to search online to see if you can find additional information.

Thanks!
lostfish
Posted: Thursday, June 15, 2017 1:25:49 AM
Rank: Member
Groups: Member

Joined: 6/7/2017
Posts: 13
Thanks for the additional information!

It works fine in test with the test server calling itself on a hostname:port address, so the real problem is solved, I was using localhost because I had some trouble getting integrated authentication to work as expected using a host header locally, but I'm sure there's a way.

Thanks again for your support, it's above and beyond!
eo_support
Posted: Thursday, June 15, 2017 8:47:51 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,225
Glad to hear that. Please feel free to let us know if there is anything else.


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.