Nginx - API Gateway is not forwarding the request to Auth Service

zaidahmd nginx-forum at forum.nginx.org
Wed Apr 12 09:50:56 UTC 2017


Hi Francis,

Thanks for your interest. I would certainly like to contribute for the
future implementers of NGINX reverse proxy with API gateway functionality.
Below I will explain my application with NGINX configuration I have
performed and the code snippets/references for future users. If you like I
can share my working sample application also as starter guide for custom
java authentication gateway.

Secondly, I am able to complete my configuraiton successfully and got it
working and now in testing and expanding the functionality.

1. I have two Java applications written in Spring MVC framework. Both
applications are as follows
           a. Secure Gateway
           b. Protected Application(s)
2. Client sends a request to nginx to access protected resource.
http://nginx-server/employee

3. Nginx intercepts the request and first, sends the request to "Secure
Gateway" for authentication. http://secure-gw/authenticate
**************************************************************************
		location /api {
			auth_request /authenticate;
			proxy_pass http://protected;
		}

		location = /authenticate {
			proxy_pass http://secure-gw;
		}
***************************************************************************

4. If the user is NOT a logged in user "Secure Gateway" throws a 401
exception. Otherwise 200 ok is sent as a response and NGINX forwards the
request to "Protected Application" which returns the "employee"
resource/page.

5. NGINX is configured to capture the error "401" and redirect the request
to login page of SecureGateway using a location configured to cater 401
responses.
***************************************************************************
		location =/authfull {
			proxy_pass http://secure-gw/authenticate;
			proxy_pass_request_body off;
			proxy_set_header Content-Length "";
			proxy_set_header X-Original-URI $request_uri;
		}

		error_page   401 authfull;
***************************************************************************

6. User inputs the credential into login page and submits the request to
NGINX's location "/authenticate" using URL
"http://nginx-server/authenticate". 

7. "/authenticate" location is configured to forward the requests to "Secure
Gateway" application without removing the request body i.e. carries the
username and password from the form login page.

8(a)**. After successful login a token or session-id is generated and is
stored in a common session store which is also accessible to the "Protected
Application".
8(b)**. After successful login in "Secure Gateway" the secure gateway
application sends an internal login request to "Protected Application" and
gets the cookie response. Secure Gateway places two sessionIds(with
different name) in response cookies and sends the response back to NGINX
with HTTP 200 OK status.

9. NGINX forwards the authenticated/authorized requests to the "Protected
Application"

10. "Protected Application" checks the presence of session id in cookie,
validates the cookie and if valid, serves the request.

11. After the first request, whenever the user sends a new request to NGINX
for a protected application resource, NGINX sends a subrequest to
"/authenticate" location, "Secure Gateway" verifies its session id in cookie
and if valid, nginx forwards the request to "Protected applicaiton" which
also verifies the login session-id or token and serves the request if valid
session. After frst request Secure Gateway only checks for the validity of
its own session information. This time Secure Gateway will NOT send internal
requests to Protected application.

***********************************************Image Reference of
Design:*********************************
URL : http://tinypic.com/r/35a2lbp/9

This image is missing one thing that its not showing the internal login
request from secure gateway to protected application. For info, this request
is made only once when the user is not a logged in user to secure gateway
application. All subsequent requests does not involve this internal request
flow.

**********************************************NGINX
Configuration***********************************************
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

	proxy_intercept_errors on;
	
    server {
        listen       8180;

		location /{
			auth_request /authenticate;
			proxy_pass http://protected;			
		}

		location = /authenticate {
			proxy_pass http://secure-gw;
		}
		location =/authfull {
			proxy_pass http://secure-gw/authenticate;
			proxy_pass_request_body off;
			proxy_set_header Content-Length "";
			proxy_set_header X-Original-URI $request_uri;
		}
		error_page   401 authfull;
	}

	upstream protected {
		server localhost:8280;
   	}
		
	upstream secure-gw {
		 server localhost:8080;
   	}

}
**********************************************************************Secure
Gateway - SPRING MVC Security
Configs********************************************
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
        http
        .authorizeRequests()
            .antMatchers("/authenticate").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
        	.successHandler(successHandler)
            .loginPage("/authenticate")
            .failureHandler(failureHandler)
            .permitAll()
                     .and().csrf().disable();;
	}

************************************************************UI Login
Form********************************

        <form th:action="@{/authenticate}" method="post">
            <div><label> User Name : <input type="text" name="username"/>
</label></div>
            <div><label> Password: <input type="password" name="password"/>
</label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>

********************************************************************Protected
Resource - Security Configs ***********************************************
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests().anyRequest().authenticated().and().formLogin()
				.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and()
				.logout().permitAll().and().exceptionHandling().accessDeniedHandler(accessDeniedHandler())
				.authenticationEntryPoint(authenticationEntryPoint).and().csrf().disable();
	}
****************************************************************************************************************************************************************


Hope, I am able to clarify what I am doing. I can share the sample code if
you think its requried.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273515,273544#msg-273544



More information about the nginx mailing list