The university provides a login service, used by both University and third party services. It uses Shibboleth, like most universities. There is some support "documentation" for this provided at https://warwick.ac.uk/services/its/servicessupport/web/sign-on/development/.
ITS provide a number of ways to run apps using SSO:
Before we get into requests and the technical details, it's best to cover some basic terminology first. Like much of this page, I have shamelessly ripped it from the Cambridge UIS documentation (don't worry, it has an MIT license), which you should probably read https://docs.raven.cam.ac.uk/en/latest/raven-saml2/
The SAML 2.0 ecosystem has some terminology associated with it:
The easiest way to get an idea of how SAML2 works is by tracing the requests in a web browser. They're in some annoying XML format, so I'd recommend using a browser extension like SAML Tracer. Most SAML requests are encrypted so you won't know what's happening, but the UWCS Keycloak one's aren't, making them a good example.
The SP sends a POST request (this can be a GET if both sides are configured to do that instead) to the IdP, requesting authorisation. This goes to https://idp.warwick.ac.uk/idp/profile/SAML2/POST/SSO
. The request has a AssertionConsumerServiceURL pointing back to the SP, in this case https://auth.uwcs.co.uk/realms/uwcs/broker/warwick_sso/endpoint
. It also contains the issuer, which is the Entity ID - in this case https://uwcs.co.uk/sso/warwick
.
The IdP does it's own thing - in Warwick SSO's case, this is asking the user to allow the app to receive the requested attributes, or if they've already done this, it just redirects immediately to the next step.
The IdP sends a POST request back to the SP, to the URL provided earlier. This time the request has a big signiature proving it's real, and also what we actually needed - the attributes.
The SP takes the attributes and does what it wants with them.
All in all, the actual process is very simple, once set up.
Both the SP and IdP can share their various connection specifiations through what's called metadata. This is usually available at a URL, often the Entity ID, and has a few important bits of info.
The Warwick IdP one is at https://idp.warwick.ac.uk/idp/shibboleth, and shares the supported protocols and associated URLs, and the X509 certificates. Theoretically the metadata can be used to fill in the settings on the SP side, but Keycloak didn't seem to support this, so we did it by hand.
The SP also shares metadata, with ours at https://auth.uwcs.co.uk/realms/uwcs/broker/warwick_sso/endpoint/descriptor. This contains a key for encrypting responses, our entityID, the assertion (request) consumer URL endpoint, and our requested attributes.
While Cambridge have a nice self-service form for submitting this, at Warwick the process is much more manual, involving emailing the helpdesk with your Metadata URL and requested attributes. You should also tell them if you require the service to be on the encryption exemption list.
While much of this could be taken from the metadata, it appears to be a manual process for some reason.
The full list of possible attributes is available at https://warwick.ac.uk/services/its/servicessupport/web/sign-on/development/reference/attributes/. Realistically, you might want the Uni ID, Email, First Name, Surname, and Department of someone. The names provided at the user's preferred name, which you should keep up to date in your application, in case of name changes.
On the ITS side the attribute rules look something like this:
<AttributeFilterPolicy id="releaseToUwcs">
<PolicyRequirementRule xsi:type="OR">
<Rule xsi:type="Requester" value="https://staging.uwcs.co.uk/sso/warwick/" />
<Rule xsi:type="Requester" value="https://uwcs.co.uk/sso/warwick/" />
</PolicyRequirementRule>
<AttributeRule attributeID="universityNumberUnscoped">
<PermitValueRule xsi:type="ANY" />
</AttributeRule>
<AttributeRule attributeID="givenName">
<PermitValueRule xsi:type="ANY" />
</AttributeRule>
<AttributeRule attributeID="surname">
<PermitValueRule xsi:type="ANY" />
</AttributeRule>
<AttributeRule attributeID="mail">
<PermitValueRule xsi:type="ANY" />
</AttributeRule>
...
</AttributeFilterPolicy>
These attributes are then returned by SAML as:
<saml2:AttributeStatement>
<saml2:Attribute FriendlyName="surname"
Name="urn:oid:2.5.4.4"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>Bloggs</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="givenName"
Name="urn:oid:2.5.4.42"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>Joe</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="mail"
Name="urn:oid:0.9.2342.19200300.100.1.3"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>Joe.Bloggs@warwick.ac.uk</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="eduPersonAffiliation"
Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>student</saml2:AttributeValue>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>member</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="deptcodeAttr"
Name="deptcode"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>CS</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="universityNumberUnscoped"
Name="UniversityIDUnscoped"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>2000000</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
The key thing here is that the rules are tied to the entityID and do not get updated when your metadata changes. Also, the requested attributes in the metadata appear to have no influence over this!
As mentioned before, some information is taken from the metadata. As far as I can tell, this includes:
The metadata gets re-downloaded every 24 hours, starting from when the Shibboleth server was started.
These are the settings we have set, enabling Warwick SSO as an IdP in Keycloak. You can probably change some of these to match your usage/preferences.
Identity provider entity ID - https://idp.warwick.ac.uk/idp/shibboleth
Single Sign-On service URL - https://idp.warwick.ac.uk/idp/profile/SAML2/POST/SSO
NameID policy format - Unspecified
Principal type - Attribute [Name]
Principal attribute - UniversityIDUnscoped
HTTP-POST binding response - On
HTTP-POST binding for AuthnRequest - On
HTTP-POST binding logout - Off
Want AuthnRequests signed - Off
Want Assertions signed - On
Want Assertions encrypted - Off
Validate Signatures - Off
Sign service provider metadata - On
Pass subject - On
We also have attribute mappers setup like so:
Mapper Type - Attribute Importer
Name/ID - whatever you think seems right
Sync mode override - depends on attribute, 'force' for those which are not user changable
Attribute Name/Friendly Name - as provided in the SAML response XML (see above)
Name Format - ATTRIBUTE_FORMAT_BASIC
User Attribute Name - email, lastName, firstName, and whatever seems appropriate for the rest
noEncryptionSPs
settings are hard-coded and will not update with your metadata. Alternatively, tell ITS that your entity ID has changedHere's some general info provided by ITS in 2021 (not available on the website from what I can find)
At Warwick, we have a Shibboleth IdP instance running over at https://idp.warwick.ac.uk/
Metadata is available here: https://idp.warwick.ac.uk/idp/shibboleth
Further details:EntityID: https://idp.warwick.ac.uk/idp/shibboleth (test: https://idp-test.warwick.ac.uk/idp/shibboleth)
Shibboleth metdata type: SAML 2.0
Standard attribute friendly names and URNs:
Username: eduPersonPrincipalName (urn:oid:1.3.6.1.4.1.5923.1.1.1.6)
First name: givenName (urn:oid:2.5.4.42)
Last name: surname (urn:oid:2.5.4.4)
Email address: email (urn:oid:0.9.2342.19200300.100.1.3)Users must provide explicit consent for these attributes to be released to external service providers at authentication-time: https://warwick.ac.uk/services/its/servicessupport/web/sign-on/idp-consent/
We can release other attributes or implement additional bespoke logic as part of the attribute filtering process. Please tell us if this is required.
If possible, instead of using the static copy of our metadata could you please set up your SP to maintain a periodically updated copy from https://idp.warwick.ac.uk/idp/shibboleth (for test, https://idp-test.warwick.ac.uk/idp/shibboleth).
It would avoid future issues where our metadata changes (certificates etc.) as you would get the updates automatically.
To get started, the software engineering team will need a copy of the metadata for the relying party (i.e. service provider), at which point we would share some test credentials so that you can check the authentication flow against the idp-test instance. You'd need to send us this via ServiceNow. Once everyone is content that things are working, we would deploy to production.