Skip to content

stephan-buckmaster/ruby-bearer-auth-proxy

Repository files navigation

Bearer Token Authentication (Reverse) Proxy

This Ruby application provides a simple bearer token authentication layer for an unprotected upstream server.

Introduction

Bearer token authorization is described in RFC 6750, e.g. https://datatracker.ietf.org/doc/html/rfc6750

In essence, bearer token authorization is a straightforward concept, yet when looking for configuration instructions for Apache or nginx, clear guidance is hard to find.

For example, a client can access a protected endpoint (/api/orders) on api.example.com, by including their bearer token (here, abc-super-secret-oh-no-now-its-not) in the Authorization header:

HTTP
GET /api/orders HTTP/1.1
Host: api.example.com
Authorization: Bearer abc-super-secret-oh-no-now-its-not

The client would have obtained this token (abc...now-its-not) through a prior process, for example, by having a regular user logging into a web application (such as github), accessing their api-tokens page, and generating a new token. The regular user would communicate this token to the team so that it becomes part of the API client configuration.

Whereas using the Authorization header with the format Authorization: Bearer is the standardized and recommended approach, there are other ways (sections 2.2 and 2.3 in the RFC), but here we only consider that usage.

So here is a reverse proxy server, written in Ruby.

Usage

Suppose you have an unprotected server running at http://localhost:12345, and you want to make it available on the wider network at port 23456.

  1. Install required ruby gems
bundle
  1. Add some authentication tokens

Run

ruby ./add_token_hash.rb >> bearer_token_hashes

Enter a few tokens, line by line.

  1. Start the app
UPSTREAM_URL=http://localhost:12345 TOKEN_HASH_FILE=./bearer_token_hashes rackup app.rb -o 0.0.0.0 -p 23456
  1. Now you can access the upstream server, but only when providing a valid token as entered in Step 1. If your server is accessible by address 192.168.1.2, this should do the trick:
curl -H 'Authentication: Bearer one-of-your-tokens-from-step-1' http://192.168.1.2:23456

You can verify that the response will be an HTTP 401 error with message, Invalid bearer token, when an invalid token is used:

curl -H 'Authentication: Bearer not-one-of-your-tokens-from-step-1' http://192.168.1.2:23456

Exercise: What happens when there is no Authentication header? Or when it doesn't have a Bearer?

Support for additional ENV entries:

HTTP_HOST. For example, with

HTTP_HOST=127.0.0.1 UPSTREAM_URL=http://localhost:12345 TOKEN_HASH_FILE=./bearer_token_hashes rackup app.rb -o 0.0.0.0 -p 23456

the HTTP_HOST value of 127.0.0.1 will be used when passing the request to the UPSTREAM_URL

Basic Auth

Since they are similar, we threw in support for "Basic" HTTP Authentication as well, see https://datatracker.ietf.org/doc/html/rfc7617 To create user name/password hash file:

ruby add_user_pwd_hash.rb > user-pwd-hashes

To start the reverse proxy server:

HTTP_HOST=localhost HTTP_BASIC_AUTH_HASH_FILE=./user-pwd-hashes UPSTREAM_URL=http://localhost:1234 rackup http_basic_auth_app.rb -p 23456

Tests

Tests can be executed with the usual rake command, or individually as in

ruby test/app_test.rb

About

An HTTP proxy supporting Bearer Authentication

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages