Shibboleth Service Provider on virtual hosts serving multiple applications

Multidomain Environment

The Shibboleth SP can be used in a multi-domain environment, this is particularly relevant in a shared web-hosting scenario where a number of web applications will have different Shibboleth configurations using the same instance of Shibboleth (i.e.. different domain on same server, or differing attribute requirements per-application). The example below shows how this configuration can be achieved,

Let's presume we have set one service called: library.example.com and it's protected by shibboleth and in the production Edugate federation. Now we want protect another on called maths.example.com which is on the same host and part of the test Edugate federation.

Shibboleth configuration

You need to create new certificate and key for shibboleth (not Apache), in this example they will be named maths-example-com-key.pem and maths-example-com-cert.pem. The certificates and keys must be configured within shibboleth2.xml file for for each multidomain SP as follows; Firstly copy the piece of code

<ApplicationDefaults ...>
....
....
</ApplicationDefaults>

replace ApplicationDefaults with ApplicationOverride and paste in just before

</ApplicationDefaults>

You then need to modify this part of code. It is very important to define settings specific to the maths.example.com domain inside<ApplicationOverride > and </ApplicationOverride > 
For example;

<ApplicationOverride id="maths-example-com" 
         entityID="https://maths.example.com/shiboleth"
         REMOTE_USER="eppn"
         signing="false" encryption="false">
       <Sessions lifetime="28800" timeout="3600" checkAddress="false"
           handlerURL="/Shibboleth.sso" handlerSSL="false"
           exportLocation="http://localhost/Shibboleth.sso/GetAssertion" 
           exportACL="127.0.0.1"
           idpHistory="false" idpHistoryDays="7">

          <!-- Default example directs to a specific 
              IdP's SSO service (favoring SAML 2 over Shib 1). -->
          <SessionInitiator type="Chaining" Location="/Login"  id="Intranet"
                   relayState="cookie"
                   entityID="https://defaul-idp.example.com/idp/shibboleth">
              <SessionInitiator type="SAML2" acsIndex="1" 
                       template="bindingTemplate.html"/>
              <SessionInitiator type="Shib1" acsIndex="5"/>
          </SessionInitiator>

          <!-- An example using an old-style WAYF, which means Shib 1 only
                  unless an entityID is provided. -->
          <SessionInitiator type="Chaining" Location="/WAYF" id="WAYF"
                  relayState="cookie">
              <SessionInitiator type="SAML2" acsIndex="1"
                      template="bindingTemplate.html"/>
              <SessionInitiator type="Shib1" acsIndex="5"/>
              <SessionInitiator type="WAYF" acsIndex="5"
                      URL="https://wayf.example.org/WAYF"/>
          </SessionInitiator>

          <!-- example supporting the new-style of discovery service. -->
          <SessionInitiator type="Chaining" Location="/DS" id="DS"
                  isDefault="true" relayState="cookie">
              <SessionInitiator type="SAML2" acsIndex="1"
                      template="bindingTemplate.html"/>
              <SessionInitiator type="Shib1" acsIndex="5"/>
              <SessionInitiator type="SAMLDS"
                      URL="https://ds.heanet.ie/DS/"/>
          </SessionInitiator>

        <md:AssertionConsumerService Location="/SAML2/POST" index="1"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
        <md:AssertionConsumerService Location="/SAML2/POST-SimpleSign" index="2"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"/>
          <md:AssertionConsumerService Location="/SAML2/Artifact" index="3"
               Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
          <md:AssertionConsumerService Location="/SAML2/ECP" index="4"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"/>
          <md:AssertionConsumerService Location="/SAML/POST" index="5"
              Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"/>
          <md:AssertionConsumerService Location="/SAML/Artifact" index="6"
              Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"/>

          <!-- LogoutInitiators enable SP-initiated local or global/single logout of sessions. -->
          <LogoutInitiator type="Chaining" Location="/Logout" relayState="cookie">
              <LogoutInitiator type="SAML2" template="bindingTemplate.html"/>
              <LogoutInitiator type="Local"/>
          </LogoutInitiator>

          <!-- md:SingleLogoutService locations handle single logout (SLO) protocol messages. -->
          <md:SingleLogoutService Location="/SLO/SOAP"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"/>
          <md:SingleLogoutService Location="/SLO/Redirect" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"/>
          <md:SingleLogoutService Location="/SLO/POST" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
          <md:SingleLogoutService Location="/SLO/Artifact" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
       <!-- md:ManageNameIDService locations handle NameID management (NIM) protocol messages. -->
          <md:ManageNameIDService Location="/NIM/SOAP"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"/>
          <md:ManageNameIDService Location="/NIM/Redirect" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"/>
          <md:ManageNameIDService Location="/NIM/POST" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
          <md:ManageNameIDService Location="/NIM/Artifact" conf:template="bindingTemplate.html"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
          <!--
          md:ArtifactResolutionService locations resolve artifacts issued when using the
           SAML 2.0 HTTP-Artifact binding on outgoing messages, generally uses SOAP.
          -->
          <md:ArtifactResolutionService Location="/Artifact/SOAP" index="1"
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"/>

          <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
          <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>

          <!-- Status reporting service. -->
          <Handler type="Status" Location="/Status" acl="127.0.0.1"/>

          <!-- Session diagnostic service. -->
          <Handler type="Session" Location="/Session" showAttributeValues="false"/>

      </Sessions>
          <!-- List of metadata locations which contain trusted Idps. This is just example -->
      <MetadataProvider type="Chaining">
          <!-- Example of remotely supplied batch of signed metadata. -->
          <!--
          <MetadataProvider type="XML" uri="http://edugate-test.heanet.ie/edugate-test-metadata-signed.xml"
               backingFilePath="federation-metadata.xml" reloadInterval="7200">
             <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
             <MetadataFilter type="Signature" certificate="fedsigner.pem"/ >
          </MetadataProvider>
          -- >
      <AttributeFilter type="XML" validate="true" 
                 path="maths-incoming-attribute-policy-.xml"/>
      <CredentialResolver type="File" key="maths-example-com-key.pem" 
                 certificate="maths-example-com-cert.pem"/>

      </ApplicationOverride>

