Skip to main content

Two ways to integrate OAuth with HTTP Basic Auth Only applications

 

HTTP Basic auth is essentially obsolete – your username and password are publicly visible to anyone. There are two ways that your credentials are transmitted:

  1. In the header like http://username:[email protected]
  2. In the Authorization header. The username and password are concatenated to username:password, and then Base64 encoded – which becomes dXNlcm5hbWU6cGFzc3dvcmQK

With either method no explanation is necessary as to why this is a very bad idea. But some legacy systems rely solely on this method of authentication. How can you improve this? What if you have some new federation tool that supports OAuth? You could integrate a PAM (Privileged Access Management) system that dynamically changes passwords, but it is costly and adds another layer of complexity. Here are two options that essentially do the same thing as a proprietary PAM system, but leverage AWS resources.

 

Option 1 – Generate dynamic password and use it inside regular HTTP Basic Auth

The first option, while not secure enough for public facing use, could work if it’s a private intranet app with a limited number of users. A Lambda function (referred to “PAM Lambda”) would read a user’s cookies (assuming the OAuth/OIDC access_token, id_token, etc are stored there). This lambda function would generate a random string, set it to the current user’s password, and then 302 redirect the user to the web application protected by HTTP Basic auth. Then, upon logout the same Lambda would be called to reset the password to yet another random string, preventing anyone who may have intercepted that token from using it for future requests. This lambda would be protected by a Lambda authorizer, which would provide the token verification.

Here’s the step by step flow:

  1. User accesses web app with basic auth.
  2. Homepage redirects user to OAuth IDP for authentication.
  3. OAuth IDP redirects user to “PAM Lambda”
  4. Lambda authorizer intercepts request and verifies token
  5. If token is good, “PAM Lambda” executes and sets the random password for the user, whether that user is in LDAP, SQL, whatever the web application uses for a datastore.
  6. “PAM Lambda” then 302 redirects the user to the web application with the username:randompassword in the URL.
  7. Upon logout, “PAM Lambda” executes again, setting a new random password.

 

Option 2 – Password Setting Lambda and NGINX Reverse Proxy

With Option 1, your credentials are still being exposed. While the passwords are ephemeral and are secure (especially if you create a strong random string like a 256-bit hash), your webserver is still exposed. A more optimal solution would be using a reverse proxy like NGINX. NGINX has JavaScript support through njs and the auth_request directive, meaning it alone can do the token verification, password setting, and manipulate and pass headers on to the underlying web application. This way nothing is exposed to the user. Here is the request flow:

  1. User accesses web app fronted by NGINX.
  2. JS file inside NGINX validates the token, sets the password, and headers.
  3. User’s request is proxied on to underlying web app transparently.