Add AuthN to HAPI FHIR with OAuth2 Proxy, Nginx and Keycloak - Part 3

Introduction

This is the third post, in a series of posts about adding support for Authentication (AuthN) to HAPI FHIR with OAuth2 Proxy, Nginx and Keycloak:

Nginx

Nginx is a HTTP web server, reverse proxy, content cache, load balancer, TCP/UDP proxy server, and mail proxy server.

I followed the recommendations in the following guides:

We will route all traffic through Nginx and use the Nginx auth_request directive to make subrequests to OAuth2 Proxy in order to authenticate requests to HAPI FHIR.

SSL Termination

To set up a HTTPS server, add the ssl parameter to the listen directive in the server block:

server {

  server_name hapi-fhir.au.localhost;
  listen 443 ssl default_server;
  include /etc/nginx/conf/ssl.conf;

  ...
 
}  

See: nginx-default.conf.template

And specify the locations of the server certificate and private key files:

ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;

ssl_stapling_verify on;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'AEAD-AES128-GCM-SHA2561 AEAD-AES256-GCM-SHA3842 AEAD-CHACHA20-POLY1305-SHA2563 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384';

access_log  /var/log/nginx/access.log;

See: ssl.conf

The server certificate is a public entity. It is sent to every client that connects to Nginx. The private key is a secure entity and should be stored in a file with restricted access. However, Nginx must be able to read this file.

The auth_request directive

To perform authentication, NGINX makes a HTTP subrequest to an external server where the subrequest is verified. If the subrequest returns a 2xx response code, access is allowed, if it returns 401 or 403, access is denied.

nginx-default.conf.template:

server {

  ...

  location /private/ {
    auth_request           /oauth2/auth;
    auth_request_set       $auth_status            $upstream_status;
  }
  
  location /oauth2/ {
    proxy_pass             http://oauth2-proxy:4180;
    proxy_set_header       Host                    $host;
    proxy_set_header       X-Real-IP               $remote_addr;
    proxy_set_header       X-Auth-Request-Redirect $request_uri;
  }

  location = /oauth2/auth {
    internal;

    # Proxy for AuthN server
    proxy_pass              http://oauth2-proxy:4180;

    proxy_pass_request_body off;
    proxy_set_header        Content-Length         "";
    proxy_set_header        X-Forwarded-Uri        $request_uri;

    proxy_set_header        Host                   $host;
    proxy_set_header        X-Real-IP              $remote_addr;
  }

  ...
 
}  

See: nginx-default.conf.template

The Nginx auth_request directive allows Nginx to authenticate requests via OAuth Proxy's /auth endpoint.

Source Code

What's Next

In the next post, we'll take a look at how to configure OAuth2 Proxy.

References
System Hardening
OAuth 2.0
Keycloak
Nginx
OAuth2 Proxy