Configuring the Apache web server for Raven OAuth2¶
This page follows on from the first steps page and peeks behind the scenes a bit about how our example web server is configured. By doing so you will learn how to configure the Apache web server to require Raven authentication when visiting a site.
Prerequisites¶
This guide is written assuming you have completed the first steps guide, that you have had some experience with the Linux command line and have configured an Apache web server before.
In order to add Raven authentication to a website you will need to make sure that the mod_auth_openidc is Apache module is installed on your server. If you are running a Debian or Ubuntu server this is provided by the libapache2-mod-auth-openidc package which can be installed via apt-get
. Other Linux distributions will require an alternative install command, such as yum install mod_auth_openidc
.
In this guide we will make use of a pre-built Docker container based on Ubuntu.
Fetching and building the container image¶
We will be making use of Play with Docker as we did on the first steps page. If you haven't done so already make sure now that:
- You have created a Play with Docker instance.
- You have set the
CLIENT_ID
andCLIENT_SECRET
environment variables to out OAuth2 client credentials.
Previously we made use of a pre-built container to demonstrate Raven integration. Now we will build our own.
Use the git
command line tool to fetch the Raven documentation samples and move into the apache-oauth2
directory:
git clone https://gitlab.developers.cam.ac.uk/uis/devops/iam/authentication/doc-samples.git
cd doc-samples/apache-oauth2
Build a new container image called my-server
:
docker build -t my-server .
Run the web-server just as you did on the first steps page except using your new image name:
docker run --rm -it -e CLIENT_ID -e CLIENT_SECRET -p 8000:80 my-server
Important
Make sure you have set the CLIENT_ID
and CLIENT_SECRET
environment variables.
Experiment with the container¶
Since you are now building the container yourself, you can experiment with changing how it is configured.
- Press Ctrl-C in the Play with Docker window to stop the web server.
- Click the editor button and navigate to
/root/doc-samples/apache-oauth2/htdocs
. - Click on index.shtml to edit the code of the example web page.
- Change the word "Congratulations" to "Well done".
- The Play with Docker editor changes the permissions on files it edits so, back in the Play with Docker terminal window, use the following command to restore them:
chmod -R oug+r htdocs/
Try re-building and re-running the web server:
docker build -t my-server .
docker run --rm -it -e CLIENT_ID -e CLIENT_SECRET -p 8000:80 my-server
If you visit the link next to the open port button, you should see that the message is different from the one you got when following the steps on the first steps page.
A tour of the container¶
Now you are familiar with how to modify the container configuration, you can experiment with the container setup to gain some familiarity with it. Don't worry if you've never used docker before. We'll now go on a tour of how the container works its magic.
Installing mod_auth_openidc¶
The Dockerfile describes the steps to set up the container. We start from a base Ubuntu install. We run a number of basic system configuration commands but the main commands which install and configure mod_auth_openidc are as follows:
apt-get install apache2 libapache2-mod-auth-openidc
a2enmod auth_openidc
Configuring mod_auth_openidc¶
The Apache web server supports serving multiple websites from the same server. Each website is usually configured with a <VirtualHost>
section in the Apache configuration file.
The configuration for our protected site can be found within the sites/protected.conf file. The mod_auth_openidc module is configured using directives which start OIDC...
.
OpenID connect metadata URL¶
The OpenID Connect specification describes a way to auto-configure a number of the OAuth2 parameters for a particular authentication server. We can use the OIDCProviderMetadataURL
directive to specify the appropriate metadata configuration URL for Raven:
# Raven OAuth2 is provided by Google. This URL provides metadata which
# auto-configures some OAuth2 parameters.
OIDCProviderMetadataURL \
https://accounts.google.com/.well-known/openid-configuration
OAuth2 client credentials¶
The OIDCClientID
and OIDCClientSecret
directives let you specify the OAuth2 client credentials for your site. In our container we load them from the CLIENT_ID
and CLIENT_SECRET
environment variables but you can specify them directly in your configuration if you wish:
# OAuth2 client application.
OIDCClientID "some-client-id"
OIDCClientSecret "some-client-secret"
Redirect URI¶
When a website wants to cause a user to sign in, it redirects them to Raven. Raven, in turn, needs to know where to redirect the user back to after they have authenticated. This is a special URL on your site known as the "redirect URI".
It doesn't matter what you choose as a redirect URI as long as it doesn't conflict with any other URL on your website. A good choice is /.oidc/redirect
.
Our example container allows the redirect URI to be customised with an environment variable but you can specify it directly in the configuration if you wish:
# Redirect URI claimed by mod_auth_openidc. This should not be any URL used by
# the site you're protecting. A good choice is usually something like
# "/.oidc/redirect".
OIDCRedirectURI "/.oidc/redirect"
Session cookie passphrase¶
It would be tiresome in the extreme if each time a visitor to your site navigated around it they were prompted for their Raven credentials. To prevent this mod_auth_openidc
keeps a special value in a "session cookie" which a user's web browser presents to the web server on each visit to identify them. To make sure that this cookie can't be faked, it is encrypted with a secret value you configure in the web server.
This value should ideally be a long random string. The container generates a different passphrase each time it is run but in production you should use a fixed value and add it to the Apache configuration using the OIDCCryptoPassphrase
directive:
# Crypto passphrase for session cookie. This is used to encrypt a session
# cookie which allows users to re-visit your site once signed in without
# having to present their Raven credentials again.
OIDCCryptoPassphrase "e3b0c44298fc1c149996fb92427ae41e4649b934ca495991b7852b855"
Info
The container uses a little bit of Unix command line trickery to generate the passphrase. Try it yourself in the Play with Docker terminal:
dd if=/dev/urandom of=/dev/stdout count=100 2>/dev/null | sha256sum - | cut -f1 -d ' '
In production, you should make use of whatever secure token generation system you currently use.
Token request parameters¶
The OAuth2 standard allows for websites to make special requests about sign ins. For example they could request that a user always be asked for their password even if they have signed in before. Raven OAuth2 uses the hd
parameter to signal that a website only wants users with @cam.ac.uk
email addresses. The parameters are set via the OIDCAuthRequestParams
directive:
# OAuth2 token request parameters. Use "hd=cam.ac.uk" to request the Raven
# login box.
OIDCAuthRequestParams "hd=cam.ac.uk"
If you don't set the hd
parameter you will get a generic Google login box. This may be what you want if you want offer sign in to both the public and Raven account holders.
OAuth2 scopes¶
In the OAuth2 protocol, "scope" refers to the set of things a server wants to be able to do on behalf of a user. To get the @cam.ac.uk
email address for the user in you only need the "email" scope. To get other basic information on a user such as name and profile picture you need the "openid" and "profile" scopes. Generally it is best to specify all three. Do this via the OIDCScope
directive:
# Scopes indicating the information we want back from Raven.
OIDCScope "openid email profile"
Remote user¶
Apache supports the concept of a "remote user" which some applications use to automatically create user accounts when a user signs in. If your application makes use of this feature, you can configure mod_auth_openidc to use the user's email address as their username via the OIDCRemoteUserClaim
directive:
# Some sites look at the "remote user" setting in Apache to determine the
# username which should be used. Set this to the user's "@cam.ac.uk" email
# address.
OIDCRemoteUserClaim email
Tip
It is possible to perform some regular expression trickery with OIDCRemoteUserClaim
to strip the domain-name part of the email address off. This is not recommended since, as described in the Raven "golden rules", it reduces your ability to allows users without CRSids to use your site.
Requiring sign in¶
Configuring mod_auth_openidc does not actually cause the website to be Raven enabled. You must explicitly specify locations within a site which require sign in. To protect the entire site you can use the following <Location>
section which should be within the appropriate <VirtualHost>
section:
# Protect entire site with Raven authentication.
<Location />
# Use OIDC authentication - ESSENTIAL FOR RAVEN WORKFLOW
AuthType openid-connect
<RequireAll>
# Require that authentication succeeded.
Require valid-user
# Require that the user be a Raven user.
#
# THIS CHECK IS REQUIRED TO STOP ANYONE WITH A PUBLIC GOOGLE ACCOUNT
# FROM SIGNING IN TO YOUR SITE.
Require claim "hd:cam.ac.uk"
</RequireAll>
</Location>
Always check the hd
claim
Great sites follow the Raven "golden rules". Although you can set the hd
request parameter via OIDCAuthRequestParams
, a clever user could modify the request in their browser and request sign in for any public Google account. Unless you check the hd
claim in the response from Raven you are essentially letting anyone on the Web access your site.
Next steps¶
On this page you learned how to build and customise the example Apache container. You saw all the mod_auth_openidc configuration directives required to configure Raven sign in and you saw how to require sign in for an entire web site.
Remember to read the Raven golden rules when configuring your website.
The complete list of configuration directives for mod_auth_openidc is available if you want to find out more.