Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emulate ASP.NET authentication cookie

I maintain an ASP.NET MVC website that uses

FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);

to sign users in (they end up with a cookie named .ASPXAUTH).

The client wants me to add an HTML to PDF feature, so I'm wrapping the wkhtmltopdf library and calling that. This ends up being a command that looks like this:

wkhtmltopdf http://example.com/Foo/Edit/42 Foo.pdf

However, that results in making a PDF of the login screen, as the wkhtmltopdf user agent is redirected since it doesn't have the correct cookie.

That's fine since, according to the wkhtmltopdf documentation, there's an argument like this:

--cookie <name> <value>         Set an additional cookie (repeatable)

So I modify the command to be:

wkhtmltopdf --cookie .ASPXAUTH 91C0DE4C...  http://example.com/Foo/Edit/42 Foo.pdf

Where the cookie value is retrieved using Request.Cookie[".ASPXAUTH"].Value.

Unfortunately, this doesn't seem to work and I have no idea why. I know that ASP.NET is receiving the cookie because when I breakpoint the login page after the redirect, I can see that it's been set. So why does ASP.NET not accept my copied cookie?

Here's the contents of a request that ASP.NET allows (from Chrome):

GET http://localhost:50189/ReportingMonth/Edit/1193391 HTTP/1.1
Host: localhost:50189
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-CA,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: .ASPXAUTH=C8189041BF69FEF89A834B6F5035B786EC40145FFFBA3DBB6A04973BC58021C73D8D374E3577AA44BC26A784BC8A0C24831CF49FBD596BFFBA42C613E3C2C0C893D1587B7743D051643088BB8BAB667C047E0D1B84D7B76C4AADA7C62AB460D87C954BF9118BF5945E7D325D455CFD13A34C3DD5E597AFDF75D3C8EE76D8488B08ABBF6AE065B4C57CE47CB65AB17D65; language=en; ui-tabs-[object Object]=0

And here's one that it redirects to the login (from wkhtmltopdf):

GET http://localhost:50189/ReportingMonth/Edit/1193391 HTTP/1.1
Cookie: .ASPXAUTH=C8189041BF69FEF89A834B6F5035B786EC40145FFFBA3DBB6A04973BC58021C73D8D374E3577AA44BC26A784BC8A0C24831CF49FBD596BFFBA42C613E3C2C0C893D1587B7743D051643088BB8BAB667C047E0D1B84D7B76C4AADA7C62AB460D87C954BF9118BF5945E7D325D455CFD13A34C3DD5E597AFDF75D3C8EE76D8488B08ABBF6AE065B4C57CE47CB65AB17D65
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.3 (KHTML, like Gecko) Qt/4.7.1 Safari/533.3
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Connection: Keep-Alive
Accept-Encoding: gzip
Accept-Language: en-US,*
Host: localhost:50189
like image 582
cdmckay Avatar asked Sep 21 '11 06:09

cdmckay


2 Answers

I found the problem. I noticed that once I changed the User-Agent field (in Fiddler) to be the same as Chrome, it worked fine. So I did a little web sleuthing and discovered this bug on the wkhtmltopdf project page.

From the bug:

This is an issue under ASP .NET 4.0 as it seems that .NET interprets the User-Agent string "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-AU) AppleWebKit/532.4 (KHTML, like Gecko) Qt/4.6.1 Safari/532.4" as not supporting cookies which I think is preventing the --cookie option from working under ASP.

So it looks like the solution is either figuring out a way to make wkhtmltopdf change it's User-Agent header (not looking promising) or figure out a way to tell ASP.NET that that user agent does support cookies.

Thanks for you help Darin Dimitrov.

Update

Ok, I figured out how to tell ASP.NET that the Qt web browser used by wkhtmltopdf supports cookies. You need to create a file called qt.browser and save it in a directory callde App_Browsers in the root of your ASP.NET project. Here's what you put in the qt.browser file:

<browsers>
    <!-- Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/530.1 (KHTML, like Gecko) Qt/4.7.1 Safari/530.1 -->
    <browser id="Qt" parentID="Safari">
        <identification>
            <userAgent match="Qt/(?'version'(?'major'\d+)(\.(?'minor'\d+)?)\w*)" />
        </identification>       

        <capabilities>
            <capability name="browser"                         value="Qt" />
            <capability name="version"                         value="${version}" />
            <capability name="majorversion"                    value="${major}" />
            <capability name="minorversion"                    value="${minor}" />
            <capability name="type"                            value="Qt${major}" />
            <capability name="ecmascriptversion"               value="3.0" />
            <capability name="javascript"                      value="true" />
            <capability name="javascriptversion"               value="1.7" />
            <capability name="w3cdomversion"                   value="1.0" />
            <capability name="tagwriter"                       value="System.Web.UI.HtmlTextWriter" />
            <capability name="cookies"                         value="true" />
            <capability name="frames"                          value="true" />
            <capability name="javaapplets"                     value="true" />
            <capability name="supportsAccesskeyAttribute"      value="true" />
            <capability name="supportsCallback"                value="true" />
            <capability name="supportsDivNoWrap"               value="false" />
            <capability name="supportsFileUpload"              value="true" />
            <capability name="supportsMaintainScrollPositionOnPostback" value="true" />
            <capability name="supportsMultilineTextBoxDisplay" value="true" />
            <capability name="supportsXmlHttp"                 value="true" />
            <capability name="tables"                          value="true" />
        </capabilities>
    </browser>
</browsers>

Then re-compile your project (and maybe restart your server if you can) and then presto, you can emulate the ASP.NET authentication cookie!

like image 148
cdmckay Avatar answered Oct 21 '22 23:10

cdmckay


Looks like a bug and there seems to be a fix in the trunk.

like image 2
Darin Dimitrov Avatar answered Oct 22 '22 01:10

Darin Dimitrov