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)

Most upvoted comments

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=true works for me though. I removed the redirect-uri-template and let spring boot security use the default configuration.

@ayulit Have you tried setting the redirect-uri-template from:

${AWS_CLOUD_URI:http://localhost:8080}/auth/login/oauth2/code/google

to

{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 with server.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 😃