Skip to footer content
USING IRONPDF

Render Authenticated Web Pages to PDF Using Cookies

Most HTML-to-PDF jobs break for the same reason: the page only looks right after a user signs in. IronPDF drives a Chrome engine, so it sees what an unauthenticated browser would, a login screen or an empty shell, until you hand it the right cookies. Three pieces of the API solve this, the RequestContext property, the ApplyCookies method, and the CustomCookies dictionary. Here is where each one fits, with a snippet to match.

Rendering invoices and statements behind login

A customer's invoice sits on a session-protected route, and your application already holds their session. Pass that session ID straight through CustomCookies:

using IronPdf;
using System.Collections.Generic;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "ASP.NET_SessionId", sessionId }
};

renderer.RenderUrlAsPdf("https://app.example.com/account/invoices/1042")
        .SaveAs("invoice-1042.pdf");
using IronPdf;
using System.Collections.Generic;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "ASP.NET_SessionId", sessionId }
};

renderer.RenderUrlAsPdf("https://app.example.com/account/invoices/1042")
        .SaveAs("invoice-1042.pdf");
Imports IronPdf
Imports System.Collections.Generic

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global
renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
    {"ASP.NET_SessionId", sessionId}
}

renderer.RenderUrlAsPdf("https://app.example.com/account/invoices/1042").SaveAs("invoice-1042.pdf")
$vbLabelText   $csharpLabel

For basic or Windows authentication, reach for ApplyCookies instead. It signs in at the URL with the supplied credentials and captures the resulting cookies into the global context, which the following render then reuses:

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;

var credentials = new ChromeHttpLoginCredentials
{
    NetworkUsername = "svc_reports",
    NetworkPassword = "your_password"
};

string uri = "https://app.example.com/account/invoices/1042";
renderer.ApplyCookies(uri, credentials);

renderer.RenderUrlAsPdf(uri).SaveAs("invoice-1042.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;

var credentials = new ChromeHttpLoginCredentials
{
    NetworkUsername = "svc_reports",
    NetworkPassword = "your_password"
};

string uri = "https://app.example.com/account/invoices/1042";
renderer.ApplyCookies(uri, credentials);

renderer.RenderUrlAsPdf(uri).SaveAs("invoice-1042.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global

Dim credentials As New ChromeHttpLoginCredentials With {
    .NetworkUsername = "svc_reports",
    .NetworkPassword = "your_password"
}

Dim uri As String = "https://app.example.com/account/invoices/1042"
renderer.ApplyCookies(uri, credentials)

renderer.RenderUrlAsPdf(uri).SaveAs("invoice-1042.pdf")
$vbLabelText   $csharpLabel

Token-based and third-party authentication

Modern apps rarely lean on simple HTTP credentials. They authenticate with JWTs, OAuth, or SAML, often storing the result in a cookie. Since CustomCookies takes any key-value pair, a bearer token or identity-provider cookie drops straight in:

renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "auth_token", jwt },
    { "refresh_token", refreshToken }
};
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "auth_token", jwt },
    { "refresh_token", refreshToken }
};
Imports System.Collections.Generic

renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
    {"auth_token", jwt},
    {"refresh_token", refreshToken}
}
$vbLabelText   $csharpLabel

Personalized and localized documents

Cookies often carry locale, currency, or feature-flag state. Forward them, and the PDF matches what that specific user sees, in the correct language and currency:

renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "locale", "en-AU" },
    { "currency", "AUD" },
    { "feature_newLayout", "on" }
};
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "locale", "en-AU" },
    { "currency", "AUD" },
    { "feature_newLayout", "on" }
};
renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
    {"locale", "en-AU"},
    {"currency", "AUD"},
    {"feature_newLayout", "on"}
}
$vbLabelText   $csharpLabel

Batch generation that shares one session

To generate many PDFs for the same authenticated user in sequence, set RequestContext to Global. The browser state, cookies included, persists across renders, so you authenticate once instead of per document:

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "ASP.NET_SessionId", sessionId }
};

foreach (var id in invoiceIds)
{
    renderer.RenderUrlAsPdf($"https://app.example.com/invoices/{id}")
            .SaveAs($"invoice-{id}.pdf");
}
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Global;
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "ASP.NET_SessionId", sessionId }
};

