-
Notifications
You must be signed in to change notification settings - Fork 6k
JdbcOAuth2AuthorizedClientService should support update when saving #8425
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
Comments
@stavshamir Thank you for the detailed report. Yes, I agree the solution to this bug will need to ensure an atomic update. How about, Would you be interested in submitting a PR for this fix? |
Even if we wrap the use a transaction, the following scenario may occur:
Then what? Retry? After some more thought, I came up with this: @Override
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal) {
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
Assert.notNull(principal, "principal cannot be null");
if (existsAuthorizedClient(authorizedClient, principal)) {
updateAuthorizedClient(authorizedClient, principal);
} else {
try {
insertAuthorizedClient(authorizedClient, principal);
} catch (DuplicateKeyException e) {
updateAuthorizedClient(authorizedClient, principal);
}
}
} I believe this would make the result consistent with the in memory implementation. |
@stavshamir Good point. The scenario you describe is still an issue. The one thing I want to point out is that this issue is NOT a Spring Security issue but rather a Solution Architecture / Environment issue. Spring Security is not responsible for handling or co-ordinating distributed transactions. Instead this needs to be solved within the Application Architecture and Environment configuration. Makes sense? Your proposed solution will definitely improve on the scenario you describe. Yes, please go with this and much appreciated for delivering this fix. |
Before this commit, JdbcOAuth2AuthorizedClientService threw DuplicateKeyException when re-authorizing or when authorizing the same user from a different client. This commit makes JdbcOAuth2AuthorizedClientService's saveAuthorizedClient method consistent with that of InMemoryOAuth2AuthorizedClientService. Fixes gh-8425
Description
Configuring
JdbcOAuth2AuthorizedClientService
as follows:Allows only one authorization of the same user - trying to log in from one browser, and then from another, throws a
DuplicateKeyException
, making it unusable for SSO.More importantly, it throws the same exception when a refresh token is used for re-authorization when the access token is expired, meaning this class can't be used when re-authorization flow is required.
This behavior is inconsistent with the in memory implementation which is backed by a
Map
andput
to save the authorized client.To Reproduce
JdbcOAuth2AuthorizedClientService
.Expected behavior
Re-authorization and login from a different client should not throw an exception. Instead, it should behave the same as
InMemoryOAuth2AuthorizedClientService
behaves whensaveAuthorizedClient
is called.The solution to this bug must provide an atomic operation at the database level to be able to support concurrent access from multiple application instances. The only idea I had to achieve that is to use a
ON DUPLICATE KEY UPDATE
statement, but this will make this class non-generic.If you have another idea, I would be glad to implement it and create a pull request.
The text was updated successfully, but these errors were encountered: