NginxOmniauthAdapter - Use omniauth for nginx auth_request
Use omniauth for your nginx's authentication via ngx_http_auth_request_module.
NginxOmniauthAdapter provides small Rack app (built with Sinatra) for auth_request
.
Prerequisite
- nginx with ngx_http_auth_request_module
Quick example
$ bundle install
$ cd example/
$ foreman start
http://ngx-auth-test.lo.nkmiusercontent.com:18080/
(make sure to have nginx on your PATH)
Usage
Steps
- Start adapter app with proper configuration
- enable
auth_request
and add some endpoints on nginx
- See
example/nginx-site.conf
for nginx configuration.
Running with Rubygems
# Gemfile
gem 'nginx_omniauth_adapter'
Then write config.ru
then deploy it. (see ./config.ru for example)
Using docker
- Prebuilt: https://quay.io/repository/sorah/nginx_omniauth_adapter
- Own your risk.
- They're built at circleci
- Build manually: checkout this repo and run
docker build .
.- Much safer.
- But if you can't trust upstream image
quay.io/sorah/rbenv:2.2
, write your own Dockerfile. This is just a simple Rack app.
Configuration
environment variable is available only on included config.ru (or Docker image).
-
:providers
: omniauth provider names. -
:provider_http_header
$NGX_OMNIAUTH_PROVIDER_HTTP_HEADER
(string): Name of HTTP header to specify OmniAuth provider to be used (see below). Defaults to 'x-ngx-omniauth-provider`. -
:secret
$NGX_OMNIAUTH_SESSION_SECRET
: Rack session secret. Should be set when not on dev mode -
:host
$NGX_OMNIAUTH_HOST
: URL of adapter. This is used for redirection. Should include protocol (e.g.http://example.com
.)- If this is not specified, adapter will perform redirect using given
Host
header.
- If this is not specified, adapter will perform redirect using given
-
:allowed_app_callback_url
$NGX_OMNIAUTH_ALLOWED_APP_CALLBACK_URL
(regexp): If specified, URL only matches to this are allowed for app callback url. -
:allowed_back_to_url
$NGX_OMNIAUTH_ALLOWED_BACK_TO_URL
(regexp): If specified, URL only matches to this are allowed for back_to url. -
:app_refresh_interval
NGX_OMNIAUTH_APP_REFRESH_INTERVAL
(integer): Interval to require refresh session cookie on app domain (in second, default 1 day). -
:adapter_refresh_interval
NGX_OMNIAUTH_ADAPTER_REFRESH_INTERVAL
(integer): Interval to require re-logging in on adapter domain (in second, default 3 days).
Working with multiple OmniAuth providers
When multiple providers are passed to :providers
, nginx_omniauth_adapter defaults to the first one in list.
Other providers in list will only be activated for requests with x-ngx-omniauth-provider
header (key is configurable via :provider_http_header
).
Included config.ru (or Docker)
You can set configuration via environment variables.
The following variables are only available on included config.ru:
-
$NGX_OMNIAUTH_SESSION_COOKIE_NAME
: session cookie name (defaultngx_omniauth
) -
$NGX_OMNIAUTH_SESSION_COOKIE_TIMEOUT
: session cookie expiry (default 3 days) -
$NGX_OMNIAUTH_DEV=1
or$RACK_ENV=development
- enable dev mode (omniauth developer provider)
- github provider
-
$NGX_OMNIAUTH_GITHUB_KEY
,$NGX_OMNIAUTH_GITHUB_SECRET
: application key + secret. -
$NGX_OMNIAUTH_GITHUB_HOST
: (optional) Set if you'd like to use GitHub Enterprise instance (e.g.https://YOUR-GITHUB-ENTERPRISE
) -
$NGX_OMNIAUTH_GITHUB_TEAMS
: (optional) Restrict to specified teams (e.g.awesomeorganization/owners
)
-
- google_oauth2 provider
-
$NGX_OMNIAUTH_GOOGLE_KEY
,$NGX_OMNIAUTH_GOOGLE_SECRET
: oauth2 key + secret. -
$NGX_OMNIAUTH_GOOGLE_HD
: (optional) Restrict to specified hosted domain (Google Apps Domain).
-
Manually (Rack)
If you're going to write config.ru
from scratch, make sure:
- OmniAuth is included in middleware stack
- Rack session is enabled in middleware stack
Then run:
run NginxOmniauthAdapter.app(
providers: %i(developer),
secret: secret_base64, # optional
# ... (set more configuration, see above variable list)
)
How it works
-
browser access to restricted area (where
auth_request
has enabled) -
nginx sends subrequest to
/_auth/challenge
. It will be proxied to adapter app (GET /test
) -
adapter app
/test
returns 401 when request (browser) doesn't have valid cookie -
nginx handles 401 with
error_page
, so do internal redirection (/_auth/initiate
) -
nginx handles
/_auth/initiate
. It will be proxied to adapter appGET /initiate
.
- Also nginx passes some information for callback to adapter app.
-
x-ngx-omniauth-initiate-back-to
URL to back after logged in -
x-ngx-omniauth-initiate-callback
URL that proxies to adapter app/callback
. This must be same domain to backend app for cookie.
-
adapter app
GET /initiate
redirects to/auth/:provider
. - Browser do some authenticate in adapter app with Omniauth.
-
adapter app's omniauth callback sets valid session, then redirects to
/_auth/callback
, where specified atx-ngx-omniauth-initiate-callback
.
-
Adapter app gives GET parameter named
session
on redirect. It contains encrypted session.
-
nginx handles
/_auth/callback
. It will be proxied to adapter app/callback
.
- This decrypts given encrypted session string and set to cookie.
- Then redirect to
x-ngx-omniauth-initiate-back-to
.
- browser backs to URL where attempted to access first, at step 1.
-
nginx sends auth subrequest to backend app
/test
. -
backend app
/test
returns 200, because request has valid session cookie. - nginx returns response as usual.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/sorah/nginx_omniauth_adapter.
License
The gem is available as open source under the terms of the MIT License.