Describe the bug OAuth2AuthorizationCodeGrantFilter strictly compares used redirect url with the one constructed from actual http request in order to process authorization response. In cloud setup these urls never equal due to request rewrite in gateway and usage of ip address from service registry.
To Reproduce original redirect url: https://{some host}/gateway/auth the one coming to auth service after gateway rewrite and ip resolved in eureka: http://{some ip here}/auth
Expected behavior I should be able to override the condition in order to customise the authorisation based on my architecture.
Sample
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: jgrandja
@michalgebauer The redirect_uri sent in the Authorization Request must be an exact match when the the Authorization Server redirects the Authorization Response back to the client - OAuth2AuthorizationCodeGrantFilter.
This is implemented per spec and is a recommended best practice in "2.1. Protecting Redirect-Based Flows":
When comparing client redirect URIs against pre-registered URIs, authorization servers MUST utilize exact string matching
I'm going to close this as implemented per spec and it cannot be configurable as this could introduce an attack vector.
Comment From: michalgebauer
Dear @jgrandja , thank you for your time you invested in answering my question. Still, I did not find in the spec, you are referring to, that the utilisation must be implemented by literally comparing the incoming request. Could you or someone else please find an example or documentation of spring oauth2 in cloud environment? How this filter should be used in the platform with gateway, scaling, load balancing... There you never know final IP that will be used to address the authorisation server. Even though you will not change the request matching code, I need to 'hack it' and move my condition e.g. somewhere into filter. It is doable, but I would expect from the lib the open-close principle. Thank you.
Comment From: michalgebauer
The spec requires a comparison of the redirect URL provided by the Resource Owner in the authentication flow against the actual redirect URL. In this request, I am not asking: - to deactivate the check - to manipulate in any way, the URL provided for the customer which are an intrinsic part of the security and as such are described in the spec.
I would like to be provided with the possibility to define the "actual" redirect URL because in an enterprise environment with multiple instances, load balancing and forwarding of messages, the actual information (required URL as seen by the resource owner) get's lost and is replaced by the IP address of the final pod/container.
Comment From: jgrandja
@michalgebauer
I would like to be provided with the possibility to define the "actual" redirect URL
You could define your own ClientRegistrationRepository @Bean, which would give you full control on defining/building the ClientRegistration's and setting the ClientRegistration.redirectUriTemplate to whatever you need.
Here are a couple of references:
Overriding Spring Boot 2.x Auto-configuration ClientRegistrationRepository
Another extension point you may consider is registering a custom OAuth2AuthorizationRequestResolver, which would give you control in setting OAuth2AuthorizationRequest.redirectUri - see Customizing the Authorization Request
I'm also wondering if you configured the ForwardedHeaderFilter? This might be the easiest solution for your setup. Take a look at Initiating the Authorization Request, where it states:
Configuring the
redirect-uriwith URI template variables is especially useful when the OAuth 2.0 Client is running behind a Proxy Server. This ensures that theX-Forwarded-*headers are used when expanding theredirect-uri.
Hope this helps?
Comment From: michalgebauer
Dear @jgrandja ,
thanks a lot! Sure, I went through all spring security documentation regarding oauth2 and even debugged the lib in search for the solution. I did create CustomAuthorizationRequestResolver and custom AuthorizationRequestRepository, which I need anyway, but got stuck with the exact request comparison.
Thanks for pointing out to ForwardedHeaderFilter, that is exactly what I need and I was about to write something like that myself.
Great support, now I see you rightfully closed my issue!