The document provides an overview of how to setup and configure OKTA with a test Shibboleth sP (Service Provider) instance with a example site which is secured using OKTA. It can be used to explore how OKTA and Shibboleth sP interact with the SAML assertion exchange. The deployment is simple and provides the following:
An AWS VPC, with an EC2 instance that will act as the Shibboleth sP and host the test website.
OKTA Application acting as the IdP (Identity Provider) to allow the Shibboleth sP to authenticate with the IdP to allow user access to the test website. OR
Open Athens acting as the IdP (Identity Provider) to allow the Shibboleth sP to authenticate with the IdP to allow user access to the test website.
The example site used a domain called www.domain.com, but you may choose to use another domain, additionally in this example the domain has its Name Servers (NS) within AWS Route53, again this not essential, nor is using AWS for running the test instance, it was chosen being its an easy method to spin something up rapidly for testing. Terraform was used to deploy the instance, however you could configure this manually, additionally no fancy Terraform state management is used, this is just stored locally. Additionally the steps are manual, although they could be automated if required, however for the purposes of this document, exposing these steps gives a more rounded learning and understanding of the approach and the mechanisms involved.
Option 1 – Example Site Authenticated with OKTA and Shibboleth sP
An example configuration that allows you to authenticate a test website using Shibboleth sP with OKTA as the IdP. There are another section where we explore the configuration for using the Shibboleth sP, but instead using Open Athens as the IdP.
Deploy the Instance
Ensure you have the a workstation with Terraform and the AWS CLI installed, and you have the Terraform script(s) downloaded from the below:
Terraform: https://github.com/tristanhself/general/tree/master/aws/test-sp
So now we deploy the instance with:
cd test-sP
terraform apply --auto--approve
Once the instance has been deployed, retrieve its ID from the AWS console (or CLI) and then connect to it via SSM so you can get a BASH prompt.
aws ssm start-session --target <instance-ID>
Perform Apache Install and Configuration
You’ll now need to install Apache including the various rewrite modules so we can put up a simple test site.
sudo apt-get install apache2 -y
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo a2enmod rewrite
sudo systemctl restart apache2
sudo apt-get install ntp
timedatectl set-timezone Europe/London
You should now be able to get to the default page site on:
Configure HTTP and HTTPS Sites
Firstly move/copy the files to create the basic configuration files:
mv /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-tristanself.co.uk.conf
mv /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/000-tristanself.co.uk-SSL.conf
Next you need to edit the two files to make the files look as below, we’re making any HTTP connections redirect to HTTPS.
Note at this stage we’re just using the self-signed certificate for now.
/etc/apache2/sites-available/000-tristanself.co.uk.conf
<VirtualHost *:80>
ServerName tristanself.co.uk
ServerAlias www.tristanself.co.uk
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
/etc/apache2/sites-available/000-tristanself.co.uk-SSL.conf
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#Include conf-available/serve-cgi-bin.conf
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
#SSLCACertificatePath /etc/ssl/certs/
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
#SSLCARevocationPath /etc/apache2/ssl.crl/
#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
#SSLVerifyClient require
#SSLVerifyDepth 10
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<FilesMatch "\.(?:cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
Create the symlinks, then restart Apache.
ln -s /etc/apache2/sites-available/000-tristanself.co.uk.conf /etc/apache2/sites-enabled/000-tristanself.co.uk.conf
ln -s /etc/apache2/sites-available/000-tristanself.co.uk-SSL.conf /etc/apache2/sites-enabled/000-tristanself.co.uk-SSL.conf
sudo systemctl restart apache2
Create Simple Test Website Pages
We’ll now create some website pages to test with:
cd /var/www/html
rm index.html
Create an index.html file in /var/www/html as follows:
index.html
<html>
<body>
<h1>Simple Site</h1>
Hello There!
<a href="secure/index.html">Secure Site</a>
</body>
</html>
Then, create an index.html file in /var/www/html/secure as follows:
<html>
<body>
<h1>Top Secure Site</h1>
You're in the secret page<br>
<a href="/Shibboleth.sso/Session">Show Session Information</a><br>
<a href="/Shibboleth.sso/Status">Show Status Information</a><br>
<a href="/Shibboleth.sso/Logout">Shibboleth Logout</a>
</body>
</html>
You should now be able to test, but obviously the secure site won’t yet work, but you should get your new index.html page.
Shibboleth sP Installation and Configuration
Next we install Shibboleth, which are implemented as an Apache module:
sudo apt-get install libapache2-mod-shib
sudo a2enmod shib
Set up a Shibboleth certificate (n.b. these are different to the Apache certificate). On Debian and its derivatives, run the command (as we are using Shibboleth sP v3+):
sudo shib-keygen -h www.tristanself.co.uk -e https://www.tristanself.co.uk/shibboleth -n sp-encrypt
sudo shib-keygen -h www.tristanself.co.uk -e https://www.tristanself.co.uk/shibboleth -n sp-signing
The keys is/are created in /etc/shibboleth.
Check the certificate fingerprint(s) as follows (you will need to confirm this with IAM later as part of the registration process):
openssl x509 -fingerprint -in /etc/shibboleth/sp-encrypt-cert.pem -sha256
openssl x509 -fingerprint -in /etc/shibboleth/sp-signing-cert.pem -sha256
Edit Apache Configuration
Edit these files and put in the following location into the files so that when a user goes to the “secure” part of the site the authentication are enforced and passed to Shibboleth sP to handle.
sudo vi /etc/apache2/sites-available/000-tristanself.co.uk.conf
sudo vi /etc/apache2/sites-available/000-tristanself.co.uk-SSL.conf
Add the following to both files above:
...
<Location /secure/>
AuthType shibboleth
ShibRequestSetting requireSession 1
Require valid-user
</Location>
...
OKTA Configuration
We now need to create an Application within OKTA to represent our Test Website with its Shibboleth sP authentication; this is not provided as a complete configuration guide, more just what the basic settings should be.
General




