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

Support POST for authorization code request flow #1874

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

sylvain-costanzo
Copy link

Closes gh-1811

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 13, 2025
@sylvain-costanzo
Copy link
Author

The removal of the oidc scope matcher now allow OAuth2AuthorizationEndpointFilter to send POST /authorize request without the openid scope to the converters.

But I see two issues with this development:

1- The default converter OAuth2AuthorizationCodeRequestAuthenticationConverter still need the oidc scope to be used, but removing this condition will mess things up with the consent request, who, in the default implementation and in the demo-authorizationserver sample, is also a POST without the openid scope (and without the response_type parameter, who make this converter throw an error).

Tackling this issue seems a bit out of scope for this PR so I didn't touch anything, and it can be surely be solved with some custom converters.

2- Another minor issue I see is that the oauth2 specification is saying that a /authorize request (GET or POST) is supposed to have the parameters in the query string,

The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the "application/x-www-form-urlencoded" format

contradicting the OIDC spec saying that POST requests must use the body

If using the HTTP POST method, the request parameters are serialized using Form Serialization, per Section 13.2.

So this way of getting the request parameters may have to be updated, but again it can be solved with a custom converter, so it also felt out of scope of this PR.

Considering these 2 issues, I am not sure the PR is answering the "Support POST for authorization code request flow", and I would like your opinion on this

@sylvain-costanzo
Copy link
Author

Rewording my thoughts, I don't think these issues are completely out of scope, but they need significant refactor with more regression risks than the small change here.
The original goal of gh-1811 was to allow a POST /authorize without scope parameter to be sent to the converters, and this PR allows it.

@sylvain-costanzo sylvain-costanzo marked this pull request as ready for review January 16, 2025 18:24
@jgrandja jgrandja self-assigned this Jan 16, 2025
@jgrandja jgrandja added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 16, 2025
@jgrandja jgrandja changed the title Remove the openid scope matcher in OAuth2AuthorizationEndpointFilter Support POST for authorization code request flow Jan 16, 2025
String scope = request.getParameter(OAuth2ParameterNames.SCOPE);
return StringUtils.hasText(scope) && scope.contains(OidcScopes.OPENID);
};
RequestMatcher responseTypeParameterMatcher = (
Copy link
Collaborator

Choose a reason for hiding this comment

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

responseTypeParameterMatcher should not be removed as it will break the Authorization Consent flow. Only remove openidScopeMatcher here as well as in OAuth2AuthorizationCodeRequestAuthenticationConverter

Copy link
Author

Choose a reason for hiding this comment

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

In OAuth2AuthorizationEndpointFilter, removing the openid scope and letting the response_type would result of a matcher like this:

(GET or (POST and response_type)) or (POST and !response_type)

which is the same as (GET or POST) that's why I removed the response_type matcher.

I can add it back if you prefer it that way.

Copy link
Author

Choose a reason for hiding this comment

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

I removed the openid scope matcher from the converter OAuth2AuthorizationCodeRequestAuthenticationConverter

Copy link
Collaborator

Choose a reason for hiding this comment

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

would result of a matcher like this:
(GET or (POST and response_type)) or (POST and !response_type)

I believe we still need the response_type parameter in the matching because it's the difference between an Authorization Request or Authorization Consent Request.

However, I think we need to adjust the matching as follows:

Authorization Request
(GET or POST) and response_type

Authorization Consent Request
POST and !response_type

This should be applied to OAuth2AuthorizationEndpointFilter and both OAuth2AuthorizationCodeRequestAuthenticationConverter and OAuth2AuthorizationConsentAuthenticationConverter to be consistent.

Copy link
Author

Choose a reason for hiding this comment

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

Adding the response_type matcher to the GET request in OAuth2AuthorizationEndpointFilter will make the server return a 404 if a GET /authorize request is performed without the required response_type parameter, instead of a 400.

Specifically it is breaking the test OAuth2AuthorizationEndpointFilterTests.doFilterWhenAuthorizationRequestMissingResponseTypeThenInvalidRequestError() so I don't think adding this matcher in OAuth2AuthorizationEndpointFilter is a good solution.

For the same reason, adding these matcher rules to OAuth2AuthorizationCodeRequestAuthenticationConverter will make the request not enter the converter and prevent the server to return a 400 (it is breaking the same test).


This highlight the fact that a POST /authorize request without the response_type parameter will be treated as a consent request, so maybe we could add a condition in OAuth2AuthorizationConsentAuthenticationConverter to check if the user is authenticated?
A way to solve all this could be to create a new converter after OAuth2AuthorizationCodeRequestAuthenticationConverter and OAuth2AuthorizationConsentAuthenticationConverter to catch this missing parameter, so we can use the matcher in the converters?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, the matching rules stated in the previous comment need to be adjusted as follows:

Authorization Request
GET or (POST and response_type)

Authorization Consent Request
POST and !response_type

I tried this on my end and all tests pass.

Copy link
Author

Choose a reason for hiding this comment

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

I added a distinction between the Authorize matcher and the Consent matcher in OAuth2AuthorizationEndpointFilter.
A previous commit updated OAuth2AuthorizationCodeRequestAuthenticationConverter.
Nothing to do for OAuth2AuthorizationConsentAuthenticationConverter
It should be fine now

Copy link
Collaborator

Choose a reason for hiding this comment

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

@sylvain-costanzo I will get to this next week. I'm trying to wrap up a priority task by end of this week.

@jgrandja
Copy link
Collaborator

@sylvain-costanzo

The Spring team has recently migrated to the Developer Certificate of Origin (DCO) for our contribution process. See Submitting Pull Requests for additional details on the new process. Please format the commits in this PR as the DCO check did not pass.

@sylvain-costanzo sylvain-costanzo force-pushed the support-post-for-authorization-code-flow branch from 99b5960 to 40c8b22 Compare January 22, 2025 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

Support POST for authorization code request flow
3 participants