OAuth2 Spring security with Google login doesn't work

Viewed 258

I found a really good tutorial on third-party login with Spring security in the link below, It contains both front-end and back-end code.

https://www.callicoder.com/spring-boot-security-oauth2-social-login-part-1/

Github : https://github.com/callicoder/spring-boot-react-oauth2-social-login-demo

Everything works perfectly locally as well as in a cloud server in a normal docker container. But if I put this code behind a reverse proxy preferably Nginx (using docker swarm) there seems to be some issue in the redirection. In my console, I'll get the authorization_request_not_found error. I have basically googled and tried everything but for some reason, it's not working. I am definitely missing something. So any help is much appreciated. The required code snippets are down below.

For example, if our domain is test.oauth.com

i) Nginx proxy's default.conf

server {
        listen 443 ssl;
        
        index index.html index.htm index.nginx-debian.html;

        server_name test.oauth.com;
        ssl_certificate /home/bundle_chained.crt;
        ssl_certificate_key /home/private.key;
        
        proxy_set_header     X-Real-IP           $remote_addr;
        proxy_set_header     X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header     X-Forwarded-Proto   $scheme;
        proxy_set_header     Host                $http_host;
        proxy_set_header     X-Forwarded-Host    $server_name;
        proxy_set_header     X-Forwarded-Server  $host;
        proxy_set_header     X-Forwarded-Port    $server_port;
        proxy_set_header     Cookie              $http_cookie;

        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

       location /login {
                    rewrite ^/login(.*)$ $1 break;
                    proxy_pass http://test-login-server:8080/;
                    proxy_redirect off;
        }

        location / {
                rewrite ^/(.*)$ /$1 break;
                proxy_pass http://test-react-server/;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection ‘upgrade’;
                proxy_cache_bypass $http_upgrade;
        }
}

server {
    listen 80;
    server_name test.oauth.com;
    return 301 https://$host$request_uri;
}

ii) Nginx react server's default.conf

server {
        listen 80;
        
        index index.html index.htm index.nginx-debian.html;

        server_name test.oauth.com;

        location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

        try_files $uri $uri/ /index.html;

        proxy_cache cache_zone;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_cache_use_stale error timeout http_500;
        proxy_cache_valid 200 10m;
        add_header X-Cached $upstream_cache_status;

        }


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
}

I am using another Nginx server (test-react-server) to serve the front-end build.

iii) Application.yml of Spring

server:
  forward-headers-strategy: NATIVE

spring:
    datasource:
        url: jdbc:mysql://127.0.0.1:3306/spring_social?createDatabaseIfNotExist=true
        username: <username>
        password: <password>


    jpa:
        show-sql: true
        hibernate:
            ddl-auto: update
            naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
        properties:
            hibernate:
                dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    security:
      oauth2:
        client:
          registration:
            google:
              clientId: <google-client-id>
              clientSecret: <google-client-secret>
              redirectUri: "{baseUrl}/login/oauth2/callback/{registrationId}"
              scope:
                - email
                - profile
            facebook:
              clientId: <facebook-client-id>
              clientSecret: <facebook-client-secret>
              redirectUri: "{baseUrl}/login/oauth2/callback/{registrationId}"
              scope:
                - email
                - public_profile
            github:
              clientId: <github-client-id>
              clientSecret: <github-client-secret>
              redirectUri: "{baseUrl}/login/oauth2/callback/{registrationId}"
              scope:
                - user:email
                - read:user
          provider:
            facebook:
              authorizationUri: https://www.facebook.com/v3.0/dialog/oauth
              tokenUri: https://graph.facebook.com/v3.0/oauth/access_token
              userInfoUri: https://graph.facebook.com/v3.0/me?fields=id,first_name,middle_name,last_name,name,email,verified,is_verified,picture.width(250).height(250)
app:
  auth:
    tokenSecret: 04ca023b39512e46d0c2cf4b48d5aac61d34302994c87ed4eff225dcf3b0a218739f3897051a057f9b846a69ea2927a587044164b7bae5e1306219d50b588cb1
    tokenExpirationMsec: 864000000

  cors:
    #allowedOrigins: http://localhost:3000
    allowedOrigins: https://test.oauth.com,https://test.oauth.com/login
  oauth2:
    authorizedRedirectUris:
      #- http://localhost:3000/oauth2/redirect
      - https://test.oauth.com/oauth2/redirect

iv) Front-end's package.json

{
  "name": "react-social",
  "version": "0.1.0",
  "private": true,
  "homepage": "http://test-react-server",
  "dependencies": {
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-router-dom": "^4.3.1",
    "react-s-alert": "^1.4.1",
    "react-scripts": "1.1.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

v) Front-end's index.js

export const API_BASE_URL = 'https://test.oauth.com/login';

export const ACCESS_TOKEN = 'accessToken';

export const OAUTH2_REDIRECT_URI = 'https://test.oauth.com/oauth2/redirect'


export const GOOGLE_AUTH_URL = API_BASE_URL + '/oauth2/authorize/google?redirect_uri=' + OAUTH2_REDIRECT_URI;
export const FACEBOOK_AUTH_URL = API_BASE_URL + '/oauth2/authorize/facebook?redirect_uri=' + OAUTH2_REDIRECT_URI;
export const GITHUB_AUTH_URL = API_BASE_URL + '/oauth2/authorize/github?redirect_uri=' + OAUTH2_REDIRECT_URI;

Screenshot of error-1

Screenshot of error-2

vi) Stack trace of error

org.springframework.security.oauth2.core.OAuth2AuthenticationException: [authorization_request_not_found] 
    at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:170)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:222)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:178)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:833)

I dumped the stack trace in OAuth2AuthenticationFailureHandler class.

0 Answers
Related