Skip to content
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

Add PKCE support #93

Closed
wants to merge 1 commit into from
Closed

Add PKCE support #93

wants to merge 1 commit into from

Conversation

Kehrlann
Copy link
Contributor

@Kehrlann Kehrlann commented Jul 2, 2020

This is a first stab at PKCE implementation - see #45 . The idea is to validate the structure of how to achieve PKCE validation, and then start iterating from there.

Notes:

  • The SHA256 code verification was stolen directly from spring-security, see org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver#createHash . We might want to make that public in spring-security at some point ?
  • We consider a client is public client when the principal is null but it has client ID.

TODOs:

Authorization endpoint

  • RFC 7636 - 4.4 Server Returns the Code ; validate code_challenge & code_challenge_method
  • CODE_CHALLENGE is required ; CODE_CHALLENGE_METHOD can be null (will default to plain)
  • Only trigger PKCE checks for public clients (registeredClient.clientSecret is blank)
  • Consider what is a "public" client - maybe we could mark some "redirectUris" to require PKCE vali
  • Add tests for OAuth2AuthorizationEndpointFilter

Token endpoint

  • Validate code_verifier for both "plain" and "S256" methods (for public clients)
  • If code_challenge_method is null, default to plain
  • Polish changes to OAuth2AuthorizationCodeAuthenticationProvider (null checks, try-catches)
  • In OAuth2AuthorizationCodeAuthenticationProvider.authenticate, authenticate public client - See RFC 6749 - 3.2.1. Token Endpoint > Client Authentication [1]

Integration tests

  • Add integration test for PKCE

[1] In the "authorization_code" "grant_type" request to the token endpoint, an unauthenticated client MUST send its "client_id" to prevent itself from inadvertently accepting a code intended for a client with a different "client_id". This protects the client from substitution of the authentication code. (It provides no additional security for the protected resource.)

@Kehrlann Kehrlann force-pushed the pkce branch 4 times, most recently from 8dad963 to d6209df Compare July 9, 2020 12:22
@Kehrlann
Copy link
Contributor Author

Kehrlann commented Jul 9, 2020

I started adding tests for OAuth2AuthorizationCodeAuthenticationProvider. They are messy for now, but mostly allow me to validate the implementation.
Two of them are failing, they show the need for OAuth2AccessTokenAuthenticationToken to support public clients - today, only private clients are supported.

The first stab at this stops at d6209df, the last commit is the failing tests, quite a bit messy.

Copy link
Collaborator

@jgrandja jgrandja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @Kehrlann! Please see initial review comments.

@Kehrlann Kehrlann force-pushed the pkce branch 2 times, most recently from f57faa0 to 24f6068 Compare July 23, 2020 13:30
@Kehrlann Kehrlann marked this pull request as ready for review July 28, 2020 07:55
@Kehrlann
Copy link
Contributor Author

The PR is ready for review. Still to be decided: how do we identify public clients in OAuth2AuthorizationEndpointFilter ?

  1. When the registeredClient has no clientSecret, its' a 100% public client, that's currently covered.
  2. However, the registered client could have a secret and still be used as a public client. Something to explore could be: some redirect uris of a client could be tagged with "require PKCE".

@uhhhh2
Copy link

uhhhh2 commented Jul 29, 2020

Thoughts on letting all clients (public and confidential) that use authorization code also use PKCE (confidential will have both secret & PKCE), but only require PKCE for public clients. (those without client secrets) like in spring-projects/spring-security#6548 ?

@Kehrlann
Copy link
Contributor Author

With the current proposed implementation, confidential clients may send PKCE parameters. However, those parameters will not be validated. Not sure if we should put this in v1 ?

It makes sense to validate whatever PKCE params confidential clients send, especially if we're allowing confidential clients to do it in spring-security.

@jgrandja jgrandja added this to the 0.0.2 milestone Aug 19, 2020
@jgrandja jgrandja added the type: enhancement A general enhancement label Aug 19, 2020
@jgrandja jgrandja self-assigned this Aug 19, 2020
@Kehrlann
Copy link
Contributor Author

Rebased on top of master. For info, I have only checked the build & ran the tests on conflicting commits.

Copy link
Collaborator

@jgrandja jgrandja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates @Kehrlann! I left a few comments inline.
Also, can you please squash the commits on next update.
Thanks.

@Kehrlann
Copy link
Contributor Author

Included all corrections, squashed. There's still one open question, and we should be almost good to go.

jgrandja added a commit that referenced this pull request Oct 6, 2020
jgrandja added a commit that referenced this pull request Oct 6, 2020
@jgrandja
Copy link
Collaborator

jgrandja commented Oct 6, 2020

Thanks for the great work @Kehrlann ! This is now in master!

FYI, I added a polish commit with some minor updates.

Also, I discovered an issue when reviewing the integration test OAuth2PkceTests. The test revealed an issue with the implementation so it needed to be re-worked. Ultimately, the client needs to be authenticated before it hits the token endpoint. Therefore, I needed to move the PKCE authentication logic from OAuth2AuthorizationCodeAuthenticationProvider to OAuth2ClientAuthenticationProvider.

Apologies, as I missed this during the review process. I decided to go ahead an apply the change. Take a look at the commit 5c31fb1 and let me know if you have any questions.

Thanks again for all the great work!

@jgrandja jgrandja closed this Oct 6, 2020
@jgrandja jgrandja added the status: duplicate A duplicate of another issue label Oct 6, 2020
@Kehrlann Kehrlann deleted the pkce branch October 12, 2020 12:46
mohammedBalhaddad pushed a commit to mohammedBalhaddad/spring-authorization-server that referenced this pull request Oct 12, 2020
mohammedBalhaddad pushed a commit to mohammedBalhaddad/spring-authorization-server that referenced this pull request Oct 12, 2020
doba16 pushed a commit to doba16/spring-authorization-server that referenced this pull request Apr 21, 2023
doba16 pushed a commit to doba16/spring-authorization-server that referenced this pull request Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants