A server that routes authenticated requests to multiple authentication servers based on the presence of specific headers or cookies in a request.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.about.yml
.gitignore
.travis.yml
LICENSE.md
README.md
delegate.go
delegate_test.go
main.go
main_test.go
options.go
options_test.go

README.md

authdelegate Authentication Delegate Server

Build Status

Coverage Status

A server that routes authenticated requests to multiple authentication servers based on the presence of specific headers or cookies in a request.

It is compatible with the Nginx ngx_http_auth_request_module and its auth_request directive.

Use case

Imagine a static site served by nginx that contains API endpoints that should be authenticated both via bitly/oauth2_proxy (so normal users can see the JSON in a browser) and via mbland/hmacproxy (so that programs can access the endpoints via HMAC-authenticated requests). This program allows you to forward requests to both servers depending on whether any incoming request has either an Oauth2 cookie or a header containing an HMAC signature.

Note: While the primary use case is delegating auth_requests to multiple authentication servers, the authdelegate could be used to proxy requests generally.

Installation

For now, install from source:

$ go get github.com/mbland/authdelegate

Configuration and execution

The authdelegate takes a single command line argument, a path to a JSON file of configuration information. Example:

{
  "port": 8080,
  "ssl_cert": "/path/to/ssl.cert",
  "ssl_key": "/path/to/ssl.key",
  "upstreams": [
    { "url": "http://127.0.0.1/oauth2/auth",
      "cookie_name": "_oauth2_proxy"
    },
    { "url": "http://127.0.0.1/hmacproxy/auth",
      "header_name": "X-Hmac-Signature"
    },
    { "url": "http://127.0.0.1/auth"
    }
  ]
}

The arguments are:

  • port: the port number on which to run the service
  • ssl_cert (optional): path to your server's SSL certificate
  • ssl_key (optional): path to your server's SSL certificate key
  • upstreams: list of servers to which requests will be forwarded
    • url: address of the upstream server
    • header_name (optional): the name of the header that signals that requests should be sent to this server
    • cookie_name (optional): the name of the cookie that signals that requests should be sent to this server

The rules are thus:

  • If ssl_cert is specified, ssl_key must be specified as well, and vice versa.
  • There must be at least one entry in upstreams.
  • Upstream servers are checked in the order in which they are specified.
    • i.e. If a request has both a header and a cookie that matches more than one defined upstream server, it will be forwarded to the server that appears first in the list.
  • No two upstreams can specify the same header_name or cookie_name.
  • Only one of header_name or cookie_name can be specified per upstream.
  • There can be at most one upstream with neither header_namenorcookie_namespecified, and it must be the last entry inupstreams`, as all requests not matching earlier upstreams will be forwarded to this "default" upstream.
  • If there is not a default upstream, and a request does not match any other defined upstreams, a 401 response (http.StatusUnauthorized) will be returned.
  • The X-Original-URI header will be added to all forwarded requests, unless the header is already defined in the original request.

Nginx configuration

Add configuration such as the following to your nginx instance, where:

  • PORT is replaced with the port number of your service
  • myservice.com is replaced with the virtual server name for your service
  • ssl/star.myservice.com.conf contains the SSL configuration for your server.
  • http://127.0.0.1:8080 matches the address of the local authdelegate instance from above
  • The X-Original-URI header is added to the authentication request, defined using the builtin $request_uri nginx variable.
server {
  listen PORT ssl spdy;
  server_name  myservice.com;

  include ssl/star.myservice.com.conf;

  location / {
    auth_request /auth;
    auth_request_set $http_set_cookie $upstream_http_set_cookie;
    ...
  }

  location = /auth {
    internal;
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-Original-URI $request_uri;
  }
}

Accepting incoming requests over SSL

If you wish to expose the delegate directly to the public, rather than via an Nginx proxy scheme, pass the -ssl-cert and -ssl-key options along all other -auth parameters.