Notice
The examples and use cases described here are intended to show the different ways SURF Research Access Management can be used and connected to application. These examples and use cases are not always validated by SURF.
SURF Research Access management is built on standards like SAML and OpenID Connect to authenticate and authorise users to applications. However, when applications can not be configured to support either of these protocols, a last resort solution is available in the form of a Reverse Proxy if the application can be configured to accept authentication and/or authorisation via HTTP request headers or the REMOTE_USER
environment variable.
HTTP Request headers
HTTP Request headers are a part of the data that (web) clients send to a web-application when creating a request. Normally it would be unwise to use, let alone trust these headers as anyone who is a little technically inclined can inject these headers in every request and thus could impersonate every user on the platform. Thus, using HTTP Request headers should only be used when received from a trusted source.
REMOTE_USER environment
When a (web) application does not support accepting authentication and authorisation information from the request headers, it sometimes can be configured to acceptexternal authentication using the REMOTE_USER
environment variable. The environment is a part of the context in which the web application runs and can be controlled by the server that serves that web application. It is, again, imperative that this environment is trusted and the variables used can only be set by a trusted party.
Reverse Proxy
Both solutions mentioned above require a trusted system, which is where the reverse proxy comes in. The reverse proxy is a web server that, on one hand, is connected to the external network which receives non-trusted user requests and which is capable of authenticating the user using SAML or OpenID Connect (OIDC) using plugins or modules. One example of such a webserver is Apache. Apache can be configured to require a successful OIDC-login before certain resources (endpoints) on the server are accessible to the end-user.
When the Apache webserver is running as a stand-alone server, it can manipulate the environment of the application and inject information originating from the OIDC or SAML authentication, for example by inserting the username of the authenticated user into the REMOTE_USER
variable. The application, in turn, can make appropriate authorisation decisions based on the value(s) in the REMOTE_USER environments variable(s).
The (Apache) webserver can also forward external requests to a back-end application server and return the response to the client as if it were server from the server itself. This is called a reverse proxy. In reverse proxy mode, the webserver can inject extra information in the back-end request in the form of HTTP request headers. If we make sure the backend server can only be reached by the reverse proxy, we can safely trust the information in the HTTP request headers to authenticate and authorise the user that is requesting the application.
Security
I should be clear from the above that it is important that the secured resource is only accessible from the reverse proxy and that the reverse proxy correctly takes care of protecting (all) endpoints that fall under the reverse proxy configuration. Also, accepting headers that can be manipulated by the client is dangerous so the configuration should explicitly unset any incoming header before assigning the required values.
Apache OIDC module mod_auth_openidc
This section gives an example setup for the Apache webserver using the mod_auth_openidc
module. This module can be downloaded from https://github.com/zmartzone/mod_auth_openidc/ but is also available by default on all major Linux distributions.
A generic VirtualHost configuration using this module might look something like this:
LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so <VirtualHost *:80> ServerName mysite.example.edu DocumentRoot /var/www/html OIDCProviderMetadataURL https://proxy.sram.eduteams.org/.well-known/openid-configuration OIDCClientID oidc_client_id OIDCClientSecret oidc_client_secret OIDCResponseType "code" OIDCResponseMode "query" OIDCScope "openid profile" OIDCRedirectURI http://mysite.example.edu/redirect_uri OIDCCryptoPassphrase random_passphrase # Enable Reverse Proxy ProxyRequests On ProxyPreserveHost on # Authentication Header RequestHeader unset X-Authenticated-User RequestHeader unset X-Authenticated-Name RequestHeader set X-Authenticated-User expr=%{ENV:OIDC_CLAIM_sub} RequestHeader set X-Authenticated-Name expr=%{ENV:OIDC_CLAIM_sub} <Location /> AuthType openid-connect Require valid-user ProxyPassMatch http://172.22.11.1:8000/ ProxyPassReverse http://172.22.11.1:8000/ </Location> </VirtualHost>
An line by line explanation follows:
- Line 1: Loads the moduel for OIDC authentication
- Lines 2-4: Sets up a virtual host for the site
mysite.example.edu
- Lines 6-14: Set up OIDC authentication. The different settings may differ for different OIDC OPs, and should be provided by your OP
- Lines 16-18: Enable the reverse proxy; further configuration is done below
- Lines 20-24: First explicitly unset the authentication headers the web server receives from the user's browser, and then fill them with values provided by the OIDC authentication module. Note that the can use any header names here, depending on what you application accepts. These headers will be sent to the backend application configrues in lines 29-30
- Lines 27-28: Force OIDC authentication for all URLs (everything under
/
). - Lines 29-30: Configure the proxy mapping: pass all URLs to the application running on
http://172.22.11.1:8000/
Note that this is merely an example. To use this in production, you should make sure that the OIDC connection (to SRAM or another OP) uis set up correctly, and you should make sure that HTTPS is setup correctly for your web server (this is not shown in the example above)
Apache SAML module mod_auth_mellon
This section contain a similar example using the mod_auth_mellon
module, which provides SAML2-based authentication. Note that the mod_auth_mellon
module requires a bit more configuration, but that the structure of the configuration is similar to the OIDC case: set up the cirtual host, set up the authentication, fill the varaibles from the authenticaiotn date, set up the reverse proxy.
https://github.com/latchset/mod_auth_mellon
LoadModule auth_mellon_module /usr/lib64/httpd/modules/mod_auth_mellon.so <VirtualHost *:80> ServerName mysite.example.edu DocumentRoot /var/www/html MellonCacheSize 100 MellonLockFile "/var/run/mod_auth_mellon.lock" MellonPostTTL 900 MellonPostSize 1048576 MellonPostCount 100 MellonDiagnosticsFile logs/mellon_diagnostics MellonDiagnosticsEnable Off # Enable Reverse Proxy ProxyRequests On ProxyPreserveHost on # Authentication Header RequestHeader unset X-Authenticated-User RequestHeader unset X-Authenticated-Name RequestHeader set X-Authenticated-User %{MELLON_user}e env=MELLON_user RequestHeader set X-Authenticated-Name %{MELLON_username}e env=MELLON_username <Location /> AuthType Mellon Require valid-user MellonEnable "auth" MellonVariable "cookie" MellonCookiePath / MellonUser "urn:oid:1.3.6.1.4.1.5923.1.1.1.6" MellonSessionDump Off MellonSamlResponseDump Off MellonEndpointPath "/mellon" MellonDefaultLoginPath "/" MellonSessionLength 86400 MellonIdPMetadataFile /etc/httpd/mellon/idp-metadata.xml ProxyPassMatch http://172.22.11.1:8000/ ProxyPassReverse http://172.22.11.1:8000/ </Location> </VirtualHost>