I need to change the authorizationRedirectStrategy in OAuth2AuthorizationRequestRedirectFilter because I want to manipulate the redirect_uri before redirecting.

Currently it is always initialized with new DefaultRedirectStrategy() and I can not change it.

This is necessary because we hava a multi-tenant SaaS application with wildcard subdomains for our customers and we need to redirect to a central URL before redirecting to the final destination for Oauth authentication.

Comment From: sjohnr

Hi @tompson. I see what you are saying regarding customizing the redirect. However, have you tried customizing the OAuth2AuthorizationRequestResolver? The redirect that is sent comes from authorizationRequest.getAuthorizationRequestUri(), which could be directly influenced by the request resolver. Does that provide a similar customization hook that you're looking for?

Comment From: tompson

Hi @sjohnr, yes, I tried to implement a custom OAuth2AuthorizationRequestResolver this works for login but not for oauth client authorization because then the method org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter#matchesAuthorizationResponse fails because the redirectUri does not match

Comment From: sjohnr

I think perhaps I'm misunderstanding you or we have a disconnect.

This is necessary because we hava a multi-tenant SaaS application with wildcard subdomains for our customers and we need to redirect to a central URL before redirecting to the final destination for Oauth authentication.

Are you wanting to influence the actual browser redirect to the authorization server, e.g. override the authorization endpoint you are redirected to? Or are you wanting to manipulate the redirect_uri query parameter that is used to redirect back to your client application?

Comment From: tompson

Our customers get their own hostnames for using our application:

``` customer1.example.com customer2.example.com customer3.example.com ... ````

so the redirect_uri I send to Google or Microsoft for authentication would need to be different for every customer - which does not work because I need to configure the valid redirect_uri for the OAuth credentials at the provider.

So I want to send always the same redirect_uri like redirect.example.com to the authentication provider and include the real redirect uri as an additional parameter (currently in the state parameter) which my controller at redirect.example.com extracts and then redirects to.

Comment From: sjohnr

Hi @tompson, thanks for the clarification. Based on your description, it sounds like you're trying to modify the redirect_uri query parameter so that you can take control of the redirect flow that happens on the way back to your application.

The problem I see with this approach is that the contract between your client and authorization server is no longer strictly enforced, as there must be an intermediary (a separate application at redirect.example.com in your example).

See this segment of video from SpringOne 2021 where I present a high level demonstration of some attacks on applications that deviate the redirect_uri matching and handling from the best practices recommended by the spec authors. In your case, it seems quite possible you would have a hard time protecting against a mix-up attack, because you allow tenants to potentially sign up for your service, which would allow them to spoof other tenants.

This is one reason why it is not easy to manipulate the redirect_uri, as it really should be static and not subject to this kind of manipulation. Perhaps you could automate dynamically provisioning a client registration with Microsoft/Google for each tenant. I would not recommend attempting to multiplex a single client registration with the provider.

If you would be so kind as to evaluate what I've described against your use case and give me some feedback in case I misunderstood anything, which is quite possible, I would appreciate it. We can potentially leave this enhancement suggestion open, but based on what I'm understanding right now, I don't recommend it as a way to solve your particular problem.

Comment From: tompson

I see your point there and I have to think about it.

In my case redirect.example.com is no separate app but the same Spring Boot app, just a different controller, I am not sure if that weakens the security.

Comment From: rvanderboom

hey,

i see this issue that looks simular.. i have upgraded our system to spring security 5 (with keycloak). everything works except our subdomain that starts with preview.

. keycloak generates a cors error because the registrationclient only allows 1 redirecturi. we tried to update the &redirect_uri= with the subdomain login redirect uri but, the registratedclient is still set to main domain, so keycloak denies it.

do we have to configure a registrationclient, oauthlogi filter and redirect filters for every subdomain ? that seems strange since a subdomain should not give issues and in keycloak you define the list of redirect uris allowed , so whats the use if only 1 is allowed ?

Comment From: sjohnr

In my case redirect.example.com is no separate app but the same Spring Boot app, just a different controller, I am not sure if that weakens the security.

Hi @tompson, happy new year! I don't believe that using a different endpoint on the same Spring Boot app has any bearing on the security posture of a redirection-based flow. You would still potentially be vulnerable, because you are re-using the redirection endpoint for each tenant.

do we have to configure a registrationclient, oauthlogi filter and redirect filters for every subdomain ? that seems strange since a subdomain should not give issues and in keycloak you define the list of redirect uris allowed , so whats the use if only 1 is allowed ?

@rvanderboom thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements, as we are discussing in this thread. Feel free to update this issue with a link to the re-posted question (so that other people can find it).