Expected Behavior
It would be great to have similar capabilities in oauth2Client as in oauth2Login to provide defaultSuccessUrl.
In case of SPA this could be set to SPA index page.
Current Behavior
Currently in case of OAuth2 login it's very handy to provide defaultSuccessUrl for example if the application is an SPA.
Unfortunately this is not possible with OAuth2 client. It doesn't support any callbacks (handlers) or url to redirect to after successful authorization. It's limited to redirecting back to previous request in request cache. But in case of SPA this might be empty which will result in redirecting to OAuth2 redirect url. https://github.com/spring-projects/spring-security/blob/main/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationCodeGrantFilter.java#L244
Context
I have an Spring Boot REST API with Angular SPA client. I planned to have no non-REST endpoints in controllers. But looks like I have to create at least 1 non-REST endpoint. Something like "/login" just to make sure I will have a Spring url to come back to after successful authentication. This endpoint would simply redirect back to SPA index page. But this seems to be more like a workaround.
Application repository: https://github.com/mucsi96/training-log-pro
Comment From: jgrandja
@mucsi96 http.oauth2Login() and http.oauth2Client() implement different flows and are not the same so it doesn't make sense to have feature parity between the two.
http.oauth2Login() allows users to log in by using their existing account at an OAuth 2.0 or OpenID Connect 1.0 Provider.
It's implemented using the OAuth 2.0 and OpenID Connect 1.0 Authorization Code Grant Flow.
http.oauth2Client() implements OAuth 2.0 Client support, which includes authorization grant support for authorization_code, client_credentials, password, refresh_token and urn:ietf:params:oauth:grant-type:jwt-bearer. See OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider for more details.
Also, the authorization_code implementation for http.oauth2Client() is OAuth 2.0 Authorization Code grant, whereas http.oauth2Login() implements OpenID Connect 1.0 Authorization Code Flow for user authentication. Therefore, defaultSuccessUrl(), successHandler(), failureHandler(), etc. only make sense for http.oauth2Login() since this feature implements user authentication flow and http.oauth2Client() does not implement user authentication flow.
Unfortunately this is not possible with OAuth2 client. It doesn't support any callbacks (handlers) or url to redirect to after successful authorization.
DefaultOAuth2AuthorizedClientManager and AuthorizedClientServiceOAuth2AuthorizedClientManager provide setAuthorizationSuccessHandler() and setAuthorizationFailureHandler(). I believe this is the feature you are looking for? Please see OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider for details on usage.
I'm going to close this as http.oauth2Login() and http.oauth2Client() implement different flows and the API's are not intended to be the same as per the explanation provided.
Comment From: mucsi96
Hi @jgrandja,
Thanks for reply on my issue.
Regarding error handling you are right it would be possible to call setAuthorizationFailureHandler on DefaultOAuth2AuthorizedClientManager. But unfortunately there two problems with it.
1. If I call setAuthorizationFailureHandler the authorized client will be not removed from authorized client repository. Which is not great as I would like to keep this behavior. So I would need to copy over this from Spring code.
2. It's not possible to send a custom error response in authorizationFailureHandler because on next line(https://github.com/spring-projects/spring-security/blob/main/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java#L181) the error is still rethrown and the original redirection behavior is kept. So in the end I would get a "Cannot create a session after the response has been committed" exception.
The only way for custom error handling here would be to throw a custom Exception and have a custom Filter before OAuth2AuthorizationRequestRedirectFilter which would catch this and do the custom error response for SPA instead of redirection as we are in scope of REST API.
Regarding success handling I was referring to flow in OAuth2AuthorizationCodeGrantFilter. Currently I see no nice option for customizing it to prevent the redirection behavior. https://github.com/spring-projects/spring-security/blob/main/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationCodeGrantFilter.java#L242
The only hacky workaround could be to throw some dummy Exception in custom authorized client repository on saving and have a filter which would catch it and do the custom logic. Here I would like to redirect to SPA root page similarly to defaultSuccessUrl in case of OAuth2 login instead of redirecting to previous request from request cache.