foreach (var id in invoiceIds)
{
    renderer.RenderUrlAsPdf($"https://app.example.com/invoices/{id}")
            .SaveAs($"invoice-{id}.pdf");
}
Imports IronPdf.Rendering

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.RequestContext = RequestContexts.Global
renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
    {"ASP.NET_SessionId", sessionId}
}

For Each id In invoiceIds
    renderer.RenderUrlAsPdf($"https://app.example.com/invoices/{id}").SaveAs($"invoice-{id}.pdf")
Next
$vbLabelText   $csharpLabel

The opposite scenario carries just as much weight. A service rendering for many different users at once needs Isolated context, which gives each render a clean state and stops one user's session from leaking into another's document. Give every thread its own renderer:

using System.Threading.Tasks;

Parallel.ForEach(jobs, job =>
{
    var renderer = new ChromePdfRenderer();
    renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Isolated;
    renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
    {
        { "ASP.NET_SessionId", job.SessionId }
    };

    renderer.RenderUrlAsPdf(job.Url).SaveAs(job.OutputPath);
});
using System.Threading.Tasks;

Parallel.ForEach(jobs, job =>
{
    var renderer = new ChromePdfRenderer();
    renderer.RenderingOptions.RequestContext = IronPdf.Rendering.RequestContexts.Isolated;
    renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
    {
        { "ASP.NET_SessionId", job.SessionId }
    };

    renderer.RenderUrlAsPdf(job.Url).SaveAs(job.OutputPath);
});
Imports System.Threading.Tasks
Imports IronPdf.Rendering

Parallel.ForEach(jobs, Sub(job)
    Dim renderer = New ChromePdfRenderer()
    renderer.RenderingOptions.RequestContext = RequestContexts.Isolated
    renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
        {"ASP.NET_SessionId", job.SessionId}
    }

    renderer.RenderUrlAsPdf(job.Url).SaveAs(job.OutputPath)
End Sub)
$vbLabelText   $csharpLabel

Matching the method to the job

Use standard cookies (ApplyCookies) for basic HTTP auth, Windows authentication, and simple sessions. Reach for CustomCookies with tokens, multi-parameter sessions, third-party providers, and stored preferences. Pick Global to share state across renders and Isolated to keep them separate; Auto defaults to isolated and switches to global once ApplyCookies is called.

Most failures cluster around expired tokens, mismatched cookie domains, secure-cookie handling on HTTPS URLs, and SameSite policies on cross-origin requests. Confirm cookie validity before rendering, and lean on Global when sessions must persist.

When cookies are the whole job

Cookies are no edge case in PDF generation. Get them right and you ship a usable document; get them wrong and you ship a screenshot of a login form.

Frequently Asked Questions

How do I render a login-protected page as a PDF with IronPDF?

Set RequestContext to Global and populate CustomCookies with the user's session cookie before calling RenderUrlAsPdf. IronPDF's Chrome engine will authenticate with those cookies and render the protected page.

What is the difference between ApplyCookies and CustomCookies in IronPDF?

ApplyCookies signs in using HTTP credentials (basic auth or Windows auth) and captures the resulting session cookies into the global context. CustomCookies lets you supply cookie key-value pairs directly — useful for JWT tokens, OAuth cookies, and multi-parameter sessions.

What is RequestContext and when should I use Global vs Isolated?

Use Global when multiple renders share the same authenticated session (e.g., batch-generating invoices for one user). Use Isolated when rendering for many different users concurrently, so each render gets a clean cookie state and sessions cannot bleed between users.

Can IronPDF handle JWT and OAuth authentication for PDF rendering?

Yes. Pass the token values in CustomCookies as key-value pairs (e.g., auth_token and refresh_token). IronPDF forwards them with every request the Chrome engine makes for that render.

Why does my PDF render as a blank page or login screen?

The most common causes are expired session cookies, mismatched cookie domains, secure-cookie restrictions on HTTPS URLs, and SameSite policy blocks on cross-origin requests. Verify that the cookies are valid and match the target domain before rendering.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me