-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Description
Summary
Create in-box support for Authn with JWT stored in http-only cookies
Motivation and goals
Then we develop SPA application with ASP.NET Core (for ex. with React at frontend) we very often think about how we implement authentication in our application. There is currently two ways to do it: with session cookie, and with JWT. As devs, we prefer to use jwt, because it does not require for a DB lookup.
If we decided to use jwt, there is 3 ways to do request with it:
- Set as authorization header (
Authorization: Bearer <token>
) and store it locally in memory (.AddJwtBearer()
- Set as authorization header (
Authorization: Bearer <token>
) and store it in browser local storage (.AddJwtBearer()
) - Pass jwt token in http-only cookie
The third option is currently the most secure way to pass and store jwt tokens, because we become immutable to XSS attack, because attacker cannot read our token from cookie. Still, we became vulnerable to CSRF, but this we can fix this by providing XSRF token on a client side. By the end of a day, we can see why JWT with http-only secure cookie is preferred as authn solution using jwt's.
However this way is most secure, ASP.NET Core does not provide in-box solution for this, so we need to add custom middleware to any project which uses this technique. Currently, we implement this logic by this sort of middleware:
app.UseCookiePolicy(cookiePolicyOptions); // making cookie http-only, strict, e.t.c
app.Use(async (context, next) =>
{
var token = context.Request.Cookies[".AspNetCore.Application.Id"];
if (!string.IsNullOrEmpty(token))
context.Request.Headers.Add("Authorization", "Bearer " + token);
await next();
});
app.UseAuthentication();
Futhermore, a lot of other tech solutions (such as NextAuth) already have support for this feature.
Goals:
- Create Solution to support JWT in Session token support in-box
In scope
A list of major scenarios, perhaps in priority order.
Out of scope
Scenarios you explicitly want to exclude.
Risks / unknowns
There is security concern, and we need to be careful about reviewing PR for this. Also,
Examples
Design proposal No.1: New middleware
We can add new middleware, which will
app.UseCookiePolicy(cookiePolicyOptions);
app.UseJwtInCookie(jwtInCookiePolicyOptions);
Design proposal No.2: Different authentication scheme?
I'm not sure, if that can be considered as a different authn scheme. If so, we would be able to add jwt in cookie alongside with default jwt bearer and cookies:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
// some cookie settings
})
.AddJwtBearer(options =>
{
// some jwt settings
})
.AddJwtInCookie(options =>
{
// There is an options for both cookie and jwt configuration for this?
});