How to Render Authenticated Web Pages to PDF with Cookies in C#
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");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")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");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")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 }
};Imports System.Collections.Generic
renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
{"auth_token", jwt},
{"refresh_token", refreshToken}
}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(Of String, String) From {
{"locale", "en-AU"},
{"currency", "AUD"},
{"feature_newLayout", "on"}
}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");
}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")
NextConcurrent rendering without cookie bleed
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);
});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)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.

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.