Sign-On

Assignments

Now we have configured the OKTA IdP end, we can configure the Shibboleth sP end.
Shibboleth sP Configuration
Now we need to configure Shibboleth sP with some basic configuration. First take a backup of the configuration:
cd /etc/shibboleth
sudo cp /etc/shibboleth/shibboleth2.xml /etc/shibboleth/shibboleth2.backup.xml
Then edit the /etc/shibboleth2.xml file and update these three sections within.
Update the entityID
...
<ApplicationDefaults entityID="https://www.tristanself.co.uk/shibboleth"
REMOTE_USER="eppn subject-id pairwise-id persistent-id"
cipherSuites="DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1">
...
Uncomment Metadata Source (for IdP)
...
<!-- Example of locally maintained metadata. -->
<MetadataProvider type="XML" validate="true" path="partner-metadata.xml"/>
...
Now pull down a copy of the OKTA IdP metadata with:
curl https://domain.okta.com/app/exkmibiehqCyQ1CRy417/sso/saml/metadata -o partner-metadata.xml
The update of the Metadata needs to be automated, see a later section.
Configure the Default IdP
You now need to set within the document which IdP that Shibboleth sP should use, for us this is obviously OKTA, so we need to add the following within the “<Sessions> section. Don’t worry about the WAYF discoveryURL, we’re not using this, so you can leave that as is.
<SSO entityID="http://www.okta.com/exkmibiehqCyQ1CRy417"
discoveryProtocol="SAMLDS" discoveryURL="https://ds.example.org/DS/WAYF">
SAML2
</SSO>
This configuration will tell Shibboleth sP where to send the authentication requests, when it gets them.
Expose the Attributes to End Users
You need to edit /etc/shibboleth2.xml and then set “showAttributeValues” to “true”, followed by removing the ACL (or adjusting to something more suitable) on the second:
...
<!-- Session diagnostic service. -->
<Handler type="Session" Location="/Session" showAttributeValues="true"/>
...
...
<!-- Status reporting service. -->
<Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
...
Resolve and Decode Incoming Attributes
In our OKTA configuration, being the IdP it is exposing certain attributes to the relying party, the sP, i.e. our test website running Shibboleth sP. these are: mail, sn, givenName and uid. So we need to add these to the Attribute Map.
vi /etc/shibboleth/attribute-map.xml
Add these within the file normally after the “Legacy Pairwise” section.
...
<Attribute name="mail" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="mail">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="sn" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="sn">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="givenName" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="givenName">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="uid" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="uid">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
...
If you’re not seeing the attributes appear, if you tail the /var/log/shibboleth/shibd.log file you’ll see something like the following if attributes are coming in but not being mapped correctly:
2025-04-05 18:39:52 INFO Shibboleth.AttributeExtractor.XML [9] [default]: skipping SAML 2.0 Attribute with Name: uid, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
2025-04-05 18:39:52 INFO Shibboleth.AttributeExtractor.XML [9] [default]: skipping SAML 2.0 Attribute with Name: firstname, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
Restart Apache and Shibboleth sP
We are then done, restart the services and we can test.
systemctl restart apache2
systemctl restart shibd.service
Testing and Play
Now we are all set to perform some testing. So browse to:
Then click the link for “Secure Site”, you then be redirected to OKTA IdP. Enter your credentials, then you’ll be redirected back to the secure site.

If the authentication has worked, you’ll see:

You can then click on “Show Session Information” to be able to expose what attributes the IdP has released:

If you want test within the same browser window and force re-authentications, you can open Developer Tools → Application (tab) → Storage (left menu) → Cookies, then find the “_shibsession_<numbers>”, and delete this session to force a reauthentication on the browser side.

Extra Debug Logging
If you want to enable extra logging you can do this by swapping to “DEBUG” mode, note this is pretty verbose!
vi /etc/shibboleth/shibd.logger
Normally you can just set the first line “log4j.rootCategory=INFO, shibd_log, warn_log” from “INFO” to “DEBUG”.
Then restart Shibboleth sP with: “systemctl restart shibd”.
Now you’ll see lots more useful read out, so to test go to /Shibboleth.sso/Login in your browser whilst tailing /var/log/shibboleth/shibd.log.
tail -f /var/log/shibboleth/shibd.log
Automating Metadata Download
There are a couple of ways you may be able to do this, first approach is to automate a download using a BASH script and refer to it in the configuration, the second is if there is now mechanisms within Shibboleth sP itself to automatically refresh/download metadata from an external web location.
Using an example script, let’s create the script:
touch /opt/shibboleth/update-idp-metadata.sh
chmod +x /opt/shibboleth/update-idp-metadata.sh
Now let’s edit the file and add the code:
#!/bin/bash
# Location of the downloaded metadata
METADATA_URL="https://domain.okta.com/app/exkmibiehqCyQ1CRy417/sso/saml/metadata"
DEST_PATH="/etc/shibboleth/partner-metadata.xml"
BACKUP_PATH="/etc/shibboleth/partner-metadata.xml.bak"
NOWDATE=$(date -u)
# Download new metadata
curl -sSf "$METADATA_URL" -o "${DEST_PATH}.tmp"
# Check if download succeeded
if [ $? -eq 0 ]; then
echo "$NOWDATE [INFO] Metadata downloaded successfully."
# Backup old metadata
cp "$DEST_PATH" "$BACKUP_PATH"
# Replace the old file
mv "${DEST_PATH}.tmp" "$DEST_PATH"
# Reload Shibboleth SP (to pick up new metadata)
systemctl restart shibd
echo "$NOWDATE [INFO] Metadata updated and shibd restarted."
else
echo "$NOWDATE [ERROR] Failed to download metadata from $METADATA_URL"
exit 1
fi
Now run it to test:
root@ip-192-168-0-27:/opt/shibboleth# ./update-idp-metadata.sh
[INFO] Metadata downloaded successfully.
[INFO] Metadata updated and shibd restarted.
And automate by adding to a cron like:
vi /etc/cron.d/shib-metadata
Add the following:
30 2 * * * root /opt/shibboleth/update-idp-metadata.sh >> /var/log/shibboleth/metadata-update.log 2>&1
And it will download the latest Metadata from the OKTA IdP each night at 02:30.
Website SSL Certificate
We want to have a nice certificate on our test site, so we’ll install Certbot for this. You’ll need to ensure that your site is open for challenges from CertBot’s servers, i.e. HTTP is accessible from your server, additionally, any domain you are specifying for use i.e. tristanself.co.uk and www.tristanself.co.uk in my case need to have an A record for these (at least), an AAAA record is not required unless you are using IPv6.
The Terraform creates an A record for www.tristanself.co.uk automatically, but no “apex” is created, we can do this by Terraform, but if you needed to do this manually, the following will do this. Note that AWS Route53 gives you an option to have the Apex A record be an alias of another record, rather than having to hardcode it to a specific IP, something that is normally not allowed in the DNS configuration.

