Troubleshooting cookie problems in ASP.NET Core
Having answered over 1000 questions on Stack Overflow, I’ve found that cookie-related issues are a frequent challenge for developers using ASP.NET Core, especially when implementing authentication and OpenID Connect.
Cookie problems can, in my experience, be categorized into the following categories:
- Browser Rejection
Cookies provided by the server that aren’t accepted by the browser. - Browser Omission
Cookies in the browser are not included in requests to the server. - Lost cookies
Cookies that are lost on the way to the server.
In this post, we’ll explore common ASP.NET Core cookie problems—such as browser rejection, missing cookies in requests, and lost cookies. You’ll learn practical tips to identify, diagnose, and resolve these issues, ensuring smoother authentication flows and a more reliable application experience.
Cookies rejected by the browser
When setting a cookie, we use the set-cookie response header, often accompanied by the secure and samesite attributes. Below is an example illustrating the setting of five common cookies:
HTTP/1.1 200 OK
Set-Cookie: NormalCookie=NormalValue;Path=/
Set-Cookie: NormalCookieWitSecure=NormalValueSecure;Path=/;secure
Set-Cookie: StrictCookie=StrictValue;Path=/;SameSite=Strict
Set-Cookie: LaxCookie=LaxValue;Path=/;SameSite=Lax
Set-Cookie: NoneCookie=NoneValue;Path=/;SameSite=None;Secure
…
(Note: This article will not discuss the details of the path, domain, and the HttpOnly attribute. The HttpOnly attribute is all about restricting JavaScript from accessing cookies.). I recommend setting the HttpOnly attribute on every cookie that never needs to be accessed by JavaScript.
How can I tell if the browser accepts a cookie?
The first step in troubleshooting cookie problems is to verify that the browser has accepted the cookie.
To see which cookies it has received and accepted, open the browser developer tools (F12) in Chrome and look under Application -> Storage -> Cookies.
If the expected cookies are not found here, then head over to the Network tab, locate the request that sets the cookie, and then click on the Cookies sub-tab:
Rejected cookies are highlighted in yellow. Hovering over the information (i) icon displays reasons for the blockage. As shown in the example below:
You can also activate the “Has blocked cookies” checkbox to only show requests with blocked response cookies.
Some of the most common reasons for blocking are:
- Using samesite=none without the secure attribute
- Trying to set a cookie with the secure attribute over HTTP://
- Too large cookies; keep the cookie size below 4000 bytes for maximum browser compatibility.
Cookies not included in requests
If you have concluded that the browser has accepted the cookie and it is found under Application -> Storage, great! One step forward! What’s next?
There are a few reasons why the browser might decide not to include cookies in outgoing requests:
Some of the reasons for blocking are:
- Protocol Mismatch
Cookies with the secure attribute will not be included in requests over HTTP. Incorrect samesite
For cross-site requests, you must use:samesite=none;secure when you need to support GET & POST in requests to another site
samesite=lax when you only need to support GET requests across sites.
Cross-Origin Resource Sharing (CORS)
We won’t go into CORS in this blog post. CORS can be problematic when you do API requests from JavaScript using the XMLHttpRequest or Fetch APIs.
Under the network tab, you can see why a cookie was not included in the request, as shown in the example below:
Common SameSite Cookie Problems
Some of the common samesite problems that I see are:
- SameSite=none cookies
Cookies set with the samesite=none attribute must also be marked with the secure attribute. This means that they must always be used over HTTPS, a common problem, for example, when working with OpenID Connect. - Missing samesite header?
All cookies that you set should have a samesite attribute. Otherwise, you might end up with unexpected issues where browsers will start to block them in certain circumstances.For example, Firefox writes this warning to the console when you try to set a cookie without a valid samesite attribute:
Cookie “NormalCookie” does not have a proper “SameSite” attribute value. Soon, cookies without the “SameSite” attribute or with an invalid value will be treated as “Lax”. This means that the cookie will no longer be sent in third-party contexts. If your application depends on this cookie being available in such contexts, please add the “SameSite=None“ attribute to it. To know more about the “SameSite“ attribute, read https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite |
Which samesite value should you use?
Some guidance about what value to use:
- Strict
Use this value for cookies that should only be used within the same site. For example, consider using this value for your session cookie. Using strict cookies provides the maximum protection against Cross-Site Requests. - Lax
This is the new default for cookies, which only includes the cookie GET requests across sites. - None
Use this value for cookies that should be included in all site requests. This value must be set together with the secure attribute. This is the least secure option. This makes the cookies behave like they behaved before the samesite concept was introduced.
Cookies in ASP.NET Core
What can go wrong when we use cookies in ASP.NET Core?
When you use the cookie authentication handler, the default session cookie is set as follows:
Set-Cookie: .AspNetCore.Cookies=xxxxxxx; path=/; secure; samesite=lax; httponly
This is a sensible default. You might be tempted to set the session cookie to samesite=strict, as follows:
builder.Services.AddAuthentication()
.AddCookie(opt =>
{
opt.Cookie.SameSite = SameSiteMode.Strict;
});
If you just use local authentication (like ASP.NET Core Identity), that is usually fine. But, when you use it together with OpenID Connect, you will have problems, as shown in the image below:
OpenID Connect, cookies, and IdentityServer
When you work with OpenID Connect, plenty of cookies will be involved. For example, if you use Duende IdentityServer, then the following cookies are involved during authentication:
Not properly configuring and understanding these cookies is a common source of problems.
Same domain but different ports
You might think that when you have multiple sites on the same domain but on different ports, they would have separate cookie jars:
But it turns out that they will all share the same cookie jar. The cookies are tied to the domain, not the port or scheme.
Summary
I hope the steps outlined above can help you troubleshoot your cookie problems. Here are some tips for healthier and more secure cookies:
- Always use HTTPS
Most cookie problems will go away when you move your traffic to HTTPS. Using HTTPS today is also a must If you care about security. - Set samesite
Always add the correct samesite attribute; this is a must today. - Add the secure and HttpOny attribute
Securing our cookies and all sensitive cookies should always have these two attributes set. - Do research the path and domain attributes
They can be used to further restrict to what domain (including sub-domains) and path the cookies should be included on.
Feedback, comments, found any bugs?
Let me know if you have any feedback, anything I missed, or any bugs/typos. You can find my contact details here.
About the author
Hi, I’m Tore! I have been fascinated by computers since I unpacked my first Commodore VIC-20. Today, I enjoy providing freelance development and developer training services, focusing on ASP.NET Core, IdentityServer, OpenID Connect, Architecture, and Web Security. You can connect with me on LinkedIn and Twitter, and you can find out more about me and my services here, as well as my courses for developers, including my course, Introduction to IdentityServer and OpenID-Connect.
Cookie resources
- Tips for testing and debugging SameSite-by-default and “SameSite=None; Secure” cookies
- SameSite cookie recipes
- SameSite cookies explained
- Changes to SameSite Cookie Behavior – A Call to Action for Web Developers
- Handle SameSite cookie changes in Chrome browser
- Work with SameSite cookies in ASP.NET
- Understanding “same-site” and “same-origin”
Tore’s Newsletter
Be the First to Know! Get notified about my latest blog posts, upcoming presentations, webinars, and more — subscribe today!