Skip to content

Authorization Code Flow with PKCE should support refresh tokens for confidential clients #592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andifalk opened this issue Jan 19, 2022 · 3 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@andifalk
Copy link

Expected Behavior
When using the authorization code flow + PKCE for confidential clients then it should (optionally) be also possible to issue a refresh token as well. Maybe the best way would be to just add a configuration option for registered clients to enable/disable refresh tokens.

Current Behavior
Currently, when using the authorization code flow + PKCE no refresh token is issued. This is independent of the actual client type used (also for confidential clients like Spring MVC/Thymeleaf). Implementing recommended patterns like the BFF pattern (to keep tokens away from web browser storage) would not offer good usability without the availability of refresh tokens for confidential clients (using PKCE).

Context
The current OAuth 2.1 draft (https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-04.html#section-7.8) also recommends using PKCE for confidential clients, not only for public clients:
Although PKCE was originally designed as a mechanism to protect native apps, this advice applies to all kinds of OAuth clients, including web applications and other confidential clients.

In the latest OAuth WG draft for browser-based applications, the OAuth working group describes the Backend for Frontend pattern to keep tokens out of javascript apps and the browser storage. Also, the same document recommends:
The Application Server SHOULD be considered a confidential client and issued its own client secret. The Application Server SHOULD use the OAuth 2.0 Authorization Code grant with PKCE to initiate a request for an access token.
In terms of the BFF pattern, the application server is the server-side component acting as the BFF (this may just be an API gateway). Without refresh tokens (which would also never leave the server-side) implementing this with providing good usability would be very difficult.

So in order to follow the most secure approach when using browser-based applications is to use the BFF pattern to not store tokens in the browser and also use the most secure authorization code + PKCE for the server side BFF application handling the token flow to retrieve access and refresh tokens. There are also ways to hack confidential server-side web applications that do not use PKCE (showed in this presentation by Micah Silverman from OKTA: https://youtu.be/qGKlFYSCyQk).

@andifalk andifalk added the type: enhancement A general enhancement label Jan 19, 2022
@jgrandja
Copy link
Collaborator

Hi @andifalk. You can enable refresh token for a RegisteredClient by configuring it with ...authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN). The default sample configures the client for refresh token.

I'll close this as answered.

@jgrandja jgrandja self-assigned this Jan 24, 2022
@jgrandja jgrandja added status: invalid An issue that we don't feel is valid and removed type: enhancement A general enhancement labels Jan 24, 2022
@andifalk
Copy link
Author

Hi @andifalk. You can enable refresh token for a RegisteredClient by configuring it with ...authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN). The default sample configures the client for refresh token.

I'll close this as answered.

Hi, @jgrandja I think you misunderstood my point. I am aware that I can exchange a refresh token into an access token by using AuthorizationGrantType.REFRESH_TOKEN. My point is that for a BFF when using Authz Code + PKCE (here as a confidential client) the token request does NOT issue any refresh token that I am able to exchange into an access token.

@jgrandja
Copy link
Collaborator

@andifalk

the token request does NOT issue any refresh token

The token response will contain a refresh token if ...authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) is configured for the RegisteredClient. Have you tried the default sample?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

2 participants