BIOINFORMAPPING
Home Projects Blog Publications Vitae GOMAP Docs GOMAP-Enrich Contact
Home Projects Blog Publications Vitae Contact

Enabling Okta Authentication from NGINX

I had been recently tasked enabling Okta authentication to all the users who use a private Jbrowse 2 instance. This was necessary to achieve three different goals

  1. Enhance Security and allows only authorized users to access the Jbrowse 2 instance
  2. Integrate Jbrowse 2 with into multiple apps with a single sign-on (SSO)
  3. Reduce the traffic through the VPN tunnel especially when using heavy data such as alignment tracks and other genomic files

I discovered a way to enable authentication to all visitors to a web-server with NGINX and vouch-proxy. I discovered this blog post by Aaron Parecki on the Okta Developer blogs. After a few tries I found a basic configuration that worked for NGINX and vouch-proxy.

First you need to create a free Okta developer account at https://developer.okta.com/. Okta allows you to use either your Github or Google accounts to create a new account.

Login to Okta Developer Dashboard and create a new application

  1. Click on the Applications that is indicated by the green arrow
  2. Click on the Add Application button
  3. Select Web type application as shown below and click Next
  4. Add the following details to the application form
    1. Login redirect URIs: http://localhost:9090/auth
    2. Logout redirect URIs: http://localhost:9090/logout
    3. Group assignments (default): Everyone
    4. Grant type allowed (default): Authorization Code
  5. Note down application Credentials. We will need it to configure vouch-proxy later
    1. Client ID
    2. Client secret

Install and Configure Nginx in Ubuntu

  1. The Nginx is part of the default distribution so the easy way to install is using apt-get or apt
    1
    
         sudo apt install nginx
    
  2. This creates a set of config files in the /etc/nginx directory
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
     ll /etc/nginx/
         total 72
         drwxr-xr-x   8 root root 4096 Feb 13 16:02 ./
         drwxr-xr-x 110 root root 4096 Feb 13 16:31 ../
         drwxr-xr-x   2 root root 4096 Apr 21  2020 conf.d/
         -rw-r--r--   1 root root 1077 Feb  4  2019 fastcgi.conf
         -rw-r--r--   1 root root 1007 Feb  4  2019 fastcgi_params
         -rw-r--r--   1 root root 2837 Feb  4  2019 koi-utf
         -rw-r--r--   1 root root 2223 Feb  4  2019 koi-win
         -rw-r--r--   1 root root 3957 Feb  4  2019 mime.types
         drwxr-xr-x   2 root root 4096 Apr 21  2020 modules-available/
         drwxr-xr-x   2 root root 4096 Feb 13 16:02 modules-enabled/
         -rw-r--r--   1 root root 1490 Feb  4  2019 nginx.conf
         -rw-r--r--   1 root root  180 Feb  4  2019 proxy_params
         -rw-r--r--   1 root root  636 Feb  4  2019 scgi_params
         drwxr-xr-x   2 root root 4096 Feb 13 16:02 sites-available/
         drwxr-xr-x   2 root root 4096 Feb 13 16:02 sites-enabled/
         drwxr-xr-x   2 root root 4096 Feb 13 16:02 snippets/
         -rw-r--r--   1 root root  664 Feb  4  2019 uwsgi_para
    
  3. We will have to edit the Nginx config file to add the configuration for vouch-proxy to integrate Okta Authentication.
    1. The default server block is located at /etc/nginx/sites-enabled/default
    2. I decided to add authentication to all users for all the sites so I edited the default site, but one can add aa new file for a different server config
    3. I also decided to work with http instead of https to make things easier for this tutorial, but in a production setting it’s essential to use https with SSL.
  4. Default Server Block Configuration of Nginx (After Removal of commented lines)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
         server {
             listen 80 default_server;
             listen [::]:80 default_server;
    
             root /var/www/html;
    
             # Add index.php to the list if you are using PHP
             index index.html index.htm index.nginx-debian.html;
    
             server_name _;
    
             location / {
                 try_files $uri $uri/ =404;
             }
    
         }
    
  5. Add the vouch-proxy validate configuration to the default server block

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    
         server {
             listen 80 default_server;
             listen [::]:80 default_server;
    
             root /var/www/html;
    
             # Add index.php to the list if you are using PHP
             index index.html index.htm index.nginx-debian.html;
    
             server_name _;
    
             ## Start of vouch-proxy validate block
             ## The line below send all unauthorized requests through vouch-proxy to validate
             auth_request /validate;
    
             ## Start of the Validate block to process requests
             ## This was taken from vouch-proxy default config
             location = /validate {
    
                 # forward the /validate request to Vouch Proxy
                 proxy_pass http://127.0.0.1:9090/validate;
                 # be sure to pass the original host header
                 proxy_set_header Host $http_host;
    
                 # Vouch Proxy only acts on the request headers
                 proxy_pass_request_body off;
                 proxy_set_header Content-Length "";
    
                 # optionally add X-Vouch-User as returned by Vouch Proxy along with the request
                 auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;
    
                 # these return values are used by the @error401 call
                 auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
                 auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
                 auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
             }
                
             # if validate returns `401 not authorized` then forward the request to the error401block
             error_page 401 = @error401;
    
             location @error401 {
                 # redirect to Vouch Proxy for login
                 return 302 http://localhost:9090/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
                 # you usually *want* to redirect to Vouch running behind the same Nginx config proteced by https
             }
    
    
             location / {
                 # First attempt to serve request as file, then
                 # as directory, then fall back to displaying a 404.
                 try_files $uri $uri/ =404;
    
                 ## This lines allows for tracking unique authenticated users from the application
                 proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
             }
         }
    
  6. You will have to restart the nginx service after you have modified the file and made the relevant changes
  7. If you try to access the website it would throw an error now because vouch-proxy is not installed or running on 9090

