spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Add Cookie-based Bearer Token support

Open jzheaux opened this issue 5 years ago • 7 comments

The OAuth 2.0 for Browser-Based Apps draft outlines the use of an HTTP-Only cookie to resolve the bearer token when the Application and API share a domain:

The BFF manages OAuth access and refresh tokens in the context of a cookie-based session, avoiding the direct exposure of any tokens to the JavaScript application ... Additionally, when using client-side sessions that contain access tokens, (as opposed to server-side sessions where the tokens only live on the server), the BFF SHOULD encrypt its cookie contents. This ensures that tokens stored in cookies are never written to the user's hard drive in plaintext format. This security measure helps ensure the confidentiality of the tokens in case an attacker is able to read cookies from the hard drive.

Spring Security might be able to simplify following this recommendation by introducing a cookie-based bearer token resolver. Additionally, the DSL could use that as a hint to leave CSRF enabled.

Related to https://github.com/spring-projects/spring-security/issues/8668#issuecomment-732445842

Given that encryption is part of this use case, #4435 likely should come before this ticket.

jzheaux avatar Dec 02 '20 20:12 jzheaux

@jzheaux May I ask if there are any plans to support this in one of the next releases?

dawi avatar Jun 13 '22 20:06 dawi

@jzheaux @rwinch

Is this still planned? If not, what is recommended as a workaround?

Ayrossi avatar Jul 06 '23 10:07 Ayrossi

@jzheaux @rwinch

Is this still planned? If not, what is recommended as a workaround?

Create a custom logic for passing the bearer token via HTTP only cookies between server and client.

Look here: https://youtu.be/vmEWywGzWbA

and here: https://www.youtube.com/watch?v=KxqlJblhzfI

OtenMoten avatar Jul 29 '23 10:07 OtenMoten

This is still under consideration as the best practices document is still in draft.

The idiomatic way to customize how the token is resolved is by publishing a bearer token resolver bean like so:

@Bean 
BearerTokenResolver cookieBasedBearerTokenResolver() {
    return (request) -> extractTokenFromCookie(request);
}

Note that the current draft recommends that any JWT Cookie must be Secure and HTTP-Only and should be encrypted and have a named prefixed by __Host-. Further, if you use a cookie, you will need to switch on CSRF protection.

Also, note that the recommended pattern is a BFF which often eliminates the need for a JWT cookie since the session cookie is already present and the JWT can be looked up from there.

jzheaux avatar Dec 15 '23 16:12 jzheaux

The section at the top of this issue appears to have been removed from the draft. There is now nothing about using a Cookie to transport bearer tokens from the browser to the protected API.

Is there any reason to implement this now that it is apparently no longer being considered for recommended practice?

OrangeDog avatar Jun 05 '24 11:06 OrangeDog

@Paper-Folding you are doing something wrong. /authorize (eventually) redirects to the client's callback URI. Neither endpoint should require an Authorization header to complete the request, and neither should be called via AJAX.

OrangeDog avatar Sep 06 '24 14:09 OrangeDog

@OrangeDog, I updated the links and the quoted text. It looks like the document has been reworked to further contextualize the constraints under which a JWT cookie can make sense.

jzheaux avatar Sep 24 '24 00:09 jzheaux

This is still under consideration as the best practices document is still in draft.

The idiomatic way to customize how the token is resolved is by publishing a bearer token resolver bean like so:

@Bean BearerTokenResolver cookieBasedBearerTokenResolver() { return (request) -> extractTokenFromCookie(request); } Note that the current draft recommends that any JWT Cookie must be Secure and HTTP-Only and should be encrypted and have a named prefixed by __Host-. Further, if you use a cookie, you will need to switch on CSRF protection.

Also, note that the recommended pattern is a BFF which often eliminates the need for a JWT cookie since the session cookie is already present and the JWT can be looked up from there.

This is still under consideration as the best practices document is still in draft.

The idiomatic way to customize how the token is resolved is by publishing a bearer token resolver bean like so:

@Bean BearerTokenResolver cookieBasedBearerTokenResolver() { return (request) -> extractTokenFromCookie(request); } Note that the current draft recommends that any JWT Cookie must be Secure and HTTP-Only and should be encrypted and have a named prefixed by __Host-. Further, if you use a cookie, you will need to switch on CSRF protection.

Also, note that the recommended pattern is a BFF which often eliminates the need for a JWT cookie since the session cookie is already present and the JWT can be looked up from there.

@jzheaux We are currently resolving the cookie for authentication token and we are using the BearerTokenResolver in exactly the same way as you have mentioned. But am thinking do we still need CSRF protection assuming the BFF just takes the cookie and calls the downstream via Authorization header? This article actually contradicts with what you have said about CSRF to be enabled for cookie based resolvers.

https://www.baeldung.com/csrf-stateless-rest-api#3-credentials-stored-in-cookies

kpur-sbab avatar Aug 11 '25 09:08 kpur-sbab