Firstly we install Certbot for Apache with:
apt install certbot python3-certbot-apache -y
Now you can run certbot to obtain a certificate.
certbot --apache
Complete the wizard, you can basically just accept the defaults unless you have a specific reason not to.
In my case it generated a new SSL configuration file and then added this into the “sites-enabled” but all commented out, so to remove this from the configuration run the following and restart Apache.
unlink /etc/apache2/sites-enabled/000-tristanself.co.uk-SSL.conf
systemctl restart apache
Now when visiting the site you should find that the certificate is now being used.
For completeness, you can also do the following to correct the error message in the logs about the “AH00558: apache2: Could not reliably determine the server’s fully qualified domain name…”, add the following line to the /etc/apache2/apache2.conf file:
ServerName localhost
Metadata Generation
The installation and configuration up to this point creates a working Shibboleth sP, there is also the metadata which is generated automatically by the MetadataGenerator handler, described in: Metadata Generation Handler. In our particular example we don’t need to have our sP metadata for distribution to the IdP (OKTA), but in some cases you may be required to submit the Metadata to the IdP in this XML form, and/or publish the metadata at a URL which can be read periodically by the IdP.
However, in our case we don’t actually need to do anything much with this metadata.
wget https://www.tristanself.co.uk/Shibboleth.sso/Metadata -O sp-metadata.xml
To download the metadata template, then remove the top part of the file saying:
!--
This is example metadata only. Do *NOT* supply it as is without review,
and do *NOT* provide it in real time to your partners.
-->
Shibboleth.DEPRECATION Warning
Related to the above, we are seeing the following when running a test of the Shibboleth configuration:
root@ip-192-168-0-27:/etc/shibboleth# shibd -t
2025-04-14 12:15:57 WARN Shibboleth.DEPRECATION : MetadataGenerator handler
overall configuration is loadable, check console or log for non-fatal problems
As discussed in: https://help.switch.ch/aai/guides/sp/configuration/, that since SPv3.3 the MetadataGenerator handler line within /etc/shibboleth/shibboleth2.xml causes a: “WARN Shibboleth.DEPRECATION : MetadataGenerator handler” message. According to this: https://it.umn.edu/services-technologies/resources/creating-metadata-file-your-sp this URL provides just a template, which you should download, then turn off the above to remove the warning, then customise the template, which you then publish via other means for your IdP to use, which is what was stated in previous version.
To suppress the message disable the handler by commenting out the following line in /etc/shibboleth2.xml, then restarting shibd with: systemctl restart shibd.
<Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
Note that when you disable this the metadata will no longer be available at: https://www.tristanself.co.uk/Shibboleth.sso/Metadata.
The guidance that talks about running this command to generate the sP metadata appears to be no longer relevant.
shib-metagen -2 -c sp-signing-cert.pem -h www.tristanself.co.uk -e https://www.tristanself.co.uk/Shibboleth > sp-metadata.xml
OKTA and Shibboleth sP with Signed/Encrypted Assertions
Up until now we’ve had OKTA configured to:
- Sign the SAML response message.
- Sign the SAML assertion within the SAML response message.
The Shibboleth sP having a copy of the IdP’s metadata, has a copy of the IdP’s signing certificate (public key), so can verify the authenticity of the SAML response, and SAML assertion within of having come from the IdP. But the assertion content is not encrypted.
However, we’ve not got the SAML assertion content encrypted when it is sent to the Shibboleth sP, so we’ll see about enabling “Assertion Encryption” on OKTA (IdP) to encrypt the actual assertions so they can only be read by the IdP and sP.
Obtain the Signing Certificate and Encryption Certificate from the Service Provider (sP)
Rather than digging through the metadata, we can just use the two files we created earlier which are already in PEM format, we need the /etc/shibboleth/sp-encrypt-cert.pem and /etc/shibboleth/sp-signing-cert.pem files. Copy these to your machine because we’ll need these for the next step to upload into OKTA. OKTA doesn’t appear to be able to take certificates from URLs via metadata.
Configure OKTA (IdP) for Assertion Encryption
1. Open your OKTA application, which we created earlier via the OKTA admin console.
2. Click on “General” and then edit the “SAML Settings”, then “Show Advanced Settings”.
3. Set the “Assertion Encryption” to “Encrypted”.
4. Set the “Encryption Algorithm” to “AES256-CBC”.
5. Set the “Key Transport Algorithm” to “RSA-OAEP”

You may want to use different encryption algorithms, however you should be able to determine which are supported by your Shibboleth sP by examining your Shibboleth sP’s metadata.
6. Using the two certificate files you got earlier, upload the sp-encrypt-cert.pem for the “Encryption Certificate” and the sp-signing-cert.pem for the “Signature Certificate”


7. Then save the SAML settings to confirm your changes.
Testing to Confirm
Now try to log on to your test website with the DEBUG logging enabled (see the “Extra Debug Logging” section above) once applied restart Shibboleth sP.
Now when you attempt a login you’ll see a lot for output and messages saying that the assertion content is being decrypted, if you then go back to OKTA and disable the encryption you’ll see output go back to what it was showing before that the assertions are not encrypted.
Some sample output is given below:


Website Logout
The Logout of SAML is a can of worms, in this case however, we are going to use an example of “Global Logout”.
The example shows how to configure “Global Logout”, which essentially means that when a user clicks the logout link in the test website, it logs the user out of the sP, but also instructs the IdP to log out all other sessions, even for other SAML sP protected sites (which support SLO – Single Log Out), which may or may not be what you want. An example of when you might want to use this is for shared computers, where you want to log out from all SSO enabled sites so if a user then walks away, another user doesn’t just swoop in and access another site (which wasn’t logged out), and accesses confidential information or services. Conversely, “Local Logout” will only log out the current sP, which means the user is still logged into the IdP, which would therefore allow them to immediately sign back into that sP or any other, it’s fine for a single user machine, but not desirable for a shared computer.
In this example we’re using a Global Logout, however you may want to use Local Logout depending on your requirements. If you want to use the Local Logout option, this can be achieved by not setting “Enable Single Logout” as described below, and then within the Shibboleth configuration, however for the purposes of this particular example configuration, the Local Logout can be achieved by not applying the “Allow application to initiate Single Logout” as shown below, and then removing the “SAML2” from the /etc/shibboleth2/shibboleth2.xml definition so only “Local” is left.
<Logout>SAML2 Local</Logout>
How the log-out function works in Local Logout and Global Logout configuration.

Configure OKTA Application for Global Logout
Firstly you need to make an adjustment to our OKTA application that works with our Shibboleth sP.
Edit the “SAML Settings”, then tick the box for “Enable Single Logout”, then complete the fields as shown.

