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

HttpSessionOAuth2AuthorizationRequestRepository storing one OAuth2AuthorizationRequest #9649

Conversation

candrews
Copy link
Contributor

Uses the same class name so users get this implementation by default,
whether they're specifying an AuthorizationRequestRepository or relying on
Spring Security defaults.

Note that this implementation intentionally does not handle multiple
OAuth2AuthorizationRequest's per session, regressing gh-5110

Closes gh-5145

FYI @jgrandja @rwinch

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 16, 2021
@jzheaux jzheaux added in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 16, 2021
Copy link
Contributor

@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 @candrews.

The solution is quite simple. Instead of storing multiple OAuth2AuthorizationRequest in HttpSession, we store a single one only.

This would break existing applications if the backing store is external from the container. So to restore the current behaviour we need a way for applications to revert to this. So let's add this to HttpSessionOAuth2AuthorizationRequestRepository:

@Deprecated
public final void setAllowMultipleAuthorizationRequests(boolean allowMultipleAuthorizationRequests) {
...
}

NOTE: The default will store a single OAuth2AuthorizationRequest.

Makes sense?

* @see AuthorizationRequestRepository
* @see OAuth2AuthorizationRequest
*/
public final class OldHttpSessionOAuth2AuthorizationRequestRepository
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this as all changes will be contained in HttpSessionOAuth2AuthorizationRequestRepository

@jgrandja jgrandja added this to the 5.5.0 milestone Apr 19, 2021
@candrews candrews force-pushed the limit-OAuth2AuthorizationRequest branch from 7e2ea57 to 5187280 Compare April 22, 2021 19:19
@candrews
Copy link
Contributor Author

That sounds good to me.

I've implemented that approach and updated this PR.

@candrews
Copy link
Contributor Author

@jgrandja what do you think?

🤞 this finally does it!

@candrews candrews force-pushed the limit-OAuth2AuthorizationRequest branch from 5187280 to e1fef10 Compare April 23, 2021 21:01
Copy link
Contributor

@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 @candrews. Please see review comment.

Also, please update copyright year. Thanks.

authorizationRequests = this.getAuthorizationRequests(request);
}
else {
authorizationRequests = new HashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

The default behaviour should store a single OAuth2AuthorizationRequest in session NOT a single entry in Map. Map is used only when allowMultipleAuthorizationRequests == true

Copy link
Contributor Author

@candrews candrews Apr 27, 2021

Choose a reason for hiding this comment

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

I thought of that too. But that would make the serialization data incompatible; if a user switched between allowMultipleAuthorizationRequests then they would get lots of warnings logged. Maybe that's a small annoyance, but it still seems to be an issue that would best be avoided. That approach also requires more changes which seems contrary to your preference oo keep the fix as minimal as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jgrandja ping
I'd really like to get this work completed... can you please provide me the guidance necessary for that to happen?

Thank you again!

Copy link
Contributor

Choose a reason for hiding this comment

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

Apologies for the delay @candrews. I have a lot of things I'm juggling so I'm just rotating through my priorities. I'll get to this tomorrow. Thanks for your patience.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also have a bunch of priorities, all conflicting and all urgent - I guess that's just how it goes :) Thank you for your continued attention to this issue, I greatly appreciate the opportunity to address it with you.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for thinking about passivity. However, I'd like to consider that we are also deprecating and thus removing setAllowMultipleAuthorizationRequests at some point. At that time, if there are values persisted as a Map, user applications will break when they update. This is not a huge deal since we will remove the deprecated method on a major release, but it is not ideal.

Instead, I'd prefer to read the session attribute and do an instanceof check. If it is a Map the code when the look up the proper value in the Map. Otherwise it would use the OAuth2AuthorizationRequest found in the session.

When saving, we would always save according to the allowMultipleAuthorizationRequests property.

This has the advantage that if users are not leveraging the deprecated setAllowMultipleAuthorizationRequests, then they can expect that an update to Spring Security 6 will be unlikely to cause a ClassCastException when they update to it. We also don't need any special code in Spring Security 6 to handle this scenario.

Copy link
Contributor

@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 @candrews. There is one minor change left and I think we're good to go. Please squash commits on next update.

I will have @rwinch do one last review and then we'll be ready to merge.

private HttpSessionOAuth2AuthorizationRequestRepository authorizationRequestRepository;

@Before
public void beforeEach() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename to setup()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@candrews candrews force-pushed the limit-OAuth2AuthorizationRequest branch from 82b8ef9 to 9f21c76 Compare May 2, 2021 21:03
@rwinch rwinch self-requested a review May 4, 2021 18:57
Copy link
Member

@rwinch rwinch 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 pull request and your patience. I've provided feedback inline.

authorizationRequests = this.getAuthorizationRequests(request);
}
else {
authorizationRequests = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

Thank you for thinking about passivity. However, I'd like to consider that we are also deprecating and thus removing setAllowMultipleAuthorizationRequests at some point. At that time, if there are values persisted as a Map, user applications will break when they update. This is not a huge deal since we will remove the deprecated method on a major release, but it is not ideal.

Instead, I'd prefer to read the session attribute and do an instanceof check. If it is a Map the code when the look up the proper value in the Map. Otherwise it would use the OAuth2AuthorizationRequest found in the session.

When saving, we would always save according to the allowMultipleAuthorizationRequests property.

This has the advantage that if users are not leveraging the deprecated setAllowMultipleAuthorizationRequests, then they can expect that an update to Spring Security 6 will be unlikely to cause a ClassCastException when they update to it. We also don't need any special code in Spring Security 6 to handle this scenario.

@candrews
Copy link
Contributor Author

candrews commented May 4, 2021

Thanks for that additional information. I think I've now updated this PR with that change. The approach I've taken creates a new Map when allowMultipleAuthorizationRequests is not set (which could be a garbage concern) - if that's not acceptable, let me know and I'll try a different approach. I've already tried a few other ways, but they seem to create more complex code with more duplication.

@candrews candrews force-pushed the limit-OAuth2AuthorizationRequest branch from 9f21c76 to b618cf9 Compare May 4, 2021 21:16
Copy link
Member

@rwinch rwinch left a comment

Choose a reason for hiding this comment

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

Please see the feedback inline

@rwinch rwinch assigned rwinch and unassigned jgrandja May 7, 2021
… default

Add setAllowMultipleAuthorizationRequests allowing applications to
revert to the previous functionality should they need to do so.

Closes spring-projectsgh-5145
Intentionally regresses spring-projectsgh-5110
@candrews candrews force-pushed the limit-OAuth2AuthorizationRequest branch from b618cf9 to ba5157a Compare May 10, 2021 16:18
@rwinch
Copy link
Member

rwinch commented May 12, 2021

Thanks for the PR @candrews This is merged into main via 35f5ebd I added a few more tests via 35f5ebd

@rwinch rwinch closed this May 12, 2021
sjohnr added a commit to sjohnr/spring-security that referenced this pull request Jun 2, 2021
sjohnr added a commit that referenced this pull request Jun 15, 2021
sjohnr added a commit that referenced this pull request Jun 15, 2021
sjohnr added a commit to sjohnr/spring-security that referenced this pull request Jun 15, 2021
sjohnr added a commit that referenced this pull request Jun 15, 2021
sjohnr added a commit that referenced this pull request Jun 15, 2021
akohli96 pushed a commit to akohli96/spring-security that referenced this pull request Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OAuth2AuthorizationRequest should expire
5 participants