spring-security: invalid_redirect_uri_parameter exception while running microservices on separate machines
This issue is based on Spring Security OAuth GitHub issue, which @jgrandja asked me to explain and expand here.
Summary
I’m using spring stack (Spring Boot 2.0.0.RELEASE) for creating a site that delegues user authentication/registration to Google via OAuth2. It is implemented as a few Spring Cloud microservices with a Zuul gateway running on port 8080.
Google Auth Server
Zuul Gateway(:8080)
/ \
/ \
/ \
Other OAuth2 Client Microservice(:5000)
Microservices
I use Google as an OAuth2 server, and use spring-security-oauth2 as a client, which is implemented as a separate microservice. If all my cloud is deployed at localhost everything works fine. But if my microservices are deployed at different machines, e.g. virtual machines or AWS Elastic Beanstalk, OAuth login doesn’t work.
Actual Behavior and a way for reproducing
The application uses Google for registering and authenticating users. Problem can be reproduced, if launch Zuul Gateway microservice on some separate virtual machine and other microservices should be launched at local machine ☝️
So Google should be called from the browser on VM. When the Google’s callback hits the application the following exception appears (from the log of the Client Microservice):
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_redirect_uri_parameter]
at org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider.authenticate(OAuth2LoginAuthenticationProvider.java:117) ~[spring-security-oauth2-client-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
...
Taking a look at the sources shows that the issue seems to be in the following check in the org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider class:
if (!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())) {
OAuth2Error oauth2Error = new OAuth2Error(INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
It happens, due to the following return values:
authorizationResponse.getRedirectUri()
http://192.168.1.2:5000/auth/login/oauth2/code/google
authorizationRequest.getRedirectUri()
http://localhost:8080/auth/login/oauth2/code/google
Here in redirect_uri of Response I have IP address of the machine, where Client Microservice is running, and that’s why request’s and response’s redirect_uris are not matching, so Spring Security is rejecting the user authentication with an exception 😞
Expected Behavior
While running microservices at localhost everything is ok
Configuration
Zuul Gateway Microservice config
server:
port: 8080
hystrix:
command:
default:
execution:
timeout:
enabled: false
ribbon:
ReadTimeout: 20000
ConnectTimeout: 20000
zuul:
ignoredServices: '*'
host:
connect-timeout-millis: 20000
socket-timeout-millis: 20000
routes:
auth:
path: /auth/**
url: ${AUTH_SERVICE_URI:http://localhost:5000}
stripPrefix: false
sensitiveHeaders:
OAuth2 Client Microservice config
server:
port: 5000
servlet:
contextPath: /auth
use-forward-headers: true
spring:
security:
oauth2:
resource:
filter-order: 3
client:
registration:
google:
client-id: [REMOVED]
client-secret: [REMOVED]
redirect-uri-template: ${AWS_CLOUD_URI:http://localhost:8080}/auth/login/oauth2/code/google
scope: profile,email
Version
Spring Boot 2.0.0.RELEASE Spring Security OAuth2 Client 5.0.3.RELEASE
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 15 (11 by maintainers)
I encountered the same error when I m setting up a Spring Boot application to authenticate users using Facebook OAuth2 implementation. Nginx (functions as reverse proxy) is configured to front the web app and also to offload the SSL cert.
The
server.use-forward-headers=trueworks for me though. I removed theredirect-uri-templateand let spring boot security use the default configuration.@ayulit Have you tried setting the
redirect-uri-templatefrom:${AWS_CLOUD_URI:http://localhost:8080}/auth/login/oauth2/code/googleto
{baseUrl}/auth/login/oauth2/code/{registrationId}This should work if the Proxy (Zuul) is configured to add the
X-Forwarded-*headers and the OAuth2 Login application is set withserver.use-forward-headers=true.See these resources for further information:
Running Behind a Front-end Proxy Server
Forwarded Headers
Thanks @izeye. I forgot to close it 😃