Save your configuration.
On the Shibboleth sP, you should now force a download of the updated metadata just to be sure (which will restart the Shibboleth sP).
/opt/shibboleth/update-idp-metadata.sh
Configure Shibboleth sP for Global Logout
Before we can test we now need to configure the Shibboleth sP for Global Logout. You’ll notice that in the earlier step when we created the Secret Website page that we have a link added to the page (i.e. /Shibboleth.sso/Logout) that will be depending on the setting configured below will either use Global Logout, where the sP makes a request to the IdP telling it to logout all the sessions, or Local Logout, where it will just trigger the current session locally on this sP to be ended.
On Shibboleth sP remove the “Local” from the following line in the etc/shibboleth2.xml config, so it only says “SAML2”.
...
<Logout>SAML2 Local</Logout>
...
Download new metadata from the IDP, and restart Shibboleth sP.
Testing
Now we have configured the Global Logout, let’s give it a try.
Go to the test website, then click the “Secure Site” link, you’ll then be redirected to the OKTA Login page, where you need to log in.
Once successfully logged in, now click on the “Shibboleth Logout” link, where you’ll now see:

What is interesting is then if you go to your organisation’s OKTA front of house page, you’ll now be required to log in, this shows how you have been fully logged out from both the sP and the IdP.

When doing this when using a Local Logout you’ll find you are still logged in to the IdP, even if you’ve been logged off from the sP. However, you’ll also find that if you refresh the example website you’ll end up logging back on again.
Option 2 – Example Site Authenticated with OpenAthens and Shibboleth sP
Using OpenAthens as the IdP instead of OKTA is actually a fairly minimal change to the configuration. In our example we use OKTA and OpenAthens for two different use cases, and OpenAthens uses OKTA as the directory source, however that is not really relevant for the purposes of this example deployment.
OpenAthens provide guidance here: https://docs.openathens.net/providers/openathens-idp-elements#OpenAthensIdPelements-Ifyouareusingothersoftware(suchasShibboleth)
These instructions for option 2 are written assuming you’ve already configured Shibboleth sP to work with OKTA, so we are reconfiguring what is already there to work with OpenAthens; to avoid having to repeat much of the documentation!
OpenAthens Configuration
We first need to create a “Resource” within OpenAthens, to do this, open the OpenAthens admin web console then:
1. Click on “Resources”, then “Catalogue”. Then click on “Custom”, as we’ll be creating a custom resource for our Shibboleth sP.
2. Click on “Create”, then select “SAML” as the resource type, then “Configure”.
3. Here either upload your Shibboleth sP metadata XML file, which you can download from the server, or alternatively add the URL to the metadata, probably not ideal to do this though because the Metadata provided via the https://www.tristanself.co.uk/Shibboleth.SSO/Metadata is not customised.
4. Click “Create Resource”.
5. If you wish you can add the Access URL on the “Resource Details” page, I used: https://www.tristanself.co.uk/secure
That’s it, you’re ready to move on with the configuration.
OpenAthens Metadata Location and Configuration
The document above says where you can get the OpenAthens Federation metadata from, to quote.
“If you are using other software (such as Shibboleth). If you are not ready to add the OpenAthens federation metadata to your SP, you can add the metadata for just your own OpenAthens IdP: https://login.openathens.net/saml/2/metadata-idp/YOUR_OPENATHENS_API_NAME“
So in our case our API name is domain.com, therefore our metadata for OpenAthens can be found at: https://login.openathens.net/saml/2/metadata-idp/domain.com
Shibboleth sP Configuration Changes
To set Shibboleth sP to work with OpenAthens you need to perform the following changes. These steps have been written assuming you’ve already configured Shibboleth sP and the test site to use OKTA, so we’ll be swapping some of the settings, rather than starting afresh.
Update EntityID
Within /etc/shibboleth/shibboleth2.xml file you need to swap the EntityID to the OpenAthens Entity ID, so find the section where you have the OKTA EntityID and swap the value, for example:
<SSO entityID="https://idp.domain.com/idp/shibboleth"
discoveryProtocol="SAMLDS" discoveryURL="https://ds.example.org/DS/WAYF">
SAML2
</SSO>
Set the entity ID to https://idp.domain.com/idp/shibboleth in the following file (in this test it was already set to Okta):
Metadata Configuration
We have already specified the metadata location to use a local file, however this currently contains the OKTA metadata, so we need to update this to have the OpenAthens metadata in it instead.
So run the following command to download the OpenAthens Metadata file.
wget https://login.openathens.net/saml/2/metadata-idp/domain.com -O /etc/shibboleth/partner-metadata.xml
Note that we have the automated download script, you should either update this script with the new URL for the OpenAthens Metadata or disable it by adding a “#” at the beginning of the line within the file in /etc/cron.d which was created in the option 1 documentation.
Then restart Shibboleth (and Apache):
systemctl restart shibd
systemctl restart apache2
Resolve and Decode Incoming Attributes
The attribute mapping from OpenAthens is a bit different to that from OKTA, depending on how the attributes are released and named we need to update the /etc/shibboleth/attribute-map.xml configuration file to be able to pluck these out of the incoming assertion. You’ll see the below, some of the attributes we were resolving for the OKTA IdP, we can leave those in there, even if they have the same name, e.g. givenName and givenName, because the first definition will be ignored, because it doesn’t match the incoming attribute assertion format.
/etc/shibboleth/attribute-map.xml
<!-- Bits I've added to this file -->
<Attribute name="mail" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="mail">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="sn" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="sn">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="givenName" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="givenName">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="uid" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" id="uid">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="urn:oid:2.5.4.42" id="givenName">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="urn:oid:2.5.4.4" id="sn">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<!-- End of my bits -->
We added these two “givenName” and “sn”, you can see that these have a different format, therefore the previous ones wouldn’t have matched.
<Attribute name="urn:oid:2.5.4.42" id="givenName">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
<Attribute name="urn:oid:2.5.4.4" id="sn">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
Now restart Shibboleth sP and Apache, and we are ready to test. If you have anything you are passing that is not mapped, you’ll see things like the following upon login within the /var/log/shibboleth/shibd.log file.
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:mace:eduserv.org.uk:athens:attribute-def:federation:1.0:identifier
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:0.9.2342.19200300.100.1.3
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:1.3.6.1.4.1.5923.1.1.1.1
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:mace:eduserv.org.uk:athens:attribute-def:organisation:1.0:identifier
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.42
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:1.3.6.1.4.1.5923.1.1.1.11
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: forenames
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: emailAddress
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: surname
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.16.840.1.113730.3.1.241
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: http://eduserv.org.uk/federation/attributes/1.0/organisationid
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.4
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.3
2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML [1] [default]: skipping SAML 2.0 Attribute with Name: organisationNum
Testing
We can now perform some testing.
Visit the test site, then click on “Secure Site”, notice now that we’re getting a slightly different logon screen within OKTA, note that in our case OpenAthens is the IdP, BUT it is backing off its authentication source to OKTA, if however you are using OpenAthens stand-alone or using it against another Directory Service, e.g. openLDAP or Active Directory, you’ll see something a bit different.
However, in our case we can see that we’re authenticating via OpenAthens rather than direct to OKTA via the OKTA application as we did in Option 1.

