Collection of tips / guides for authentication on different platforms targeting University of Waterloo.
NOTE: As of 2024, the recommended mechanism for authentication is DUO OIDC. This requires IST to grant access tokens in order to function.
Getting started
NOTE: FAST Members can access fully functional examples w/ localhost client ID on gitlab.
Your domain will need valid HTTPS
Need a callback URL (usually handled by one of the solutions below.
If doing a reverse proxy to localhost on for example port 8080 it’s critical to firewall that port!
Need to contact IST for a client key via a ticket
NEW: OpenID Connect
ISS-General 2FA https://uwaterloo.atlassian.net/servicedesk/customer/portal/2/group/413/create/1660
set summery: “OIDC: add new web client“
set select topic you require assistance with: “Duo 2FA support”
set Additional comments:
## NOTE: you first need to know your callback URI ## The django module uses /oidc/duo/callback/ ## Apache uses /secure/redirect_uri Allowed URIs: - https://x.x.uwaterloo.ca/oidc/duo/callback/ - https://x-stage.x.uwaterloo.ca/oidc/duo/callback/ *group* in short format, not full DN. claims: winaccountname, group, email, name, given_name, family_name
Combining authentication with Grouper defined NEXUS groups can be a robust solution
Quick Aside: How OIDC Auth kinda works
For those new to the technology, the basic premise is as follows:
Your website sends a https request to the OIDC authentication portal using your client key/secret (this will navigate your user away from your website). Part of the request will be your callback url
Some stuff happens on the other site – usually the user will log in and then do some 2FA stuff – you don’t need to worry about it, as we trust the OIDC portal!
The portal will redirect to your callback url with an auth token – you can store this info and use parts of it to refresh itself. Honestly this bit gets a bit hairy, so if possible you should probably just use a library.
It’s possible to get AD group information sent through the token information, which can be very useful to separate roles on your website via Grouper.
OIDC development config
During development you will find it helpful to support auth on localhost. The following configuration only supports callbacks to localhost:port/oidc/duo/callback/
. We also added a handful of port numbers to keep things simple: 3000,8000,8080,8888,443,80
OIDC_AUTH_SERVER=https://sso-4ccc589b.sso.duosecurity.com/oidc/DIUHIIU5GLVCYFDLE7P7/ OIDC_CLIENT_ID=DIUHIIU5GLVCYFDLE7P7 OIDC_CLIENT_SECRET=TODO: ask mirko for key.. or perhaps we share it? OIDC_CALLBACK=/oidc/duo/callback/
OIDC with Apache (mod_auth_openidc)
You can set up OIDC directly on your Apache / httpd server. This allows you to handle authentication outside of the application itself, and instead push REMOTE_USER to your apps for validating users.
Install Apache module (debian/ubuntu)
apt install -y libapache2-mod-auth-openidc # enable module a2enmod auth_openidc
Configure the module and a basic VirtualHost
# For advanced options see: https://github.com/OpenIDC/mod_auth_openidc <IfModule mod_auth_openidc.c> # If you have an ingress proxy like Caddy you'll need the following # respect X-Forwarded-* headers passed down from proxy OIDCXForwardedHeaders X-Forwarded-Proto X-Forwarded-Host # this personal secret is created by you and never shared! OIDCCryptoPassphrase XXXXXXXXXXX_PERSONAL_SECRET_XXXXXXXXXXX # after successfull login redirect the user to where they wanted to go # this path needs to openid-connect protected on your host OIDCRedirectURI https://myhost.fast.uwaterloo.ca/oidc-callback/redirect_uri OIDCProviderMetadataURL https://sso-4ccc589b.sso.duosecurity.com/oidc/XXXXXXXXXXXXXXXXXXXX/.well-known/openid-configuration OIDCClientID XXXXXXXXXXXXXXXXXXXX OIDCClientSecret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # NOTE: you can find scopes in the the OIDCProviderMetadataURL OIDCScope "openid profile email" OIDCRemoteUserClaim user # use HTTP_ prefix so env vars are more trusted in CGI. "see: suexec safe_env_lst" OIDCClaimPrefix HTTP_OIDC_CLAIM_ # WARN: default delimiter is comma. AD groups can contain commas! (":" is safer) OIDCClaimDelimiter ":" OIDCCacheShmEntrySizeMax 270848 </IfModule> # Assuming handling https on an ingress server like Caddy. # Also port 80 is firewalled to only talk to your ingress server. <VirtualHost _default_:80> ServerName myhost.fast.uwaterloo.ca ServerAlias myhost-stage.fast.uwaterloo.ca # NOTE: this is needed for the OIDCRedirectURI callback <Location /oidc-callback> AuthType openid-connect Require valid-user </Location> # example: only allow IdM-HR-staff users <Location /staff> AuthType openid-connect Require claim group:IdM-HR-staff </Location> # example: require user to be in two groups <Location /staff-admin> AuthType openid-connect # each require is an OR. If you want AND, use RequireAll: <RequireAll> Require claim group:IdM-HR-staff Require claim group:myhost-admin </RequireAll> # TODO: this might also work # Require claim "group:myhost-admin group:IdM-HR-staff" </Location> <Location / > AuthType openid-connect Require valid-user # if you have a simple backend to proxy to ProxyPreserveHost On ProxyPass 127.0.0.1:8080 </Location> </VirtualHost>
OIDC in Django - django-oidc-auth
django-oidc-auth is a library maintained by Mirko Vucicevich , Ryan Goggin and Steve Weber for simple OIDC auth via Django. It requires Django >= 3 and python >=3.9 (as of Feb 2024)
For the simplest configuration follow the instructions in the provided README.md, as the software has been designed and tested with campus OIDC configurations.
ADFS (Active Directory) Deprecated Auth Guides
New projects should avoid using ADFS directly if possible, and use DUO OIDC instead. This documentation is here for reference.