{"id":4452,"date":"2025-04-17T13:15:30","date_gmt":"2025-04-17T13:15:30","guid":{"rendered":"https:\/\/geekmungus.co.uk\/?p=4452"},"modified":"2025-04-17T13:15:32","modified_gmt":"2025-04-17T13:15:32","slug":"example-site-authenticated-with-okta-and-shibboleth-sp-or-openathens-and-shibboleth-sp","status":"publish","type":"post","link":"https:\/\/geekmungus.co.uk\/?p=4452","title":{"rendered":"Example Site Authenticated with OKTA and Shibboleth sP (or OpenAthens and Shibboleth sP)"},"content":{"rendered":"\n<p>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:<\/p>\n\n\n\n<p>An AWS VPC, with an EC2 instance that will act as the Shibboleth sP and host the test website.<br>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<br>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.<br>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.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Option1-ExampleSiteAuthenticatedwithOKTAandShibbolethsP\">Option 1 &#8211; Example Site Authenticated with OKTA and Shibboleth sP<\/h1>\n\n\n\n<p>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-DeploytheInstance\">Deploy the Instance<\/h2>\n\n\n\n<p>Ensure you have the a workstation with Terraform and the AWS CLI installed, and you have the Terraform script(s) downloaded from the below:<\/p>\n\n\n\n<p>Terraform: <a href=\"https:\/\/github.com\/tristanhself\/general\/tree\/master\/aws\/test-sp\">https:\/\/github.com\/tristanhself\/general\/tree\/master\/aws\/test-sp<\/a><\/p>\n\n\n\n<p>So now we deploy the instance with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd test-sP\nterraform apply --auto--approve<\/code><\/pre>\n\n\n\n<p>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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws ssm start-session --target &lt;instance-ID><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-PerformApacheInstallandConfiguration\">Perform Apache Install and Configuration<\/h2>\n\n\n\n<p>You&#8217;ll now need to install Apache including the various rewrite modules so we can put up a simple test site.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get install apache2 -y\nsudo a2enmod ssl\nsudo a2ensite default-ssl\nsudo a2enmod rewrite\nsudo systemctl restart apache2\n \nsudo apt-get install ntp\ntimedatectl set-timezone Europe\/London<\/code><\/pre>\n\n\n\n<p>You should now be able to get to the default page site on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/www.tristanself.co.uk\/\">http:\/\/www.tristanself.co.uk<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.tristanself.co.uk\">https:\/\/www.tristanself.co.uk<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ConfigureHTTPandHTTPSSites\">Configure HTTP and HTTPS Sites<\/h3>\n\n\n\n<p>Firstly move\/copy the files to create the basic configuration files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mv \/etc\/apache2\/sites-available\/000-default.conf \/etc\/apache2\/sites-available\/000-tristanself.co.uk.conf\nmv \/etc\/apache2\/sites-available\/default-ssl.conf \/etc\/apache2\/sites-available\/000-tristanself.co.uk-SSL.conf<\/code><\/pre>\n\n\n\n<p>Next you need to edit the two files to make the files look as below, we&#8217;re making any HTTP connections redirect to HTTPS.<\/p>\n\n\n\n<p>Note at this stage we&#8217;re just using the self-signed certificate for now.<\/p>\n\n\n\n<p><strong>\/etc\/apache2\/sites-available\/000-tristanself.co.uk.conf<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;VirtualHost *:80>\n        ServerName tristanself.co.uk\n        ServerAlias www.tristanself.co.uk\n \n        RewriteEngine On\n        RewriteCond %{HTTPS} off\n        RewriteRule (.*) https:\/\/%{HTTP_HOST}%{REQUEST_URI}\n \n        ServerAdmin webmaster@localhost\n        DocumentRoot \/var\/www\/html\n \n        #LogLevel info ssl:warn\n \n        ErrorLog ${APACHE_LOG_DIR}\/error.log\n        CustomLog ${APACHE_LOG_DIR}\/access.log combined\n \n        #Include conf-available\/serve-cgi-bin.conf\n&lt;\/VirtualHost><\/code><\/pre>\n\n\n\n<p><strong>\/etc\/apache2\/sites-available\/000-tristanself.co.uk-SSL.conf<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;VirtualHost *:443>\n        ServerAdmin webmaster@localhost\n \n        DocumentRoot \/var\/www\/html\n \n        #LogLevel info ssl:warn\n \n        ErrorLog ${APACHE_LOG_DIR}\/error.log\n        CustomLog ${APACHE_LOG_DIR}\/access.log combined\n \n        #Include conf-available\/serve-cgi-bin.conf\n \n        SSLEngine on\n \n        SSLCertificateFile      \/etc\/ssl\/certs\/ssl-cert-snakeoil.pem\n        SSLCertificateKeyFile   \/etc\/ssl\/private\/ssl-cert-snakeoil.key\n \n        #SSLCertificateChainFile \/etc\/apache2\/ssl.crt\/server-ca.crt\n \n        #SSLCACertificatePath \/etc\/ssl\/certs\/\n        #SSLCACertificateFile \/etc\/apache2\/ssl.crt\/ca-bundle.crt\n \n        #SSLCARevocationPath \/etc\/apache2\/ssl.crl\/\n        #SSLCARevocationFile \/etc\/apache2\/ssl.crl\/ca-bundle.crl\n \n        #SSLVerifyClient require\n        #SSLVerifyDepth  10\n \n        #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire\n        &lt;FilesMatch \"\\.(?:cgi|shtml|phtml|php)$\">\n                SSLOptions +StdEnvVars\n        &lt;\/FilesMatch>\n        &lt;Directory \/usr\/lib\/cgi-bin>\n                SSLOptions +StdEnvVars\n        &lt;\/Directory>\n&lt;\/VirtualHost><\/code><\/pre>\n\n\n\n<p>Create the symlinks, then restart Apache.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ln -s \/etc\/apache2\/sites-available\/000-tristanself.co.uk.conf \/etc\/apache2\/sites-enabled\/000-tristanself.co.uk.conf\nln -s \/etc\/apache2\/sites-available\/000-tristanself.co.uk-SSL.conf \/etc\/apache2\/sites-enabled\/000-tristanself.co.uk-SSL.conf\n \nsudo systemctl restart apache2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-CreateSimpleTestWebsitePages\">Create Simple Test Website Pages<\/h3>\n\n\n\n<p>We&#8217;ll now create some website pages to test with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/var\/www\/html\nrm index.html<\/code><\/pre>\n\n\n\n<p>Create an index.html file in \/var\/www\/html as follows:<\/p>\n\n\n\n<p>index.html<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;html>\n&lt;body>\n&lt;h1>Simple Site&lt;\/h1>\nHello There!\n&lt;a href=\"secure\/index.html\">Secure Site&lt;\/a>\n&lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p>Then, create an index.html file in \/var\/www\/html\/secure as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;html>\n&lt;body>\n&lt;h1>Top Secure Site&lt;\/h1>\nYou're in the secret page&lt;br>\n&lt;a href=\"\/Shibboleth.sso\/Session\">Show Session Information&lt;\/a>&lt;br>\n&lt;a href=\"\/Shibboleth.sso\/Status\">Show Status Information&lt;\/a>&lt;br>\n&lt;a href=\"\/Shibboleth.sso\/Logout\">Shibboleth Logout&lt;\/a>\n&lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p>You should now be able to test, but obviously the secure site won&#8217;t yet work, but you should get your new index.html page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ShibbolethsPInstallationandConfiguration\">Shibboleth sP Installation and Configuration<\/h2>\n\n\n\n<p>Next we install Shibboleth, which are implemented as an Apache module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get install libapache2-mod-shib\nsudo a2enmod shib<\/code><\/pre>\n\n\n\n<p>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+):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo shib-keygen -h www.tristanself.co.uk -e https:\/\/www.tristanself.co.uk\/shibboleth -n sp-encrypt\nsudo shib-keygen -h www.tristanself.co.uk -e https:\/\/www.tristanself.co.uk\/shibboleth -n sp-signing<\/code><\/pre>\n\n\n\n<p>The keys is\/are created in \/etc\/shibboleth.<\/p>\n\n\n\n<p>Check the certificate fingerprint(s) as follows (you will need to confirm this with IAM later as part of the registration process):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>openssl x509 -fingerprint -in \/etc\/shibboleth\/sp-encrypt-cert.pem -sha256\nopenssl x509 -fingerprint -in \/etc\/shibboleth\/sp-signing-cert.pem -sha256<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-EditApacheConfiguration\">Edit Apache Configuration<\/h2>\n\n\n\n<p>Edit these files and put in the following location into the files so that when a user goes to the &#8220;secure&#8221; part of the site the authentication are enforced and passed to Shibboleth sP to handle.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/apache2\/sites-available\/000-tristanself.co.uk.conf\nsudo vi \/etc\/apache2\/sites-available\/000-tristanself.co.uk-SSL.conf<\/code><\/pre>\n\n\n\n<p>Add the following to both files above:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n        &lt;Location \/secure\/>\n                 AuthType shibboleth\n                 ShibRequestSetting requireSession 1\n                 Require valid-user\n        &lt;\/Location>\n...<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-OKTAConfiguration\">OKTA Configuration<\/h2>\n\n\n\n<p>We now need to create an Application within OKTA to represent our Test Website with its Shibboleth sP authentication; this&nbsp;is&nbsp;not provided as a complete configuration guide, more just what the basic settings should be.<\/p>\n\n\n\n<p><strong>General<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"463\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-12.png\" alt=\"\" class=\"wp-image-4457\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-12.png 738w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-12-300x188.png 300w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"937\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-13.png\" alt=\"\" class=\"wp-image-4458\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-13.png 731w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-13-234x300.png 234w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"732\" height=\"377\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-14.png\" alt=\"\" class=\"wp-image-4459\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-14.png 732w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-14-300x155.png 300w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"937\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-16.png\" alt=\"\" class=\"wp-image-4461\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-16.png 742w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-16-238x300.png 238w\" sizes=\"auto, (max-width: 742px) 100vw, 742px\" \/><\/figure>\n\n\n\n<p><strong>Sign-On<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"734\" height=\"937\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-17.png\" alt=\"\" class=\"wp-image-4462\" style=\"width:840px;height:auto\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-17.png 734w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-17-235x300.png 235w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/figure>\n\n\n\n<p><strong>Assignments<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1012\" height=\"531\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-19.png\" alt=\"\" class=\"wp-image-4464\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-19.png 1012w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-19-300x157.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-19-768x403.png 768w\" sizes=\"auto, (max-width: 1012px) 100vw, 1012px\" \/><\/figure>\n\n\n\n<p>Now we have configured the OKTA IdP end, we can configure the Shibboleth sP end.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ShibbolethsPConfiguration\">Shibboleth sP Configuration<\/h2>\n\n\n\n<p>Now we need to configure Shibboleth sP with some basic configuration. First take a backup of the configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/etc\/shibboleth\nsudo cp \/etc\/shibboleth\/shibboleth2.xml \/etc\/shibboleth\/shibboleth2.backup.xml<\/code><\/pre>\n\n\n\n<p>Then edit the \/etc\/shibboleth2.xml file and update these three sections within.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-UpdatetheentityID\">Update the entityID<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n&lt;ApplicationDefaults entityID=\"https:\/\/www.tristanself.co.uk\/shibboleth\"\n        REMOTE_USER=\"eppn subject-id pairwise-id persistent-id\"\n        cipherSuites=\"DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1\">\n...<\/code><\/pre>\n\n\n\n<p><strong>Uncomment Metadata Source (for IdP)<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n       &lt;!-- Example of locally maintained metadata. -->\n       &lt;MetadataProvider type=\"XML\" validate=\"true\" path=\"partner-metadata.xml\"\/>\n...<\/code><\/pre>\n\n\n\n<p>Now pull down a copy of the OKTA IdP metadata with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/domain.okta.com\/app\/exkmibiehqCyQ1CRy417\/sso\/saml\/metadata -o partner-metadata.xml<\/code><\/pre>\n\n\n\n<p>The update of the Metadata needs to be automated, see a later section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ConfiguretheDefaultIdP\">Configure the Default IdP<\/h3>\n\n\n\n<p>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&nbsp;&#8220;&lt;Sessions&gt;&nbsp;section. Don&#8217;t worry about the&nbsp;WAYF&nbsp;discoveryURL, we&#8217;re not using this, so you can leave that as is.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;SSO entityID=\"http:\/\/www.okta.com\/exkmibiehqCyQ1CRy417\"\n    discoveryProtocol=\"SAMLDS\" discoveryURL=\"https:\/\/ds.example.org\/DS\/WAYF\">\n    SAML2\n&lt;\/SSO><\/code><\/pre>\n\n\n\n<p>This configuration will tell Shibboleth sP where to send the authentication requests, when it gets them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ExposetheAttributestoEndUsers\">Expose the Attributes to End Users<\/h3>\n\n\n\n<p>You need to edit \/etc\/shibboleth2.xml and then set &#8220;showAttributeValues&#8221; to &#8220;true&#8221;, followed by removing the ACL (or adjusting to something more suitable) on the second:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n            &lt;!-- Session diagnostic service. -->\n            &lt;Handler type=\"Session\" Location=\"\/Session\" showAttributeValues=\"true\"\/>\n...\n \n...\n            &lt;!-- Status reporting service. -->\n            &lt;Handler type=\"Status\" Location=\"\/Status\" acl=\"127.0.0.1 ::1\"\/>\n...<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ResolveandDecodeIncomingAttributes\">Resolve and Decode Incoming Attributes<\/h3>\n\n\n\n<p>In our OKTA configuration, being the IdP it is exposing certain attributes to&nbsp;the relying&nbsp;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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi \/etc\/shibboleth\/attribute-map.xml<\/code><\/pre>\n\n\n\n<p>Add these within the file normally after the &#8220;Legacy Pairwise&#8221; section.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n    &lt;Attribute name=\"mail\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"mail\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n    &lt;\/Attribute>\n \n    &lt;Attribute name=\"sn\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"sn\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n    &lt;\/Attribute>\n \n    &lt;Attribute name=\"givenName\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"givenName\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n    &lt;\/Attribute>\n \n    &lt;Attribute name=\"uid\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"uid\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n    &lt;\/Attribute>\n...<\/code><\/pre>\n\n\n\n<p>If you&#8217;re not seeing the attributes appear, if you tail the \/var\/log\/shibboleth\/shibd.log file you&#8217;ll see something like the following if attributes are coming in but not being mapped correctly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2025-04-05 18:39:52 INFO Shibboleth.AttributeExtractor.XML &#91;9] &#91;default]: skipping SAML 2.0 Attribute with Name: uid, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\n2025-04-05 18:39:52 INFO Shibboleth.AttributeExtractor.XML &#91;9] &#91;default]: skipping SAML 2.0 Attribute with Name: firstname, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-RestartApacheandShibbolethsP\">Restart Apache and Shibboleth sP<\/h2>\n\n\n\n<p>We are then done, restart the services and we can test.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl restart apache2\nsystemctl restart shibd.service<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-TestingandPlay\">Testing and Play<\/h2>\n\n\n\n<p>Now we are all set to perform some testing. So browse to:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.tristanself.co.uk\">https:\/\/www.tristanself.co.uk<\/a><\/p>\n\n\n\n<p>Then click the link for &#8220;Secure Site&#8221;, you then be redirected to OKTA IdP. Enter your credentials, then you&#8217;ll be redirected back to the secure site.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"440\" height=\"249\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-20.png\" alt=\"\" class=\"wp-image-4466\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-20.png 440w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-20-300x170.png 300w\" sizes=\"auto, (max-width: 440px) 100vw, 440px\" \/><\/figure>\n\n\n\n<p>If the authentication has worked, you&#8217;ll see:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"536\" height=\"292\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-21.png\" alt=\"\" class=\"wp-image-4467\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-21.png 536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-21-300x163.png 300w\" sizes=\"auto, (max-width: 536px) 100vw, 536px\" \/><\/figure>\n\n\n\n<p>You can then click on &#8220;Show Session Information&#8221; to be able to expose what attributes the IdP has released:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"784\" height=\"362\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-22.png\" alt=\"\" class=\"wp-image-4468\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-22.png 784w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-22-300x139.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-22-768x355.png 768w\" sizes=\"auto, (max-width: 784px) 100vw, 784px\" \/><\/figure>\n\n\n\n<p>If you want test within the same browser window and force re-authentications, you can open Developer Tools \u2192 Application (tab) \u2192 Storage (left menu) \u2192 Cookies, then find the &#8220;_<em>shibsession_&lt;numbers>&#8221;<\/em>, and delete this session to force a reauthentication on the browser side.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"415\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23-1024x415.png\" alt=\"\" class=\"wp-image-4469\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23-1024x415.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23-300x122.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23-768x311.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23-1536x622.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-23.png 1893w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ExtraDebugLogging\">Extra Debug Logging<\/h2>\n\n\n\n<p>If you want to enable extra logging you can do this by swapping to &#8220;DEBUG&#8221; mode, note this is pretty verbose!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi \/etc\/shibboleth\/shibd.logger<\/code><\/pre>\n\n\n\n<p>Normally you can just set the first line &#8220;log4j.rootCategory=INFO, shibd_log, warn_log&#8221; from &#8220;INFO&#8221; to &#8220;DEBUG&#8221;.<\/p>\n\n\n\n<p>Then restart Shibboleth sP with: &#8220;systemctl restart&nbsp;shibd&#8221;.<\/p>\n\n\n\n<p>Now you&#8217;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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tail -f \/var\/log\/shibboleth\/shibd.log<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-AutomatingMetadataDownload\">Automating Metadata Download<\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>Using an example script, let&#8217;s create the script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>touch \/opt\/shibboleth\/update-idp-metadata.sh\nchmod +x \/opt\/shibboleth\/update-idp-metadata.sh<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s edit the file and add the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n \n# Location of the downloaded metadata\nMETADATA_URL=\"https:\/\/domain.okta.com\/app\/exkmibiehqCyQ1CRy417\/sso\/saml\/metadata\"\nDEST_PATH=\"\/etc\/shibboleth\/partner-metadata.xml\"\nBACKUP_PATH=\"\/etc\/shibboleth\/partner-metadata.xml.bak\"\n \nNOWDATE=$(date -u)\n \n# Download new metadata\ncurl -sSf \"$METADATA_URL\" -o \"${DEST_PATH}.tmp\"\n \n# Check if download succeeded\nif &#91; $? -eq 0 ]; then\n    echo \"$NOWDATE &#91;INFO] Metadata downloaded successfully.\"\n \n    # Backup old metadata\n    cp \"$DEST_PATH\" \"$BACKUP_PATH\"\n \n    # Replace the old file\n    mv \"${DEST_PATH}.tmp\" \"$DEST_PATH\"\n \n    # Reload Shibboleth SP (to pick up new metadata)\n    systemctl restart shibd\n \n    echo \"$NOWDATE &#91;INFO] Metadata updated and shibd restarted.\"\nelse\n    echo \"$NOWDATE &#91;ERROR] Failed to download metadata from $METADATA_URL\"\n    exit 1\nfi<\/code><\/pre>\n\n\n\n<p>Now run it to test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@ip-192-168-0-27:\/opt\/shibboleth# .\/update-idp-metadata.sh\n&#91;INFO] Metadata downloaded successfully.\n&#91;INFO] Metadata updated and shibd restarted.<\/code><\/pre>\n\n\n\n<p>And automate by adding to a cron like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nvi \/etc\/cron.d\/shib-metadata<\/code><\/pre>\n\n\n\n<p>Add the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>30 2 * * * root \/opt\/shibboleth\/update-idp-metadata.sh >> \/var\/log\/shibboleth\/metadata-update.log 2>&amp;1<\/code><\/pre>\n\n\n\n<p>And it will download the latest Metadata from the OKTA IdP each night at 02:30.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-WebsiteSSLCertificate\">Website SSL Certificate<\/h2>\n\n\n\n<p>We want to have a nice certificate on our test site, so we&#8217;ll install&nbsp;Certbot&nbsp;for this. You&#8217;ll need to ensure that your site is open for challenges from&nbsp;CertBot&#8217;s servers, i.e. HTTP is accessible from your server, additionally, any domain you are specifying for use i.e.&nbsp;<a href=\"http:\/\/tristanself.co.uk\/\">tristanself.co.uk<\/a>&nbsp;and&nbsp;<a href=\"http:\/\/www.tristanself.co.uk\/\">www.tristanself.co.uk<\/a>&nbsp;in my case need to have an A record for these (at least), an AAAA record is not required unless you are using IPv6.<\/p>\n\n\n\n<p>The Terraform creates an A record for&nbsp;<a href=\"http:\/\/www.tristanself.co.uk\/\">www.tristanself.co.uk<\/a>&nbsp;automatically, but no &#8220;apex&#8221; 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.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"416\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24-1024x416.png\" alt=\"\" class=\"wp-image-4472\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24-1024x416.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24-300x122.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24-768x312.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24-1536x624.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-24.png 1757w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Firstly we install\u00a0<strong>Certbot\u00a0for Apache<\/strong>\u00a0with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install certbot python3-certbot-apache -y<\/code><\/pre>\n\n\n\n<p>Now you can run\u00a0certbot\u00a0to obtain a certificate.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>certbot --apache<\/code><\/pre>\n\n\n\n<p>Complete the wizard, you can basically just accept the defaults unless you have a specific reason not to.<\/p>\n\n\n\n<p>In my case it generated a new SSL configuration file and then added this into the &#8220;sites-enabled&#8221; but all commented out, so to remove this from the configuration run the following and restart Apache.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unlink \/etc\/apache2\/sites-enabled\/000-tristanself.co.uk-SSL.conf\nsystemctl restart apache<\/code><\/pre>\n\n\n\n<p>Now when visiting the site you should find that the certificate is now being used.<\/p>\n\n\n\n<p>For completeness, you can also do the following to correct the error message in the logs about the&nbsp;<em>&#8220;AH00558: apache2: Could not reliably determine the server&#8217;s fully qualified domain name&#8230;&#8221;<\/em>, add the following line to the&nbsp;<strong>\/etc\/apache2\/apache2.conf<\/strong>&nbsp;file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ServerName localhost<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-MetadataGeneration\">Metadata Generation<\/h2>\n\n\n\n<p>The installation and configuration up to this point creates a working Shibboleth sP, there is also the metadata which is generated automatically by the&nbsp;MetadataGenerator&nbsp;handler, described in:&nbsp;<a href=\"https:\/\/shibboleth.atlassian.net\/wiki\/spaces\/SP3\/pages\/2065334858\/Metadata+Generation+Handler\">Metadata Generation Handler<\/a>. In our particular example we don&#8217;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.<\/p>\n\n\n\n<p>However, in our case we don&#8217;t actually need to do anything much with this metadata.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/www.tristanself.co.uk\/Shibboleth.sso\/Metadata -O sp-metadata.xml<\/code><\/pre>\n\n\n\n<p>To download the metadata template, then remove the top part of the file saying:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>!--\nThis is example metadata only. Do *NOT* supply it as is without review,\nand do *NOT* provide it in real time to your partners.\n --><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Shibboleth.DEPRECATIONWarning\">Shibboleth.DEPRECATION&nbsp;Warning<\/h2>\n\n\n\n<p>Related to the above, we are seeing the following when running a test of the Shibboleth configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@ip-192-168-0-27:\/etc\/shibboleth# shibd -t\n2025-04-14 12:15:57 WARN Shibboleth.DEPRECATION : MetadataGenerator handler\noverall configuration is loadable, check console or log for non-fatal problems<\/code><\/pre>\n\n\n\n<p>As discussed in:&nbsp;<a href=\"https:\/\/help.switch.ch\/aai\/guides\/sp\/configuration\/\">https:\/\/help.switch.ch\/aai\/guides\/sp\/configuration\/<\/a>, that since SPv3.3 the&nbsp;MetadataGenerator&nbsp;handler line within \/etc\/shibboleth\/shibboleth2.xml&nbsp; causes a: &#8220;WARN&nbsp;Shibboleth.DEPRECATION&nbsp;:&nbsp;MetadataGenerator&nbsp;handler&#8221; message.&nbsp;According to this:&nbsp;<a href=\"https:\/\/it.umn.edu\/services-technologies\/resources\/creating-metadata-file-your-sp\">https:\/\/it.umn.edu\/services-technologies\/resources\/creating-metadata-file-your-sp<\/a>&nbsp;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.&nbsp;<\/p>\n\n\n\n<p>To suppress the message disable the handler by commenting out the following line in&nbsp;<strong>\/etc\/shibboleth2.xml<\/strong>, then restarting&nbsp;shibd&nbsp;with:&nbsp;<strong>systemctl restart&nbsp;shibd<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Handler type=\"MetadataGenerator\" Location=\"\/Metadata\" signing=\"false\"\/><\/code><\/pre>\n\n\n\n<p>Note that when you disable this the metadata will no longer be available at:&nbsp;<a href=\"https:\/\/www.tristanself.co.uk\/Shibboleth.sso\/Metadata\">https:\/\/www.tristanself.co.uk\/Shibboleth.sso\/Metadata<\/a>.<\/p>\n\n\n\n<p>The guidance that talks about running this command to generate the sP metadata appears to be no longer relevant.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shib-metagen -2 -c sp-signing-cert.pem -h www.tristanself.co.uk -e https:\/\/www.tristanself.co.uk\/Shibboleth > sp-metadata.xml<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-OKTAandShibbolethsPwithSigned\/EncryptedAssertions\">OKTA and Shibboleth sP with Signed\/Encrypted Assertions<\/h2>\n\n\n\n<p>Up until now we&#8217;ve had OKTA configured to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign the SAML response message.<\/li>\n\n\n\n<li>Sign the SAML assertion within the SAML response message.<\/li>\n<\/ul>\n\n\n\n<p>The Shibboleth sP having a copy of the IdP&#8217;s metadata, has a copy of the IdP&#8217;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.<\/p>\n\n\n\n<p>However, we&#8217;ve not got the SAML assertion content encrypted when it is sent to the Shibboleth sP, so we&#8217;ll see about enabling &#8220;Assertion Encryption&#8221; on OKTA (IdP) to encrypt the actual assertions so they can only be read by the IdP and sP.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ObtaintheSigningCertificateandEncryptionCertificatefromtheServiceProvider(sP)\">Obtain the Signing Certificate and Encryption Certificate from the Service Provider (sP)<\/h3>\n\n\n\n<p>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&nbsp;<strong>\/etc\/shibboleth\/sp-encrypt-cert.pem<\/strong>&nbsp;and&nbsp;<strong>\/etc\/shibboleth\/sp-signing-cert.pem<\/strong>&nbsp;files. Copy these to your machine because we&#8217;ll need these for the next step to upload into OKTA. OKTA doesn&#8217;t appear to be able to take certificates from URLs via metadata.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ConfigureOKTA(IdP)forAssertionEncryption\">Configure OKTA (IdP) for Assertion Encryption<\/h3>\n\n\n\n<p>1. Open your OKTA application, which we created earlier via the OKTA admin console.<\/p>\n\n\n\n<p>2. Click on &#8220;General&#8221; and then edit the &#8220;SAML Settings&#8221;, then &#8220;Show Advanced Settings&#8221;.<\/p>\n\n\n\n<p>3. Set the &#8220;Assertion Encryption&#8221; to &#8220;Encrypted&#8221;.<\/p>\n\n\n\n<p>4. Set the &#8220;Encryption Algorithm&#8221; to &#8220;AES256-CBC&#8221;.<\/p>\n\n\n\n<p>5. Set the &#8220;Key Transport Algorithm&#8221; to &#8220;RSA-OAEP&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"577\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25-1024x577.png\" alt=\"\" class=\"wp-image-4474\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25-1024x577.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25-300x169.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25-768x433.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25-1536x865.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-25.png 1663w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>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&#8217;s metadata.<\/p>\n\n\n\n<p>6. Using the two certificate files you got earlier, upload the&nbsp;<strong>sp-encrypt-cert.pem<\/strong>&nbsp;for the &#8220;Encryption Certificate&#8221; and the&nbsp;<strong>sp-signing-cert.pem<\/strong>&nbsp;for the &#8220;Signature Certificate&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"606\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26-1024x606.png\" alt=\"\" class=\"wp-image-4475\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26-1024x606.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26-300x178.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26-768x455.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26-1536x909.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-26.png 1830w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"829\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-27-1024x829.png\" alt=\"\" class=\"wp-image-4476\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-27-1024x829.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-27-300x243.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-27-768x622.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-27.png 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>7. Then save the SAML settings to confirm your changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-TestingtoConfirm\">Testing to Confirm<\/h2>\n\n\n\n<p>Now try to log on to your test website with the DEBUG logging enabled (see the &#8220;Extra Debug Logging&#8221; section above) once applied restart Shibboleth sP.<\/p>\n\n\n\n<p>Now when you attempt a login you&#8217;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&#8217;ll see output go back to what it was showing before that the assertions are not encrypted.<\/p>\n\n\n\n<p>Some sample output is given below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"273\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28-1024x273.png\" alt=\"\" class=\"wp-image-4477\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28-1024x273.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28-300x80.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28-768x204.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28-1536x409.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-28.png 1623w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"506\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29-1024x506.png\" alt=\"\" class=\"wp-image-4478\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29-1024x506.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29-300x148.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29-768x380.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29-1536x759.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-29.png 1622w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-WebsiteLogout\">Website Logout<\/h2>\n\n\n\n<p>The Logout of SAML is a can of worms, in this case however, we are going to use an example of &#8220;Global Logout&#8221;.<\/p>\n\n\n\n<p>The example shows how to configure &#8220;Global Logout&#8221;, 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 &#8211; 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&#8217;t just swoop in and access another site (which wasn&#8217;t logged out), and accesses confidential information or services. Conversely, &#8220;Local Logout&#8221; 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&#8217;s fine for a single user machine, but not desirable for a shared computer.<\/p>\n\n\n\n<p>In this example we&#8217;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 &#8220;Enable Single Logout&#8221; 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 &#8220;Allow application to initiate Single Logout&#8221; as shown below, and then removing the &#8220;SAML2&#8221; from the \/etc\/shibboleth2\/shibboleth2.xml definition so only &#8220;Local&#8221; is left.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Logout>SAML2 Local&lt;\/Logout><\/code><\/pre>\n\n\n\n<p>How the log-out function works in Local Logout and Global Logout configuration.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"509\" height=\"194\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-30.png\" alt=\"\" class=\"wp-image-4479\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-30.png 509w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-30-300x114.png 300w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ConfigureOKTAApplicationforGlobalLogout\">Configure OKTA Application for Global Logout<\/h3>\n\n\n\n<p>Firstly you need to make an adjustment to our OKTA application that works with our Shibboleth sP.<\/p>\n\n\n\n<p>Edit the &#8220;SAML Settings&#8221;, then tick the box for &#8220;Enable Single Logout&#8221;, then complete the fields as shown.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"778\" height=\"210\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-31.png\" alt=\"\" class=\"wp-image-4480\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-31.png 778w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-31-300x81.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-31-768x207.png 768w\" sizes=\"auto, (max-width: 778px) 100vw, 778px\" \/><\/figure>\n\n\n\n<p>Save your configuration.<\/p>\n\n\n\n<p>On the Shibboleth sP, you should now force a download of the updated metadata just to be sure (which will restart the Shibboleth sP).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/opt\/shibboleth\/update-idp-metadata.sh<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ConfigureShibbolethsPforGlobalLogout\">Configure Shibboleth sP for Global Logout<\/h3>\n\n\n\n<p>Before we can test we now need to configure the Shibboleth sP for Global Logout. You&#8217;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.&nbsp;<a href=\"https:\/\/ssg-confluence.internal.sanger.ac.uk\/Shibboleth.sso\/Logout\">\/Shibboleth.sso\/Logout<\/a>) 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.<\/p>\n\n\n\n<p>On Shibboleth sP remove the &#8220;Local&#8221; from the following line in the etc\/shibboleth2.xml config, so it only says &#8220;SAML2&#8221;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n&lt;Logout>SAML2 Local&lt;\/Logout>\n...<\/code><\/pre>\n\n\n\n<p>Download new metadata from the IDP, and restart Shibboleth sP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Testing\">Testing<\/h2>\n\n\n\n<p>Now we have configured the Global Logout, let&#8217;s give it a try.<\/p>\n\n\n\n<p>Go to the test website, then click the &#8220;Secure Site&#8221; link, you&#8217;ll then be redirected to the OKTA Login page, where you need to log in.<\/p>\n\n\n\n<p>Once successfully logged in, now click on the &#8220;Shibboleth Logout&#8221; link, where you&#8217;ll now see:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"888\" height=\"298\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-32.png\" alt=\"\" class=\"wp-image-4481\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-32.png 888w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-32-300x101.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-32-768x258.png 768w\" sizes=\"auto, (max-width: 888px) 100vw, 888px\" \/><\/figure>\n\n\n\n<p>What is interesting is then if you go to your organisation&#8217;s OKTA front of house page, you&#8217;ll now be required to log in, this shows how you have been fully logged out from both the sP and the IdP.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"893\" height=\"770\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-33.png\" alt=\"\" class=\"wp-image-4482\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-33.png 893w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-33-300x259.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-33-768x662.png 768w\" sizes=\"auto, (max-width: 893px) 100vw, 893px\" \/><\/figure>\n\n\n\n<p>When doing this when using a Local Logout you&#8217;ll find you are still logged in to the IdP, even if you&#8217;ve been logged off from the sP. However, you&#8217;ll also find that if you refresh the example website you&#8217;ll end up logging back on again.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Option2-ExampleSiteAuthenticatedwithOpenAthensandShibbolethsP\">Option 2 &#8211; Example Site Authenticated with&nbsp;OpenAthens&nbsp;and Shibboleth sP<\/h1>\n\n\n\n<p>Using&nbsp;OpenAthens as&nbsp;the IdP instead of OKTA is actually a fairly minimal change to the configuration. In our example we use OKTA and&nbsp;OpenAthens for&nbsp;two different use cases, and&nbsp;OpenAthens uses&nbsp;OKTA as the directory source, however that is not really relevant for the purposes of this example deployment.<\/p>\n\n\n\n<p>OpenAthens provide&nbsp;guidance here:&nbsp;<a href=\"https:\/\/docs.openathens.net\/providers\/openathens-idp-elements#OpenAthensIdPelements-Ifyouareusingothersoftware(suchasShibboleth)\">https:\/\/docs.openathens.net\/providers\/openathens-idp-elements#OpenAthensIdPelements-Ifyouareusingothersoftware(suchasShibboleth)<\/a><\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/ssg-confluence.internal.sanger.ac.uk\/s\/hqtir2\/9012\/9rxlc3\/_\/images\/icons\/emoticons\/warning.svg\" alt=\"(warning)\">&nbsp;<strong>&nbsp;These instructions for option 2 are written assuming you&#8217;ve already configured Shibboleth sP to work with OKTA, so we are reconfiguring what is already there to work&nbsp;with OpenAthens; to avoid having to repeat much of the documentation!<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-OpenAthensConfiguration\">OpenAthens Configuration<\/h2>\n\n\n\n<p>We first need to create a &#8220;Resource&#8221;&nbsp;within OpenAthens, to do this, open the&nbsp;OpenAthens admin&nbsp;web console then:<\/p>\n\n\n\n<p>1. Click on &#8220;Resources&#8221;, then &#8220;Catalogue&#8221;. Then click on &#8220;Custom&#8221;, as we&#8217;ll be creating a custom resource for our Shibboleth sP.<\/p>\n\n\n\n<p>2. Click on &#8220;Create&#8221;, then select &#8220;SAML&#8221; as the resource type, then &#8220;Configure&#8221;.<\/p>\n\n\n\n<p>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&nbsp;<a href=\"https:\/\/www.tristanself.co.uk\/Shibboleth.SSO\/Metadata\">https:\/\/www.tristanself.co.uk\/Shibboleth.SSO\/Metadata<\/a>&nbsp;is not customised.<\/p>\n\n\n\n<p>4. Click &#8220;Create Resource&#8221;.<\/p>\n\n\n\n<p>5. If you wish you can add the Access URL on the &#8220;Resource Details&#8221; page, I used:&nbsp;<a href=\"https:\/\/www.tristanself.co.uk\/secure.\">https:\/\/www.tristanself.co.uk\/secure<\/a><\/p>\n\n\n\n<p>That&#8217;s it, you&#8217;re ready to move on with the configuration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-OpenAthensMetadataLocationandConfiguration\">OpenAthens Metadata&nbsp;Location and Configuration<\/h2>\n\n\n\n<p>The document above says where you can get the&nbsp;OpenAthens Federation&nbsp;metadata from, to quote.<\/p>\n\n\n\n<p>&#8220;<em>If you are using other software (such as Shibboleth).&nbsp;If you are not ready to add the&nbsp;OpenAthens federation&nbsp;metadata to your SP, you can add the metadata for just your&nbsp;own OpenAthens&nbsp;IdP:&nbsp;https:\/\/login.openathens.net\/saml\/2\/metadata-idp\/YOUR_OPENATHENS_API_NAME<\/em>&#8220;<\/p>\n\n\n\n<p>So in our case our API name is domain.com, therefore our metadata for\u00a0OpenAthens can\u00a0be found at:\u00a0<a href=\"https:\/\/login.openathens.net\/saml\/2\/metadata-idp\/domain.com\">https:\/\/login.openathens.net\/saml\/2\/metadata-idp\/domain.com<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ShibbolethsPConfigurationChanges\">Shibboleth sP Configuration Changes<\/h2>\n\n\n\n<p>To set Shibboleth sP to work with&nbsp;OpenAthens you&nbsp;need to perform the following changes.&nbsp;These steps have been written assuming you&#8217;ve already configured Shibboleth sP and the test site to use OKTA, so we&#8217;ll be swapping some of the settings, rather than starting afresh.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-UpdateEntityID\">Update&nbsp;EntityID<\/h3>\n\n\n\n<p>Within&nbsp;<strong>\/etc\/shibboleth\/shibboleth2.xml<\/strong>&nbsp;file you need to swap the&nbsp;EntityID to&nbsp;the&nbsp;OpenAthens&nbsp;Entity ID, so find the section where you have the OKTA&nbsp;EntityID&nbsp;and swap the value, for example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;SSO entityID=\"https:\/\/idp.domain.com\/idp\/shibboleth\"\n     discoveryProtocol=\"SAMLDS\" discoveryURL=\"https:\/\/ds.example.org\/DS\/WAYF\">\n     SAML2\n&lt;\/SSO><\/code><\/pre>\n\n\n\n<p>Set the entity ID to\u00a0<a href=\"https:\/\/idp.domain.com\/idp\/shibboleth\">https:\/\/idp.domain.com\/idp\/shibboleth<\/a>\u00a0in the following file (in this test it was already set to Okta):<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-MetadataConfiguration\">Metadata Configuration<\/h3>\n\n\n\n<p>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&nbsp;OpenAthens&nbsp;metadata in it instead.<\/p>\n\n\n\n<p>So run the following command to download the&nbsp;OpenAthens Metadata&nbsp;file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/login.openathens.net\/saml\/2\/metadata-idp\/domain.com -O \/etc\/shibboleth\/partner-metadata.xml<\/code><\/pre>\n\n\n\n<p><strong>Note that we have the automated download script, you should either update this script with the new URL for&nbsp;the OpenAthens Metadata&nbsp;or disable it by adding a &#8220;#&#8221; at the beginning of the line within the file in \/etc\/cron.d which was created in the option 1 documentation.<\/strong><\/p>\n\n\n\n<p>Then restart Shibboleth (and Apache):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl restart shibd\nsystemctl restart apache2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-ResolveandDecodeIncomingAttributes.1\">Resolve and Decode Incoming Attributes<\/h3>\n\n\n\n<p>The attribute mapping from&nbsp;OpenAthens is&nbsp;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&#8217;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&#8217;t match the incoming attribute assertion format.<\/p>\n\n\n\n<p>\/etc\/shibboleth\/attribute-map.xml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- Bits I've added to this file -->\n \n&lt;Attribute name=\"mail\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"mail\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"sn\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"sn\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"givenName\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"givenName\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"uid\" nameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\" id=\"uid\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"urn:oid:2.5.4.42\" id=\"givenName\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"urn:oid:2.5.4.4\" id=\"sn\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;!-- End of my bits --><\/code><\/pre>\n\n\n\n<p>We added these two &#8220;givenName&#8221; and &#8220;sn&#8221;, you can see that these have a different format, therefore the previous ones wouldn&#8217;t have matched.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Attribute name=\"urn:oid:2.5.4.42\" id=\"givenName\">\n    &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute>\n \n&lt;Attribute name=\"urn:oid:2.5.4.4\" id=\"sn\">\n        &lt;AttributeDecoder xsi:type=\"StringAttributeDecoder\" caseSensitive=\"false\"\/>\n&lt;\/Attribute><\/code><\/pre>\n\n\n\n<p>Now restart Shibboleth sP and Apache, and we are ready to test. If you have anything you are passing that is not mapped, you&#8217;ll see things like the following upon login within the \/var\/log\/shibboleth\/shibd.log file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:mace:eduserv.org.uk:athens:attribute-def:federation:1.0:identifier\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:0.9.2342.19200300.100.1.3\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:1.3.6.1.4.1.5923.1.1.1.1\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:mace:eduserv.org.uk:athens:attribute-def:organisation:1.0:identifier\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.42\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:1.3.6.1.4.1.5923.1.1.1.11\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: forenames\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: emailAddress\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: surname\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.16.840.1.113730.3.1.241\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: http:\/\/eduserv.org.uk\/federation\/attributes\/1.0\/organisationid\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.4\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: urn:oid:2.5.4.3\n2025-04-16 12:34:22 INFO Shibboleth.AttributeExtractor.XML &#91;1] &#91;default]: skipping SAML 2.0 Attribute with Name: organisationNum<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Testing.1\">Testing<\/h2>\n\n\n\n<p>We can now perform some testing.&nbsp;<\/p>\n\n\n\n<p>Visit the test site, then click on &#8220;Secure Site&#8221;, notice now that we&#8217;re getting a slightly different logon screen within OKTA, note that in our&nbsp;case OpenAthens is&nbsp;the IdP, BUT it is backing off its authentication source to OKTA, if however you are&nbsp;using OpenAthens&nbsp;stand-alone or using it against another Directory Service, e.g.&nbsp;openLDAP&nbsp;or Active Directory, you&#8217;ll see something a bit different.&nbsp;<\/p>\n\n\n\n<p>However, in our case we can see that we&#8217;re authenticating via&nbsp;OpenAthens&nbsp;rather than direct to OKTA via the OKTA application as we did in Option 1.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"963\" height=\"819\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-34.png\" alt=\"\" class=\"wp-image-4484\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-34.png 963w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-34-300x255.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-34-768x653.png 768w\" sizes=\"auto, (max-width: 963px) 100vw, 963px\" \/><\/figure>\n\n\n\n<p>And we&#8217;re in, going to the &#8220;Session&#8221; page within the Secure Site, we can see our attributes being released as expected.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"962\" height=\"434\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-35.png\" alt=\"\" class=\"wp-image-4485\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-35.png 962w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-35-300x135.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/04\/image-35-768x346.png 768w\" sizes=\"auto, (max-width: 962px) 100vw, 962px\" \/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Questions\">Questions<\/h1>\n\n\n\n<p>Some questions that arose from the development of the OKTA and Shibboleth sP Test.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-WhatdoestheNameIDunspecifiedmean?WhatisthedifferenceontheNameIDbit,whatdoesunspecified,persistentandtransientformatsmean?\">What does the&nbsp;NameID&nbsp;unspecified mean? What is the difference on&nbsp;the NameID&nbsp;bit, what does unspecified, persistent and transient formats mean?<\/h2>\n\n\n\n<p>In the context of SAML and Shibboleth, &#8220;NameID&#8221;&nbsp;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.&nbsp;<\/p>\n\n\n\n<p>So what does the different&nbsp;NameID format&nbsp;mean?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Unspecified\">Unspecified<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Format URI: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified<\/li>\n\n\n\n<li>Means the IdP doesn&#8217;t specify how to interpret the identifier \u2014 it&#8217;s up to the SP.<\/li>\n\n\n\n<li>Often used when the value is meaningful only to the SP (e.g., a username like &#8220;jsmith&#8221;).<\/li>\n\n\n\n<li>It can be flexible but may lack interoperability between systems.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Persistent\">Persistent<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Format URI: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent<\/li>\n\n\n\n<li>A long-term, opaque, non-assignable identifier.<\/li>\n\n\n\n<li>Same value sent to the same SP every time, enabling long-term account linking without exposing personal info.<\/li>\n\n\n\n<li>Example: 4f1c2d67-9a67-4d13-82cb-3a15eabcde12<\/li>\n\n\n\n<li>Good for privacy-preserving but consistent user identification.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-Transient\">Transient<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Format URI: urn:oasis:names:tc:SAML:2.0:nameid-format:transient<\/li>\n\n\n\n<li>A temporary, one-time-use identifier.<\/li>\n\n\n\n<li>Only valid for the current session or authentication transaction.<\/li>\n\n\n\n<li>The SP can\u2019t rely on it to link user sessions long-term.<\/li>\n\n\n\n<li>Often used when you don\u2019t want persistent tracking or user identification.<\/li>\n<\/ul>\n\n\n\n<p>So really using Persistent&nbsp;NameID&nbsp;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&#8217;s not a real name, it&#8217;s just an identifier. Transient is when you don&#8217;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&#8217;t care any more than that. e.g. document signing and so forth. Finally, &#8220;unspecified&#8221; is for when the sP requires the&nbsp;NameID&nbsp;contain a specific value, e.g. a username, so there is no need for format enforcement, typically you&#8217;d use this for old applications (e.g. SAML 1.1) or when it&#8217;s an internal system (which wants a specific username) or for quick set up and testing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-WhataboutSAMLassertionshavingaNameFormatofbasic,unspecifiedorURIetc.?\">What about SAML assertions having a Name Format of basic, unspecified or URI etc.?<\/h2>\n\n\n\n<p>Now we are talking&nbsp;NameFormat&nbsp;for SAML attributes, which is different from&nbsp;NameID&nbsp;and assertion confirmation. The attribute&#8217;s&nbsp;NameFormat&nbsp;affects how attributes are interpreted by the sP.<\/p>\n\n\n\n<p>In a SAML&nbsp;AttributeStatement, you send user attributes like email, display name, affiliation, etc. Each attribute has:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A Name (like urn:oid:0.9.2342.19200300.100.1.3 or just email)<\/li>\n\n\n\n<li>A\u00a0NameFormat\u00a0(which tells the SP how to interpret the Name)<\/li>\n\n\n\n<li>Optional\u00a0FriendlyName\u00a0(a human-readable alias)<\/li>\n<\/ul>\n\n\n\n<p>Digging into each&nbsp;NameFormat&nbsp;is:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-1.Unspecified-urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified\">1. Unspecified &#8211; urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Just a raw string \u2014 no special format implied.<\/li>\n\n\n\n<li>Attribute names like &#8220;email&#8221; or &#8220;uid&#8221; are just passed as-is.<\/li>\n\n\n\n<li>Most flexible, but least standardized.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-2.Basic-urn:oasis:names:tc:SAML:2.0:attrname-format:basic\">2. Basic &#8211; urn:oasis:names:tc:SAML:2.0:attrname-format:basic<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Legacy format from SAML 1.1.<\/li>\n\n\n\n<li>Names are often simple strings like &#8220;cn&#8221;, &#8220;sn&#8221;, &#8220;mail&#8221;, &#8220;uid&#8221;.<\/li>\n\n\n\n<li>Still used in some Shibboleth deployments for backward compatibility.<\/li>\n\n\n\n<li>More structured than unspecified but less so than URI.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-3.URI-urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">3. URI &#8211; urn:oasis:names:tc:SAML:2.0:attrname-format:uri<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The recommended standard format in modern SAML 2.0.<\/li>\n\n\n\n<li>Uses URIs to define attribute names, often\u00a0OIDs\u00a0or schemas.<\/li>\n\n\n\n<li>For example:\n<ul class=\"wp-block-list\">\n<li>urn:oid:0.9.2342.19200300.100.1.3 \u2192 email<\/li>\n\n\n\n<li>urn:oid:2.5.4.3 \u2192\u00a0commonName<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Highly interoperable across federations (like eduGAIN).<\/li>\n<\/ul>\n\n\n\n<p>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&#8217;ll have some sort of translation table (attribute-map.xml on Shibboleth sP for example), where you define:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What the IdP sends in the SAML assertion (Name, NameFormat).<\/li>\n\n\n\n<li>What the SP internally refers to that attribute as.<\/li>\n<\/ul>\n\n\n\n<p>So, it uses name + optional&nbsp;nameFormat&nbsp;to match SAML attributes. If there&#8217;s no match, the SP won&#8217;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.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ExampleSiteAuthenticatedwithOKTAandShibbolethsP(orOpenAthensandShibbolethsP)-AdditionalInformation\">Additional Information<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686\">https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/support.aaf.edu.au\/support\/solutions\/articles\/19000035962-installing-a-shibboleth-service-provider\">https:\/\/support.aaf.edu.au\/support\/solutions\/articles\/19000035962-installing-a-shibboleth-service-provider<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/spaces.at.internet2.edu\/display\/federation\/SP+Testing+for+SAML2\">https:\/\/spaces.at.internet2.edu\/display\/federation\/SP+Testing+for+SAML2<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.eduvpn.org\/server\/v3\/shibboleth-sp.html\">https:\/\/docs.eduvpn.org\/server\/v3\/shibboleth-sp.html<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686\">https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.iam.harvard.edu\/resources\/saml-shibboleth-integration\">https:\/\/www.iam.harvard.edu\/resources\/saml-shibboleth-integration<\/a><a href=\"https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686\">https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.shib.ncsu.edu\/docs\/logout.html\">https:\/\/docs.shib.ncsu.edu\/docs\/logout.html<\/a><a href=\"https:\/\/help.it.ox.ac.uk\/installing-shibboleth-sp-for-apache#collapse2307686\"><br><\/a><a href=\"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:\/\/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<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/it.umn.edu\/services-technologies\/resources\/creating-metadata-file-your-sp\">https:\/\/it.umn.edu\/services-technologies\/resources\/creating-metadata-file-your-sp<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/iam.alaska.edu\/shib\/wiki\/SpSetup\">https:\/\/iam.alaska.edu\/shib\/wiki\/SpSetup<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.ukfederation.org.uk\/content\/Documents\/Setup3SP\">https:\/\/www.ukfederation.org.uk\/content\/Documents\/Setup3SP<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/help.switch.ch\/aai\/guides\/sp\/logout\/\">https:\/\/help.switch.ch\/aai\/guides\/sp\/logout\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/uwconnect.uw.edu\/it?id=kb_article_view&amp;sysparm_article=KB0033930\">https:\/\/uwconnect.uw.edu\/it?id=kb_article_view&amp;sysparm_article=KB0033930<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>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 &#8230; <a title=\"Example Site Authenticated with OKTA and Shibboleth sP (or OpenAthens and Shibboleth sP)\" class=\"read-more\" href=\"https:\/\/geekmungus.co.uk\/?p=4452\" aria-label=\"Read more about Example Site Authenticated with OKTA and Shibboleth sP (or OpenAthens and Shibboleth sP)\">Read more<\/a><\/p>\n","protected":false},"author":4,"featured_media":4373,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35,53,22],"tags":[],"class_list":["post-4452","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-okta","category-saml","category-security"],"_links":{"self":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4452"}],"version-history":[{"count":11,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4452\/revisions"}],"predecessor-version":[{"id":4487,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4452\/revisions\/4487"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/media\/4373"}],"wp:attachment":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}