And we’re in, going to the “Session” page within the Secure Site, we can see our attributes being released as expected.

Questions
Some questions that arose from the development of the OKTA and Shibboleth sP Test.
What does the NameID unspecified mean? What is the difference on the NameID bit, what does unspecified, persistent and transient formats mean?
In the context of SAML and Shibboleth, “NameID” refers to the unique identifier of the user in a SAML assertion, representing the subject of the authentication, and can be anything like an email address, username, or a unique identifier.
So what does the different NameID format mean?
Unspecified
- Format URI: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
- Means the IdP doesn’t specify how to interpret the identifier — it’s up to the SP.
- Often used when the value is meaningful only to the SP (e.g., a username like “jsmith”).
- It can be flexible but may lack interoperability between systems.
Persistent
- Format URI: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
- A long-term, opaque, non-assignable identifier.
- Same value sent to the same SP every time, enabling long-term account linking without exposing personal info.
- Example: 4f1c2d67-9a67-4d13-82cb-3a15eabcde12
- Good for privacy-preserving but consistent user identification.
Transient
- Format URI: urn:oasis:names:tc:SAML:2.0:nameid-format:transient
- A temporary, one-time-use identifier.
- Only valid for the current session or authentication transaction.
- The SP can’t rely on it to link user sessions long-term.
- Often used when you don’t want persistent tracking or user identification.
So really using Persistent NameID is when you need the sP to recognise the same user over multiple sessions, e.g. so they can access a profile they have customised with user preferences etc. You also protect privacy because it’s not a real name, it’s just an identifier. Transient is when you don’t need to track a user long term, e.g. you are providing a service to access information, all you need to know that the user is from an organisation with a subscription for example, you don’t care any more than that. e.g. document signing and so forth. Finally, “unspecified” is for when the sP requires the NameID contain a specific value, e.g. a username, so there is no need for format enforcement, typically you’d use this for old applications (e.g. SAML 1.1) or when it’s an internal system (which wants a specific username) or for quick set up and testing.
What about SAML assertions having a Name Format of basic, unspecified or URI etc.?
Now we are talking NameFormat for SAML attributes, which is different from NameID and assertion confirmation. The attribute’s NameFormat affects how attributes are interpreted by the sP.
In a SAML AttributeStatement, you send user attributes like email, display name, affiliation, etc. Each attribute has:
- A Name (like urn:oid:0.9.2342.19200300.100.1.3 or just email)
- A NameFormat (which tells the SP how to interpret the Name)
- Optional FriendlyName (a human-readable alias)
Digging into each NameFormat is:
1. Unspecified – urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
- Just a raw string — no special format implied.
- Attribute names like “email” or “uid” are just passed as-is.
- Most flexible, but least standardized.
2. Basic – urn:oasis:names:tc:SAML:2.0:attrname-format:basic
- Legacy format from SAML 1.1.
- Names are often simple strings like “cn”, “sn”, “mail”, “uid”.
- Still used in some Shibboleth deployments for backward compatibility.
- More structured than unspecified but less so than URI.
3. URI – urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- The recommended standard format in modern SAML 2.0.
- Uses URIs to define attribute names, often OIDs or schemas.
- For example:
- urn:oid:0.9.2342.19200300.100.1.3 → email
- urn:oid:2.5.4.3 → commonName
- Highly interoperable across federations (like eduGAIN).
So on the sP side, you need to decide how to map incoming SAML attributes from the IdP to internal attribute names (in the sP) that your application(s) can use. So within the sP you’ll have some sort of translation table (attribute-map.xml on Shibboleth sP for example), where you define:
- What the IdP sends in the SAML assertion (Name, NameFormat).
- What the SP internally refers to that attribute as.
So, it uses name + optional nameFormat to match SAML attributes. If there’s no match, the SP won’t make the attribute available to your apps therefore you need to ensure what is coming in maps to which for interpreting and exposing user data correctly.
Additional Information
- https://help.it.ox.ac.uk/installing-shibboleth-sp-for-apache#collapse2307686
- https://support.aaf.edu.au/support/solutions/articles/19000035962-installing-a-shibboleth-service-provider
- https://spaces.at.internet2.edu/display/federation/SP+Testing+for+SAML2
- https://docs.eduvpn.org/server/v3/shibboleth-sp.html
- https://help.it.ox.ac.uk/installing-shibboleth-sp-for-apache#collapse2307686
- https://www.iam.harvard.edu/resources/saml-shibboleth-integrationhttps://help.it.ox.ac.uk/installing-shibboleth-sp-for-apache#collapse2307686
- https://docs.shib.ncsu.edu/docs/logout.html
https://github.com/ConsortiumGARR/idem-tutorials/blob/master/idem-fedops/HOWTO-Shibboleth/Service%20Provider/Debian/HOWTO%20Install%20and%20Configure%20a%20Shibboleth%20SP%20v2.x%20on%20Debian%20Linux%209%20(Stretch).md - https://it.umn.edu/services-technologies/resources/creating-metadata-file-your-sp
- https://iam.alaska.edu/shib/wiki/SpSetup
- https://www.ukfederation.org.uk/content/Documents/Setup3SP
- https://help.switch.ch/aai/guides/sp/logout/
- https://uwconnect.uw.edu/it?id=kb_article_view&sysparm_article=KB0033930