HTTP proxy for authenticating users via OAuth2
|Latest on Hackage:||0.9.9|
Sproxy - HTTP proxy for authenticating users via OAuth2
Why use a proxy for doing OAuth? Isn't that up to the application?
- sproxy is secure by default. No requests make it to the web server if they haven't been explicitly whitelisted.
- sproxy is independent. Any web application written in any language can use it.
Existing web applications with concept of roles. For example, Mediawiki, Jenkins, Icinga Web 2. In this case you configure Sproxy to allow unrestricted access to the application for some groups defined by Sproxy. These groups are mapped to the application roles. There is a plugin for Jenkins which can be used for this. Mediawiki and Icinga Web 2 were also successfully deployed in this way, though it required changes to their source code.
New web applications designed to work specifically behind Sproxy. In this case you define Sproxy rules to control access to the application's API. It would likely be a single-page application. Examples are MyWatch and Juan de la Cosa
How it works
From that point on, when sproxy detects a valid session cookie it extracts the email, checks it against the access rules, and relays the request to the back-end server (if allowed).
Hitting the endpoint
/sproxy/logout will invalidate the session cookie.
The user will be redirected to
/ after logout. The query parameter
can be provided to specify an alternate URL-encoded redirect path
Since all sproxied resources are private, it doesn't make sense for web
crawlers to try to index them. In fact, crawlers will index only the login
page. To prevent this, sproxy returns the following for
User-agent: * Disallow: /
Permissions are stored in a PostgreSQL database. See sproxy.sql for details. Here are the main concepts:
groupis identified by a name. Every group has - members (identified by email address, through
group_member) and - associated privileges (through
privilegeis identified by a name and a domain. It has associated rules (through
privilege_rule) that define what the privilege gives access to.
ruleis a combination of sql patterns for a
pathand an HTTP
method. A rule matches an HTTP request, if all of these components match the respective attributes of the request. However of all the matching rules only the rule with the longest
pathpattern will be used to determine whether a user is allowed to perform a request. This is often a bit surprising, please see the following example:
group | privilege | domain
---------------- | --------- | -----------------
privilege | domain | path | method
----------- | ----------------- | -------------- | ------
With this setup, everybody (that is
will have access to e.g.
/favicon.ico, but only
administrators will have access to
/admin/index.php, because the longest
matching path pattern is
/admin/% and only
administrators have the
readers have no access to e.g.
HTTP headers passed to the back-end server:
header | value
-------------------- | -----
From: | visitor's email address
X-Groups: | all groups that granted access to this resource, separated by commas (see the note below)
X-Given-Name: | the visitor's given (first) name
X-Family-Name: | the visitor's family (last) name
X-Forwarded-Proto: | the visitor's protocol of an HTTP request, always
X-Forwarded-For | the visitor's IP address (added to the end of the list if header is already present in client request)
X-Groups denotes an intersection of the groups the visitor belongs to and the groups that granted access:
Visitor's groups | Granted groups |
---------------- | -------------- | ---------
all | all, devops | all
all, devops | all | all
all, devops | all, devops | all,devops
all, devops | devops | devops
devops | all, devops | devops
devops | all | Access denied
sproxy will read its configuration from
config/sproxy.yml. There is example file with documentation
config/sproxy.yml.example. You can specify a
custom path with:
sproxy --config /path/to/sproxy.yml
- This is the last release of this Sproxy. See Sproxy2.
- Google: prompt for account only, don't ask for offline access.
- If the user is not authenticated, show login page with HTTP status code 511, instead of 302 -> 200. It had bad UX for AJAX calls.
- Always convert authenticated user's email to lowercase. This affects the
cookie and the
- Stop using the
- Print authentication code in debug mode only.
Fixed cabal source distribution
Added support for LinkedIn OAuth2 API. Added new options
linkedin_client_secret. They are optional as well as Google's
client_secret. The user is now redirected to the
sproxy/loginpage to choose an OAuth2 provider.
- Session shelf life is configurable with the
session_shelf_lifeoption in configuration file. Defaults to 30 days. It was hard-coded before.
- Dropped dependency on
logging-facade(fail to build). Log to stderr only, log levels: error, warning, info, debug. The
log_targetoption is ignored.
- Allow running as unprivileged user: added option
userin the configuration file.
- Default log level is
debugif omitted in the configuration file.
- Combine the multiple header fields into one "field-name: field-value" pair with a comma-separated list for the field-value (Instead of removing duplicates).
sproxy [ -h | --help ]works (using docopt)
- Stop counting client parsing failures as errors.
- Made some options in configuration file optional with reasonable default values:
redirect_http_to_https: yes if
listen == 443-
- Allow backend at UNIX socket: new option
- Removed tests (unsupported).
- Don't build Sproxy library.
- Deny SSLv3.
- Removed the
auth_token_keyoption from the config file. The token is generated randomly on startup. Restarting sproxy invalidates existing sessions.