Note: usually you only need copy parts which you want to change, see the the configuration for the library.example.com which has a different entityID, federation metadata, different policy on signing and encrypting SAML messages and different certificates for signing and encryption. It also has longer session and metadata lifetimes;

<ApplicationOverride id="library-example-com" 
         entityID="https://library.example.com/shiboleth"
         REMOTE_USER="email"
         signing="true" encryption="false">
       	<Sessions lifetime="80000" timeout="36000" checkAddress="false"
           handlerURL="/Shibboleth.sso" handlerSSL="false"
           exportLocation="http://localhost/Shibboleth.sso/GetAssertion" 
           exportACL="127.0.0.1"
           idpHistory="false" idpHistoryDays="7">
	
           <SessionInitiator type="Chaining" Location="/DS" id="DS"
                  isDefault="true" relayState="cookie">
              <SessionInitiator type="SAML2" acsIndex="1"
                      template="bindingTemplate.html"/>
              <SessionInitiator type="Shib1" acsIndex="5"/>
              <SessionInitiator type="SAMLDS"
                      URL="https://wayf.heanet.ie/WAYF/WAYF"/>
          </SessionInitiator>
	</Sessions>
          
	<MetadataProvider type="XML" uri="https://edugate.heanet.ie/edugate-federation-metadata-signed.xml"
               backingFilePath="libraryt-federation-metadata.xml" reloadInterval="72000">
             <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
             <MetadataFilter type="Signature" certificate="fedsigner.pem"/ >
          </MetadataProvider
      <AttributeFilter type="XML" validate="true" 
                 path="library-incoming-attribute-policy.xml"/>
      <CredentialResolver type="File" key="library-example-com-key.pem" 
                 certificate="library-example-com-cert.pem"/>

</ApplicationOverride>

 

Any changes made to the Shibboleth2.xml file can be checked for errors as follows;

/usr/sbin/shibd -t /etc/shibboleth/shibboleth2.xml

Apache configuration
You need to set which part of shibboleth configuration will be used by specific virtualhost.
As you see your new configuration has id="maths-example-com" so to load this configuration you need add below code into (apache) maths.example.com virtualhost

ShibRequestSetting applicationId maths-example-com

The library application, which will require Shibboleth authentication for the entire library.example.com domain rather than specifific Location's, would be configured as follows

ShibRequestSetting applicationId library-example-com
ShibRequireSession On

Note: If ShibRequestSetting is not set in VirtualHost then default (ApplicationDefault id="default") shibboleth config is used.