Setup vouch-proxy and start the service

  1. Easiest way to use vouch-proxy is to use the docker image provided.
    1. Installation instructions are available at https://github.com/vouch/vouch-proxy for the brave souls
  2. Make a config directory for vouch-proxy at any location
    1. E.g. ~/vouch-proxy/config
  3. Create a file called ~/vouch-proxy/config/config.yml and add the following configuration to the file for initial testing
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
     # vouch config
     # bare minimum to get vouch running with OpenID Connect (such as okta)
    
     testing: true
    
     listen: 0.0.0.0  # VOUCH_LISTEN
     port: 9090       # VOUCH_PORT
    
     vouch:
         allowAllUsers: true
    
     cookie:
         # allow the jwt/cookie to be set into http://yourdomain.com (defaults to true, requiring https://yourdomain.com) 
         secure: false
         # vouch.cookie.domain must be set when enabling allowAllUsers
         domain: localhost
    
     oauth:
         # Generic OpenID Connect
         # including okta
         provider: oidc
         client_id: XXXXXXXXXXXXXXXXXXXX
         client_secret: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
         auth_url: https://dev-ZZZZZZZZ.okta.com/oauth2/default/v1/authorize
         token_url: https://dev-ZZZZZZZZ.okta.com/oauth2/default/v1/token
         user_info_url: https://dev-ZZZZZZZZ.okta.com/oauth2/default/v1/userinfo
         scopes:
             - openid
             - email
         callback_url: http://localhost:9090/auth
    
  4. This configuration allows you to test if the authentication flow is working correctly and manually advance the steps after authentication
  5. Run the docker image for vouch-proxy
    1
    2
    3
    4
    5
    6
    7
    
         # docker stop vouch-proxy  ## Needed if restarting the daemon
         # docker rm vouch-proxy ## Needed if restarting the daemon
         docker run -d \
             -p 9090:9090 \
             --name vouch-proxy \
             -v ${HOME}/vouch-proxy/config:/config \
             voucher/vouch-proxy
    
  6. Now you are all set to see if the authentication workflow is working as intended
  7. Open a incognito or private window to test and load http://localhost. It should show an okta login screen as shown below
  8. Enter your credentials and Sign In to Okta
  9. The page should automatically direct you to http://localhost and voila you should be able to see the default Nginx screen below
Kokulapalan's Personal Website