Superseded install guide

Note: This version of the IdP Install Guide has been superseded. Please refer to the IdP Overview page for the latest version of this guide.



Installing a Shibboleth 2.x IdP

 Software  Version Provide by  Since
 Shibboleth  2.3.6 A Project of the Internet2 Middleware Initiative Feb 27th, 2012
 uApprove  2.4.1 SWITCHaai 

This page is a guide to installing a Shibboleth 2.3.6 and later IdP. This page assumes the IdP would be installed on a blank Linux system (typically a virtual machine) and follows from that point on. The IdP will be installed both with the Shibboleth IdP software and the uApprove attribute release approval web application.

This guide is periodically updated as new versions of the software installed become available. This guide is current for IdP 2.3.6 and uApprove 2.?.?. The guide is written with assumption that CentOS/RHEL 6 as the OS and Tomcat6 as the web application server.

Securing your server on which you deploy your IdP is essential to maintain the federation trust. This guide does not cover server setup or security.

During the installation there will be a number of tests to confirm previous steps have been performed correctly. These tests are tagged with the  icon to the left. For a successful installation please ensure all tests are completed before moving to the next step. If you have difficulty completing a test please contact the AAF support desk support@aaf.edu.au for assistance.



Modifications to Identity Management system

Your Identity Management System (IdMS) will very likely have most of the attributes asked for by the federation - or will have enough information to synthesize the specific attribute values on the fly inside the IdP. But for some attributes, the IdMS might not have enough information. The following information should be considered for adding into your IdMS:
  • eduPersonEntitlement: The eduPersonEntitlement attribute is a storage container for values representing privileges to access resources within the federation. It is a multi-valued string attribute. The values will have the form of a URI - with specific values that are yet to be defined.

eduPersonEntitlement

Origin/ObjectClass: 
eduPerson [eduPerson]
OID:  1.3.6.1.4.1.5923.1.1.1.7 
SAML attribute name: urn:mace:dir:attribute-def:eduPersonEntitlement 
LDAP syntax:  directoryString [1.3.6.1.4.1.1466.115.121.1.15] 
Number of values:  Multiple 
Example values:  urn:mace:washington.edu:confocalMicroscope 
http://publisher.example.com/contract/GL123
  • auEduPersonSharedToken: The auEduPersonSharedToken uniquely identifies users when accessing certain resources - particularly within the computational grid and data grid. The values should be opaque, non-reassignable and persistent - and transferrable when a user moves between institutions. Even though the values are typically created as hash-values on first use, they MUST be stored and each institution must be ready to accept values users already have when coming from another institution. The attribute can be stored in either the IdMS directly (preferred), or in a database. 

auEduPersonSharedToken

Origin/ObjectClass:  auEduPerson 
OID:  1.3.6.1.4.1.27856.1.2.5 
SAML attribute name:   urn:mace:federation.org.au:attribute:auEduPersonSharedToken 
LDAP syntax:  directoryString [1.3.6.1.4.1.27856.1.2.5] 
Number of values:  Single 
Example values:  ZsiAvfxa0BXULgcz7QXknbGtfxk 


  • eduPersonAssurance: This attribute represents the Levels of Assurance. Either add the attribute into the IdMS directly, or start collecting enough information to synthesize the values later in a scripted attribute definition (like done for Affiliation below).  

eduPersonAssurance

Origin/ObjectClass:  eduPerson 
OID:  1.3.6.1.4.1.5923.1.1.1.11 
SAML attribute name:  urn:oid:1.3.6.1.4.1.5923.1.1.1.11 
LDAP syntax:   directoryString [1.3.6.1.4.1.1466.115.121.1.15] 
Number of values:  multiple 
Example values:  See AAF IdentityLoA Vocabulary 



Preliminaries

System firewall configuration

If you are implementing a local firewall on the server using iptables you need to permit incoming traffic to ports 80, 443 and 8443. The following configuration will apply.

  • Edit /etc/sysconfig/iptables and add rules to permit incoming traffic to ports 80, 443, and 8443;
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8443 -j ACCEPT

  • Restart iptables:
service iptables restart


Bootstrapping the VM

We assume a standard install of either CentOS or RHEL, version 6. 

NOTE: CentOS/RHEL 5: The IdP web application will run inside Tomcat  6. CentOS/RHEL 5 comes with Tomcat5 but can NOT be used by Shibboleth. Tomcat6 can be installed from JPackage or installing from a tar-ball from Apache

Note: Shibboleth has not been verified with Tomcat 7 yet, use the latest Tomcat 6 version only.


Install packages

  • Apache with mod_ssl, Java (with javac) and Tomcat:
yum -y install httpd mod_ssl java-1.6.0-openjdk java-1.6.0-openjdk-devel ant tomcat6

  • MySQL (needed for storing sharedToken values and uApprove attribute release approvals)
MySQL is not strictly required and an alternative database system may be used if already available on site - just use the corresponding JDBC drivers for the alternative database.
yum -y install mysql mysql-server

  • Install NTP (if time synchronization is to be done inside the VM)
yum -y install ntp

Local configuration

  • Configure NTP: time synchronization is crucial for the Shibboleth IdP to correctly interact with Service Providers in the federation. Please gather beforehand the hostname or IP address of the time server provided within your organisation. Further on, we'll assume it's ntp.institution.domain.edu.au. If your organisation is not providing one, you may use an external source (including the default servers listed in /etc/ntp.conf) - but make sure your firewall allows the NTP traffic through (outgoing UDP port 123 traffic + reply packets).
    • Do a one-off synchronization
ntpdate -s ntp.institution.domain.edu.au

    • Edit /etc/ntp.conf and:
      • Comment out local server (server 127.127.1.0 and fudge 127.127.1.0)
      • Comment out CentOS servers (all lines starting with server)
      • The local time server:
server ntp.institution.domain.edu.au

    • Make ntpd start on system startup
chkconfig ntpd on

    • Start ntpd now
service ntpd start

    • Check ntpd is running and synchronizing: run
ntpdc -p

  • Disable SELinux: the Apache LDAP module does not work with SELinux - SELinux would not allow the module to open outgoing TCP connections.
    • Disable SELinux now:
echo 0 > /selinux/enforce

    • And for future restarts, edit /etc/sysconfig/selinux and change:
SELINUX=permissive


Basic Shibboleth IdP and uApprove installation

Rationale and planning

From the very beginning, we will install the Shibboleth IdP:
  • as a web application WAR file managed by Tomcat
  • with uApprove integrated into the web application
  • with a Tomcat login screen used for authentication
Having done these steps early in the installation prevents them from slipping later on.

The installation paths will be (as close to defaults as possible, putting all IdP files under /opt:)
  • IDP_HOME - /opt/shibboleth-idp (default)
  • Tomcat home: /var/lib/$TOMCAT_NAME (where Tomcat web applications and common files live)
Your IdP hostname will be idp.institution.domain.edu.au

Your scope, home organization name and security domain will be institution.domain.edu.au

Your IdP entityId will be https://idp.institution.domain.edu.au/idp/shibboleth

  • The Shibboleth IdP installation directory (from where Shibboleth IdP software is installed) will be /home/shibsrc/shibboleth-identityprovider-<version> - and the name of the directory will be stored in SHIB_INST_HOME (here, we assume version is 2.3.6)
  • The uApprove installation directory will be /home/shibsrc/uApprove-<version> and the name of the directory will be stored in UAPPROVE_INST_HOME (here, we assume version is 2.4.1)
  • Configure the corresponding environment variables: create /etc/profile.d/shib.sh with the following content and make the file executable by all users:

/etc/profile.d/shib.sh

IDP_VERSION="2.3.6"

UAPPROVE_VERSION="2.4.1"
 
SHIB_HOME=/opt/shibboleth-idp
 
SHIB_INST_HOME=/home/shibsrc/shibboleth-identityprovider-$IDP_VERSION
 
IDP_HOME=/opt/shibboleth-idp
 
JAVA_HOME=/usr/lib/jvm/java
 
TOMCAT_NAME=tomcat6
 
TOMCAT_HOME=/var/lib/$TOMCAT_NAME
 
UAPPROVE_INSTALL=/home/shibsrc/uApprove-$UAPPROVE_VERSION

export IDP_VERSION UAPPROVE_VERSION SHIB_HOME IDP_INSTALL IDP_HOME JAVA_HOME TOMCAT_HOME UAPPROVE_INSTALL


  • Load the environment variables into your current environment.
source /etc/profile.d/shib.sh

  • Create a shibsrc user to retain the shibboleth IdP installation files. These will be needed when upgrading your IdP software.
useradd shibsrc



Basic Shibboleth Installation

  • Create an installation directory and download Shibboleth
cd /home/shibsrc
wget http://www.shibboleth.net/downloads/identity-provider/latest/shibboleth-identityprovider-${IDP_VERSION}-bin.zip
unzip shibboleth-identityprovider-${IDP_VERSION}-bin.zip
cd $SHIB_INST_HOME
  • Invoke installer
sh ./install.sh
  • When prompted, give the following non-default answers:
    • FQDN is the hostname assigned to your IdP, typically idp.institution.domain.edu.au
    • Keystore password would be used to create the java keystore containing the back-channel certificates. As the private key will be also stored on disk in an unencrypted X509 key file, there is no need to choose a secure keystore password... (Note: you will need the Keystore password later in this guide).
FQDN: idp.institution.domain.edu.au
Keystore: changeit

Important

When re-running the installer in the future (you'll be asked to do so further on in this guide), you'll be asked whether to overwrite the configuration files. 
It is important you answer NO to that question - otherwise, all modifications made to the configuration files will be lost.
  • This installs the Shibboleth IdP web application into /opt/shibboleth-idp/war/idp.war

Configure Tomcat and deploy the IdP WAR

Context Deployment Fragment

  • Create /etc/$TOMCAT_NAME/Catalina/localhost/idp.xml with the following content:

idp.xml

      <Context docBase="/opt/shibboleth-idp/war/idp.war"
               privileged="true"
               antiResourceLocking="false"
               antiJARLocking="false"
               unpackWAR="false"
               swallowOutput="true" />

Endorsed libraries

  • Endorse XML libraries used by the IdP installed into Tomcat6.
    • Create /var/lib/$TOMCAT_NAME/common/endorsed:
mkdir -p /var/lib/$TOMCAT_NAME/common/endorsed

    • Add the following to /etc/$TOMCAT_NAME/$TOMCAT_NAME.conf to make endorsed directories really work:
JAVA_ENDORSED_DIRS="/var/lib/$TOMCAT_NAME/common/endorsed"

    • Copy all jars from $SHIB_INST_HOME/endorsed/ into this endorsed directory:
cp $SHIB_INST_HOME/endorsed/* /var/lib/$TOMCAT_NAME/common/endorsed


Connectors

  • Connectors in /etc/$TOMCAT_NAME/server.xml, if not already defined, define a n AJP connector at port 8009

Note: Tomcat6 already has this connector defined, but in an insecure way that would be opening the connector to outside connections as well. Comment the original definition out and instead put this definition in.

<Connector port="8009"
           address="127.0.0.1"
           enableLookups="false"
           redirectPort="443"
           protocol="AJP/1.3"
           tomcatAuthentication="false" />

  • And comment out the existing http connector defined for port 8080:
<!--
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
-->


SOAP Endpoints

  • Shibboleth IdPs and SPs may communicate directly, as opposed to sending messages via the user's browser, during certain operations (Attribute Query, Artifact Resolution, and Logout).

cd /usr/share/$TOMCAT_NAME/lib
wget https://build.shibboleth.net/nexus/content/repositories/releases/edu/internet2/middleware/security/tomcat6/tomcat6-dta-ssl/1.0.0/tomcat6-dta-ssl-1.0.0.jar
chmod 644 tomcat6-dta-ssl-1.0.0.jar

    • Add the following connector definition to Tomcat's /etc/$TOMCAT_NAME/server.xml file:
<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11Protocol"
           SSLImplementation="edu.internet2.middleware.security.tomcat6.DelegateToApplicationJSSEImplementation"
           scheme="https"
           SSLEnabled="true" 
           clientAuth="true"
           keystoreFile="$IDP_HOME/credentials/idp.jks"
           keystorePass="$PASSWORD" />

    • Replace $IDP_HOME with the IdP home directory entered during installation.
    • Replace $PASSWORD with the password for the IdP key entered during installation.

Memory settings

  • Tweak Tomcat memory settings: increase the default Java minimal and maximal heap size settings to at least 512MB (or more, depending the total RAM in your VM)
    • Edit /etc/$TOMCAT_NAME/$TOMCAT_NAME.conf and add:
JAVA_OPTS="${JAVA_OPTS} -Xms256m -Xmx768m"

File and Directory permissions

  • Make all files under /opt/shibboleth-idp owned by Tomcat
chown -R tomcat:tomcat $IDP_HOME


Tomcat start-up test

  • At this point Tomcat6 should start without error and the un-configured IdP should also start but will not be able to process logins at this point.  It might take some time for Tomcat to  deploy the web application the first time you start it.
service $TOMCAT_NAME start


  • To verify there are no errors you should check the following log files and confirm there are no errors.
Tomcat logs
    • /var/log/$TOMCAT_NAME/catalina.out 
IdP log
    • $IDP_HOME/logs/idp-process.log
You should correct all errors before moving on.  The final line of this log after a successful startup should similar to the following:
INFO [edu.internet2.middleware.shibboleth.common.config.BaseService:180] - shibboleth.HandlerManager service loaded new configuration




Configure Apache

Configuration

Apache needs to be configured to:
  • Listen on ports 443 - this is done via a separate configuration file idp.conf  (bypassing parts of the default configuration in ssl.conf)
  • Configured to disable SSL session cache to work around a bug
  • To configure the virtual host for ports 443, download the files attached to this page into idp.conf the Apache configuration directory /etc/httpd/conf.d
  • In the files, replace all occurrences of  idp.institute.edu.au with the hostname of your IdP
  • In idp.conf, configure the SSL VirtualHost to use the commercial certificate issued for your IdP
  • Make a backup of your ssl.conf
cd /etc/httpd/conf.d/
cp ssl.conf ssl.conf.dist

  • Edit your ssl.conf and:
    • Disable SSL session cache by commenting out the default SSLSessionCache directive and instead setting the cache to none:
#SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCache         none

  • Delete the whole default <VirtualHost> section from ssl.conf (the definitions in idp.conf will be used instead).
  • Delete the entry for Listen 443 (because we now have the directive in idp.conf).

Testing Apache

  • Start Apache.
service httpd start

  • Navigate to the IdP login page https://idp.institute.domain.edu.au/idp/Authn/UserPassword. This should result in a page similar to the following.



Basic Shibboleth Configuration

Load the Federation Metadata

  • Configure the IdP to load the Federation Metadata in $IDP_HOME/conf/relying-party.xml by adding the following snippets into the Chaining MetadataProvider.
Note: There are three versions of the AAF Metadata, this installation uses the Complete Metadata. This version of the Metadata will continue to expand and grow as new features become available. For more information on the other version of Metadata see the knowledge base article "Two version of the AAF Metadata available".

<!-- AAF Federation metadata -->
<metadata:MetadataProvider id="AAF" xsi:type="metadata:FileBackedHTTPMetadataProvider"
                          metadataURL="http://manager.test.aaf.edu.au/metadata/metadata.aaf.signed.complete.xml"
                          backingFile="/opt/shibboleth-idp/metadata/AAF-metadata.xml">
            <metadata:MetadataFilter xsi:type="metadata:ChainingFilter">
                <metadata:MetadataFilter xsi:type="metadata:RequiredValidUntil"
                                maxValidityInterval="864000" />
                <metadata:MetadataFilter xsi:type="metadata:SignatureValidation"
                                trustEngineRef="shibboleth.MetadataTrustEngine"
                                requireSignedMetadata="true" />
                <metadata:MetadataFilter xsi:type="metadata:EntityRoleWhiteList">
                    <metadata:RetainedRole>samlmd:SPSSODescriptor</metadata:RetainedRole>
                </metadata:MetadataFilter>
                <metadata:MetadataFilter xsi:type="metadata:SchemaValidation"/>
            </metadata:MetadataFilter>
        </metadata:MetadataProvider>

Important: AAF Test environment metadata is being loaded. Remove '.test' from the Metadata URL to use the AAF Production version.

  • The AAF metadata should have their signature verified: add the trust engine definition as well (or uncomment and configure it further down in the file):
    <!-- Trust engine used to evaluate the signature on loaded AAF metadata. -->

    <security:TrustEngine id="shibboleth.MetadataTrustEngine" xsi:type="security:StaticPKIXSignature">
        <security:ValidationInfo id="AAFCredentials" xsi:type="security:PKIXFilesystem">
            <security:Certificate>/opt/shibboleth-idp/credentials/aaf-metadata-cert.pem</security:Certificate>
        </security:ValidationInfo>
    </security:TrustEngine>


  • This definition is referring to a certificate used to verify the signature - store the certificate in /opt/shibboleth-idp/credentials
cd /opt/shibboleth-idp/credentials

# For the AAF Test Environment
wget  https://manager.test.aaf.edu.au/metadata/metadata-cert.pem -O aaf-metadata-cert.pem

# For the AAF Production Environment
wget  https://manager.aaf.edu.au/metadata/metadata-cert.pem -O aaf-metadata-cert.pem

  • Note that the relying-party.xml file also refers to:
    • Our own metadata generated for the IdP in /opt/shibboleth-idp/metadata/idp-metadata.xml
    • Our own credentials stored in /opt/shibboleth-idp/credentials/idp.crt and /opt/shibboleth-idp/credentials/idp.key
    • Our own entityId (also stored in the self-metadata in /opt/shibboleth-idp/metadata/idp-metadata.xml

Test Metadata Loading

  • Restart Tomcat to force the IdP to download and consume the AAF Metadata.
service $TOMCAT_NAME restart

  • Check that Tomcat restarted with no problems.  Note that it might take some time for Tomcat to download the metadata files.  Evidence of this occurring will be found by
    • The creation of updating of the AAF Metadata file /opt/shibboleth-idp/metadata/AAF-metadata.xml
    • Logs in the log file /opt/shibboleth-idp/logs/idp-process.log




Configure IdP with a login screen

It is desirable to have a site-branded login screen - which makes it easier for users to recognize the proper login screen - and may be necessary for deploying site-wide login and password-handling policies. The credentials are then cached only for a given period of time - instead of the whole browser session.

For deploying a login screen for a Shibboleth 2.x IdP:
  • Edit $IDP_HOME/conf/handler.xml and
    • Uncomment Username/Password Login Handler
Note: The AAF core attribute AuthenticationMethod is populated from the value provided in the ph:AuthenticationMethod below.
<!--  Username/password login handler -->

<ph:LoginHandler xsi:type="ph:UsernamePassword"
                  jaasConfigurationLocation="file:///opt/shibboleth-idp/conf/login.config">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
    </ph:LoginHandler>


    • Comment out RemoteUser LoginHandler
<!-- Login Handlers -->
<!--
    <ph:LoginHandler xsi:type="ph:RemoteUser">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</ph:AuthenticationMethod>
    </ph:LoginHandler>
-->

  • Optionally, customize session duration (default 30 minutes): add the following attribute (with the duration either in minutes or using the PT notation) to the UsernamePassword login handler: (Example extends session inactivity duration to 1 hour).
authenticationDuration="PT1H0M0.000S"

  • Edit $IDP_HOME/conf/login.config and provide details for the LDAP server (uncomment and configure LdapLoginModule section). You may have to provide more attributes than what's in the default commented-out section: namely subtreeSearch="true" and serviceUser and serviceCredential with login details for a privileged account (to look up users). 
   edu.vt.middleware.ldap.jaas.LdapLoginModule required
      host="ldap.institute.domain.edu.au"
      base="ou=useraccounts,dc=institute,dc=domain,dc=edu,dc=au"
      serviceUser="<ldap user DN here>"
      serviceCredential="<ldap password here>"
      subtreeSearch="true"
      ssl="false"
      tls="false"
      userField="uid";

  • Ensure form-based auth managed by the container is enabled. Edit $SHIB_INST_HOME/src/main/webapp/WEB-INF/web.xml and uncomment the Form based login-config.
    <!-- Uncomment if you want form-based auth managed by the container -->
    <login-config> <auth-method>FORM</auth-method> <realm-name>IdP Password Authentication</realm-name> <form-login-config>
        <form-login-page>/login.jsp</form-login-page> <form-error-page>/login-error.jsp</form-error-page> </form-login-config> </login-config>


  • Rebuild and redeploy the WAR file afterwards by re-running the installer:
cd $SHIB_INST_HOME
sh ./install.sh

LDAP connections with TLS/SSL with an untrusted certificate

The connection to the LDAP server can be established either over plain LDAP (no cryptographic protection), or over LDAP with either TLS/SSL. Some LDAP servers may be configured to only accept a bind operation over an cryptographically protected channel (TLS or SSL). Some LDAP servers might however be using a self-signed certificate - or a certificate issued by a CA not trusted by the default Java trust store. In that case, it is necessary to add the CA certificate issuing the LDAP server certificate (or alternatively the LDAP server cerificate itself) to the Java keystore.

  • Get the CA certificate and save it into /opt/shibboleth-idp/credentials/local-ca.crt (picking an appropriate file name)
  • Make a copy of the default Java key store:
cp $JAVA_HOME/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/cacerts.orig

  • Import the CA certificate into the Java keystore:
keytool -import -trustcacerts -alias "Local-CA" -file /opt/shibboleth-idp/credentials/_local-ca_.crt -keystore $JAVA_HOME/jre/lib/security/cacerts

  • Change the alias to something descriptive for the local CA
  • You will get prompted for the passphrase protecting the Java keystore. The default password is "changeit" (literally).
    1. only works for TLS and not SSL
    2. only works for the LDAP resolver itself, but not for the login screen connector in login.conf

Verify the LDAP connection

To verify that the connectivity to your LDAP server works you can again point your web browser at the IdP login page https://idp.institute.domain.edu.au/idp/Authn/UserPassword.

To test the LDAP connection, attempt to login with a known username and password. If you enter a correct username and password, the IdP should respond with an error, "An error occurred while processing your request". This indicates that the authentication to the LDAP server has been successful.

If you continue to receive "
Credentials not recognized." even though you are entering a correct username and password, check the serviceUser and serviceCredential in login.config.

If the response is taking a long time before returning
"Credentials not recognized." you should check the connect options, host, ssl, tls, etc. values in login.config. You should also check that there are no firewalls blocking packets between the IdP server and the LDAP server.  You should also look in the idp-process.log file for any LDAP connection errors.


uApprove

Rule 8.4 from the AAF Federation Rules states that "Identity Providers may only release Attributes to a Service Provider, or another Identity Provider, with the permission of the End User." The AAF recommends IdPs install uApprove to provide a mechanism for users to provide their consent to the release of personal attributes.

The uApprove application will step in the first time the user logs into a service. It will ask the user for permission to release the required (and desired) attributes to the service. The user will be asked again if the set of attributes released to the service changes, or if the values previously released change. The user also has the option of giving a Global consent which gives their permission to release any attributes to any service the user accesses in the future. The Global consent can be later revoked (via the Reset-approvals feature) and can also be completely disabled in the system-wide configuration (if the institution decided their users shouldn't be allowed to give global consent).

More information about uApprove, as well as download links, can be found at http://www.switch.ch/aai/support/tools/uApprove.html

As uApprove plugs into the IdP, the version of uApprove must be matched to be compatible with the version of IdP. The most recent version of uApprove 2.4.1 is compatible with IdP 2.3.6 (the most recent stable version of shibboleth).

The following instructions are closely based on the uApprove 2.4.1 installation manual, http://www.switch.ch/aai/downloads/uApprove-manual/.

You should confirm at the uApprove website that 2.4.1 is still the most recent version.  If not, you should refer to the new version's installation manual for updated instructions.

uApprove can store the approval information in either a SQL database, or in a flat file. Storing the information in a SQL database is more scalable, and it also allows users to revoke consent already given. This guide documents installing uApprove configured to use a local MySQL database. Please refer to the uApprove installation manual for other alternatives (such as connecting to an external database).

Install uApprove

  • Download the uApprove binary distribution, unpack it into /home/shibsrc.
cd /home/shibsrc
wget http://www.switch.ch/aai/downloads/uApprove-${UAPPROVE_VERSION}.zip
unzip uApprove-${UAPPROVE_VERSION}.zip


Library Installation

Copy the libraries to the IdPs library directory:

cp $UAPPROVE_INSTALL/lib/*.jar $SHIB_INST_HOME/lib

cp $UAPPROVE_INSTALL/lib/jdbc/*.jar $SHIB_INST_HOME/lib

Provide the JDBC connector for your database to the classpath of the IdP. You might use one of the provided MySQL or HSQL JDBC connector:


cp $UAPPROVE_INSTALL/lib/jdbc/optional/#jdbc-connector#.jar $SHIB_INST_HOME/lib

Ensure that only one version of each library is present in $SHIB_INST_HOME/lib.

Configuration Template

Copy the configuration template to the IdPs configuration directory:

cp $UAPPROVE_INSTALL/manual/configuration/uApprove.properties $SHIB_HOME/conf

cp $UAPPROVE_INSTALL/manual/configuration/uApprove.xml $SHIB_HOME/conf

Webapp files


Copy of the web application files like the JSPs, CSS files and images to the IdPs webapp directory:

mkdir $SHIB_INST_HOME/src/main/webapp/uApprove

cp $UAPPROVE_INSTALL/webapp/* $SHIB_INST_HOME/src/main/webapp/uApprove

Database Preparation

Configure MySQL for a very long connection timeout. By default, MySQL closes connections after 8 hours of inactivity. This breaks connections overnight - and the database clients running on the IdP (uApprove and also SharedToken) report errors when reconnecting to the database (even when using autoReconnect=true). Edit /etc/my.cnf and add the following into the [mysqld] section:

wait_timeout=31536000 # 3600*24*365 - one year

Restart the Database after the configuration change

/etc/init.d/mysqld restart

Setup the database, the following database parameters are as a guide only.
  • Create a MySQL database (uApprove), a user (also uApprove), and grant the user full access over the database (replace DB-PASSWORD with a suitable password):
mysql -u root -p
mysql>
CREATE DATABASE uApprove;
CREATE USER 'uApprove'@'localhost' IDENTIFIED BY 'DB-PASSWORD';
GRANT INSERT, SELECT, UPDATE, DELETE ON uApprove.* TO 'uApprove'@'localhost';
ALTER DATABASE uApprove DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Create the initial table structures using the schema creation files
mysql -u root -p -D uApprove < $UAPPROVE_INSTALL/manual/storage/terms-of-use-schema.sql

mysql -u root -p -D uApprove < $UAPPROVE_INSTALL/manual/storage/attribute-release-schema.sql

Web Application Deployment Descriptor

Extend the IdP web application deployment descriptor ( $SHIB_INST_HOME/src/main/webapp/WEB-INF/web.xml):

Add $IDP_HOME$/conf/uApprove.xml to the <context-param...> area in the web.xml file.


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>$IDP_HOME$/conf/internal.xml; 
$IDP_HOME$/conf/service.xml;
 
$IDP_HOME$/conf/uApprove.xml
</param-value> 
</context-param>


Add the uApprove Filter and Servlets ( $IDP_INSTALL/src/main/webapp/WEB-INF/web.xml):

Add the following at the end of the web.xml file just prior the the closing </web-app>.

<!-- uApprove Filter and Servlets -->
<filter>
<filter-name>uApprove</filter-name>
<filter-class>ch.SWITCH.aai.uApprove.Intercepter</filter-class>
</filter>
<filter-mapping>

        <filter-name>uApprove</filter-name>            <url-pattern>/profile/Shibboleth/SSO</url-pattern>            <url-pattern>/profile/SAML1/SOAP/AttributeQuery</url-pattern>            <url-pattern>/profile/SAML1/SOAP/ArtifactResolution</url-pattern>            <url-pattern>/profile/SAML2/POST/SSO</url-pattern>            <url-pattern>/profile/SAML2/POST-SimpleSign/SSO</url-pattern>            <url-pattern>/profile/SAML2/Redirect/SSO</url-pattern>            <url-pattern>/profile/SAML2/Unsolicited/SSO</url-pattern>            <url-pattern>/Authn/UserPassword</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>uApprove - Terms Of Use</servlet-name>
<servlet-class>ch.SWITCH.aai.uApprove.tou.ToUServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>uApprove - Terms Of Use</servlet-name>
<url-pattern>/uApprove/TermsOfUse</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>uApprove - Attribute Release</servlet-name>
<servlet-class>ch.SWITCH.aai.uApprove.ar.AttributeReleaseServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>uApprove - Attribute Release</servlet-name>
 <url-pattern>/uApprove/AttributeRelease</url-pattern>
</servlet-mapping>


Custom Configuration


In $SHIB_HOME/conf/uApprove.xml change:
<context:property-placeholder location="classpath:/configuration/uApprove.properties" />
to
<context:property-placeholder location="file:$SHIB_HOME$/conf/uApprove.properties" />
Note: You must expand $SHIB_HOME$ to it's actual values, e.g. /opt/shibboleth-idp
Customize $SHIB_HOME$/conf/uApprove.properties according your database environment and required features. See inline documentation for configuration options.

Deployment


To activate uApprove the IdP must be re-deployed.


cd $IDP_INSTALL
./install.sh






Start Tomcat

  • Start MySQL, Tomcat and Apache and make them auto start:
service mysqld start
service tomcat6 start
service httpd start
chkconfig mysqld on
chkconfig tomcat6 on
chkconfig httpd on

Testing uApprove

  • uApprove now be integrated into your IdP. This can be verified by,
    • Navigate to the uApprove TermsOfUse page, https://idp.institute.domain.edu.au/idp/uApprove/TermsOfUse which should result in a page similar to the following.


This is the default Terms of Use page provided with uApprove.

If you do not receive the above page then look in the tomcal logs for an Error that might indicate what has gone wrong. It will generally be a typo in of the configuration files.

Advanced uApprove Deployment

This sections contains advanced configuration topics.

Reset Attribute Release Consent

To provide an option that allows users to clear their attribute release consent during the login flow, add a check box to $IDP_INSTALL/src/main/webapp/login.jsp. You must re-deployed the IdP for this change to take effect.

<form action="<%=request.getAttribute("actionUrl")%>" method="post">   

...

<input id="uApprove.consent-revocation" type="checkbox" name="uApprove.consent-revocation" value="true"/>
<label for="uApprove.consent-revocation">Clear my attribute release consent</label>

...

</form>

Additional Information on uApprove

Additional configuration is possible with uApprove for more details refer to the uApprove manual provided on the SWITCHaai web site.





Configure Attribute Resolver

All user attributes (except AuthenticationMethod) are retrieved, generated or defined using the Attribute Resolver.  This section will show how all of the AAF Core attributes and Recommended attributes (as described in the Attributes section of the wiki) are retrieved using the Attribute Resolver.

All attribute configuration is done in /opt/shibboleth-idp/conf/attribute-resolver.xml.

Edit the file and implement the following changes:

Link your Attribute Resolver to your LDAP server

In /opt/shibboleth-idp/conf/attribute-resolver.xml, uncomment the LDAP DataConnector element and configure it with local LDAP connection parameters to connect to your LDAP server (ldapURL, baseDN, principal, principalCredential) and also set the property java.naming.referral to "follow":

<resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory" 
    ldapURL="ldap://ldap.institution.domain.com.au" baseDN="dc=institution,dc=domain,dc=com,dc=au" principal="LDAP-BIND-DN-HERE"
    principalCredential="PASSWORD-HERE">
    <dc:FilterTemplate>
        <![CDATA[
            (cn=$requestContext.principalName)
        ]]>
    </dc:FilterTemplate>
    <dc:LDAPProperty name="java.naming.referral" value="follow"/>
</resolver:DataConnector>

Link existing attributes

mail, sn (surname), givenName and displayName

Define attributes available directly in LDAP: mail, sn, givenName and displayName: just uncomment the relevant AttributeDefinition element for each of these attributes.

Define static attributes

o (organizationName),  schacHomeOrganization, schacHomeOrganizationType

We need to define several attributes that would have a static value for each user. We do so by first defining a StaticDataConnector (close to where the commented-out example is):

Provide actual meaningful values for your institution: full organization name, home organization name (same as scope), and home Organization Type.
  • For full list of homeOrganizationType values the format is "urn:mace:terena.org:schac:homeOrganizationType:<country-code>:<string>" where,
    • The <country-code> must be a valid two-letter ISO 3166 country code identifier
    • <string> from a nationally controlled vocabulary
  • Examples values
      • urn:mace:terena.org:schac:homeOrganizationType:au:university
      • urn:mace:terena.org:schac:homeOrganizationType:au:research-institution
      • urn:mace:terena.org:schac:homeOrganizationType:au:other

DataConnector - staticAttributes

<!-- Static Connector -->
<resolver:DataConnector id="staticAttributes" xsi:type="dc:Static">
    <dc:Attribute id="o">
        <dc:Value>The EXAMPLE Institution</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="homeOrganization">
        <dc:Value>example.domain.edu.au</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="homeOrganizationType">
        <dc:Value>urn:mace:terena.org:schac:homeOrganizationType:au:EXAMPLE</dc:Value>
    </dc:Attribute>
</resolver:DataConnector>

Now define the attributes:

  • Define organizationName by uncommenting the definition and changing the connector dependency from "myLDAP" to "staticAttributes"
  • Pasting in the definitions for homeOrganization and homeOrganizationType, not provided in the default configuration:

homeOrganization

<resolver:AttributeDefinition id="homeOrganization" xsi:type="ad:Simple" sourceAttributeID="homeOrganization">
    <resolver:Dependency ref="staticAttributes" />
    <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:oid:1.3.6.1.4.1.25178.1.2.9" />
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.9" friendlyName="homeOrganization" />
</resolver:AttributeDefinition>

 

homeOrganizationType

<resolver:AttributeDefinition id="homeOrganizationType" xsi:type="ad:Simple" sourceAttributeID="homeOrganizationType">
    <resolver:Dependency ref="staticAttributes" />
    <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:oid:1.3.6.1.4.1.25178.1.2.10" />
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.10" friendlyName="homeOrganizationType" />
</resolver:AttributeDefinition>

Define scripted attributes

eduPersonAffiliation, eduPersonScopedAffiliation and cn (commonName)

The eduPersonAffiliation describe the affiliation type of the user authenticating. The typical question is: "Is this person staff or student?" The full set of values (with definitions available in the AAF Attribute Recommendation) is: faculty / student / staff / employee / member / affiliate / alum / library-walk-in. The eduPersonAffiliation attribute is multi-valued and should include all values that apply to the user.

Typically, the LDAP server will not be directly providing values for these attributes, but it would have some attributes that allow to determine at least some of the affiliation type values applying to the user - e.g. to tell whether the user is a staff member or a student.

In this case, we recommend defining the attributes using a scriptlet, synthesizing the value from the LDAP attributes available.

This would be very specific for each institution. We illustrate this in an example (based on an actual setup), where we assume the LDAP server has attributes:
  • isUnderGrad (boolean)
  • isPostGrad (boolean)
  • isStaff (boolean)
We decide to give anyone with isStaff=TRUE the "staff" affiliation, and to anyone with isUnderGrad=TRUE OR isPostGrad=TRUE the "student" affiliation. Also, anyone who is staff or student also gets the "member" affiliation.
  • We first define these attributes at the Shibboleth level, importing them from LDAP, using the following definitions. Note that as these attributes are not expected to be passed in Shibboleth assertions, the definitions don't have any AttributeEncoder elements. Otherwise, we would have to decide on attribute names / OIDs to use in the encoder definitions.

isUnderGrad, isPostGrad and isStaff

<!-- prerequisite to scripted eduPersonAffiliation -->
<resolver:AttributeDefinition id="isUnderGrad" xsi:type="ad:Simple" sourceAttributeID="isUnderGrad">
    <resolver:Dependency ref="myLDAP" />
    <!-- no encoder needed -->
</resolver:AttributeDefinition>
 
<resolver:AttributeDefinition id="isPostGrad" xsi:type="ad:Simple" sourceAttributeID="isPostGrad">
    <resolver:Dependency ref="myLDAP" />
    <!-- no encoder needed -->
</resolver:AttributeDefinition>
 
<resolver:AttributeDefinition id="isStaff" xsi:type="ad:Simple" sourceAttributeID="isStaff">
    <resolver:Dependency ref="myLDAP" />
    <!-- no encoder needed -->
</resolver:AttributeDefinition>

  • We follow by defining eduPersonAffiliation using an AttributeDefinition of type Script:
<resolver:AttributeDefinition id="eduPersonAffiliation" xsi:type="ad:Script">
    <resolver:Dependency ref="isUnderGrad" />
    <resolver:Dependency ref="isPostGrad" />
    <resolver:Dependency ref="isStaff" />
    <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" />
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" />
    <ad:Script>
    <![CDATA[
            importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);
            if (eduPersonAffiliation == null) {
                    eduPersonAffiliation = new BasicAttribute("eduPersonAffiliation");
            }
            is_UnderGrad = isUnderGrad != null && isUnderGrad.getValues().size()>0 && isUnderGrad.getValues().get(0).equals("TRUE");
            is_PostGrad = isPostGrad != null && isPostGrad.getValues().size()>0 && isPostGrad.getValues().get(0).equals("TRUE");
            is_Staff = isStaff != null && isStaff.getValues().size()>0 && isStaff.getValues().get(0).equals("TRUE");
 
            if (is_Staff) { eduPersonAffiliation.getValues().add("staff"); };
            if (is_UnderGrad || is_PostGrad ) { eduPersonAffiliation.getValues().add("student"); };
            if (is_UnderGrad || is_PostGrad || is_Staff ) { eduPersonAffiliation.getValues().add("member"); };
    ]]>
    </ad:Script>
</resolver:AttributeDefinition>

  • Finally, we define the eduPersonScopedAffiliation attribute by uncommenting the definition and:
    • setting your institution's scope, in the format scope="institution.domain.edu.au"
    • changing the dependency from LDAP to the previously defined attribute eduPersonAffiliation:
<resolver:Dependency ref="eduPersonAffiliation" />

The cn (commonName) in some directories will be the user's login name, but the AAF requires the cn to contain only the user's given name and surname separated by a space. The simplest way to achieve this is to script the cn value from the user's actual given name and surname as follows.

cn

    <resolver:AttributeDefinition xsi:type="ad:Script" id="commonName">
       <resolver:Dependency ref="givenName" />
       <resolver:Dependency ref="surname" />
       <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:cn" />
       <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.3" friendlyName="cn" />


       <ad:Script><![CDATA[
           importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);

            commonName = new BasicAttribute("commonName");

            if ((typeof givenName != "undefined" && givenName != null && givenName.getValues().size()>0) &&
                (typeof surname != "undefined" && surname != null && surname.getValues().size()>0)) {

                commonName.getValues().add(givenName.getValues().get(0) + " " + surname.getValues().get(0));
            }

            if ((typeof givenName == "undefined" || givenName == null || givenName.getValues().size()==0) &&
                (typeof surname != "undefined" && surname != null && surname.getValues().size()>0)) {
                commonName.getValues().add(" " + surname.getValues().get(0));
            }

            if ((typeof givenName != "undefined" && givenName != null && givenName.getValues().size()>0) &&
                (typeof surname == "undefined" && surname == null && surname.getValues().size()==0)) {
                commonName.getValues().add(givenName.getValues().get(0) +" ");
            }

       ]]>
       </ad:Script>
    </resolver:AttributeDefinition>


Define sharedToken

auEduPersonSharedToken

The auEduPersonSharedToken attribute is an AAF core attribute that is based on the auEduPerson schema. The shared token is not part of the standard Shibboleth installation. It requires a specific plugin to be installed together with some additional configuration. This following section describes who to install the plugin that will generated Shared Tokens for users and store the shared token in either a database or a ldap directory.

  1. Following the full sharedToken install guide, we will choose to store the SharedToken value in a MySQL database - to keep track of values issued and have a means of inserting a different value if someone asks for portability.
  • Download binary from AAF Files download site
wget http://www.aaf.edu.au/download/arcs-shibext-1.5.4.jar

The shared token value MUST be stored in either the LDAP server itself (preferred, keeps the values alongside primary identity information), or alternatively in a MySQL database (easier to get going by running a MySQL server directly on the IdP).

In this section, some instructions are specific to storing the shared token values in an LDAP server, some are specific to storing the values in a local MySQL server - please choose accordingly.

  • If storing the sharedToken value in your LDAP server, edit the conf/sharedtoken.properties inside the jar and change the following settings - the search filter should be the same as in your LDAP connector - configuring which LDAP attribute is the principal name:

Note: If your ldap uses "uid" then no change is required.

DEFAULT_IDP_HOME=/opt/shibboleth-idp
ATTRIBUTE_RESOLVER=$IDP_HOME/conf/attribute-resolver.xml
SEARCH_FILTER_SPEC=cn={0}



  • Copy the JAR into $SHIB_INST_HOME/lib and (later) rerun the Shibboleth IdP installer to rebuild the webapp WAR archive. (When rerunning the installer, accept the default install location (or specify your install location, stored also in $IDP_HOME) and answer no to the question on overwriting configuration.)
cp arcs-shibext-*.jar $SHIB_INST_HOME/lib
cd $SHIB_INST_HOME
sh ./install.sh

Configuring a MySQL database for storing sharedToken values

    • Install the driver (mysql-connector-java-5.x.y-bin.jar) into $SHIB_INST_HOME/lib and also into /opt/shibboleth-idp/lib (and rerun the Shibboleth IdP installer - now)
  • Create a MySQL user: run "mysql" as root and enter the following commands:
 
create user 'idp_admin'@'localhost' identified by 'IDP_ADMIN_PASSWORD';
 grant all privileges on idp_db.* to 'idp_admin'@'localhost';
  • Create a MySQL schema: run "mysql" as idp_admin and enter the following commands:
 mysql -u idp_admin -p

 CREATE DATABASE idp_db;
 use idp_db;

 CREATE TABLE tb_st (
 uid VARCHAR(100) NOT NULL,
 sharedToken VARCHAR(50),
 PRIMARY KEY  (uid)
 );

Defining sharedToken attribute (both LDAP and MySQL)

  • Add schema definition to attribute-resolver.xml: add urn:mace:arcs.org.au:shibboleth:2.0:resolver:dc classpath:/schema/arcs-shibext-dc.xsd to the list of schema locations at the top of the file.
  • Add connector definition to attribute-resolver.xml (sharedToken) with the following customizations:
    • idPIdentifier - your IdP entityId, sourceAttributeID: combination of attributes that is unique, non-reassignable and if possible persistent - if usernames are not reused at your institution, username is perfectly fine - so the "cn" or "uid" attribute would do
    • If using a MySQL server, enter the database connection details, with the IDP_ADMIN_PASSWORD as defined just above
    • If storing sharedToken in an LDAP server:
      • Omit the DatabaseConnection element from the below snippet
      • Change the values to storeLdap="true" and storeDatabase="false"
<!-- ==================== auEduPersonSharedToken data connector ================== -->
 
<resolver:DataConnector xsi:type="SharedToken" xmlns="urn:mace:arcs.org.au:shibboleth:2.0:resolver:dc"
                    id="sharedToken"
                    idpIdentifier="https://idp.institution.domain.edu.au/idp/shibboleth"
                    sourceAttributeID="uid"
                    storeLdap="false"
                    storeDatabase="true"
                    salt="SALT-GOES-HERE">
    <resolver:Dependency ref="myLDAP" />
 
    <DatabaseConnection jdbcDriver="com.mysql.jdbc.Driver"
                        jdbcURL="jdbc:mysql://localhost/idp_db?autoReconnect=true"
                        jdbcUserName="idp_admin"
                        jdbcPassword="IDP_ADMIN_PASSWORD"
                        primaryKeyName="uid"/>
 
</resolver:DataConnector>

  • Note: on the first install, generate a suitable salt value with:
 
openssl rand -base64 36
 
    • On subsequent installs, reuse the same value (stored somewhere carefully)
  • Note also that the SharedToken value depends on the IdP entityID - which could be picked up from the environment, but is better set in the configuration.
  • Note that the JdbcURL uses "?autoReconnect=true" - which is an extension from the original shared-token installation instructions.

  • IMPORTANT: If storing the values in an LDAP server, modify the LDAP DataConnector so that the FilterTemplate element is defined without any namespace qualifier, just with a default namespace, as in the following snippet. Make the same change for any LDAPPropertyElements. This is needed due to a known problem in the shared-token implementation.
        <FilterTemplate xmlns="urn:mace:shibboleth:2.0:resolver:dc">
            <![CDATA[
                (cn=$requestContext.principalName)
            ]]>
        </FilterTemplate>
        <LDAPProperty name="java.naming.referral" value="follow" xmlns="urn:mace:shibboleth:2.0:resolver:dc" />

  • Add attribute definition to attribute-resolver.xml (auEduPersonSharedToken)
<!-- ==================== auEduPersonSharedToken attribute definition ================== -->
<resolver:AttributeDefinition id="auEduPersonSharedToken" xsi:type="ad:Simple" sourceAttributeID="auEduPersonSharedToken">
    <resolver:Dependency ref="sharedToken" />
    <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:federation.org.au:attribute:auEduPersonSharedToken" />
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.27856.1.2.5" friendlyName="auEduPersonSharedToken" />
</resolver:AttributeDefinition>


eduPersonTargetedID


The AAF Recommends using the StoreIDDataConnector over the computedID. See https://wiki.shibboleth.net/confluence/display/SHIB2/ResolverStoredIDDataConnector for configuration details.

     1. Define the database table.
The Stored ID data connector stores its created ID in a database. You must create a database table with the following definition. This can be done in the same schema use for the auEduPersonSharedToken if you use the database for storing this values.

CREATE TABLE IF NOT EXISTS shibpid (
    localEntity TEXT NOT NULL,
    peerEntity TEXT NOT NULL,
    principalName VARCHAR(255) NOT NULL default '',
    localId VARCHAR(255) NOT NULL,
    persistentId VARCHAR(36) NOT NULL,
    peerProvidedId VARCHAR(255) default NULL,
    creationDate timestamp NOT NULL default CURRENT_TIMESTAMP
        on update CURRENT_TIMESTAMP,
    deactivationDate timestamp NULL default NULL,
    KEY persistentId (persistentId),
    KEY persistentId_2 (persistentId, deactivationDate),
    KEY localEntity (localEntity(16), peerEntity(16), localId),
    KEY localEntity_2 (localEntity(16), peerEntity(16), localId, deactivationDate)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

     2. Define the Connector
To define a new computed ID data connector, create a <DataConnector xsi:type="StoredId" xmlns="urn:mace:shibboleth:2.0:resolver:dc"> element,

    <!-- Stored targted ID connector -->
    <resolver:DataConnector xsi:type="StoredId"
        xmlns="urn:mace:shibboleth:2.0:resolver:dc" id="storedID"
        sourceAttributeID="uid"
        generatedAttributeID="storedID"
        salt="ThisIsRandomText">

        <resolver:Dependency ref="myLDAP" />

        <ApplicationManagedConnection
                jdbcDriver="DRIVER_CLASS"
                jdbcURL="DATABASE_URL"
                jdbcUserName="DATABASE_USER"
                jdbcPassword="DATABASE_USER_PASSWORD" />

    </resolver:DataConnector>


     3. Set the salt value used by the data connector.
openssl rand -base64 36

     4. Uncommenting AttributeDefinition id="eduPersonTargetedID" and modifying to use the storedID data connector.

    <resolver:AttributeDefinition xsi:type="ad:SAML2NameID" id="eduPersonTargetedID"
                                  nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" sourceAttributeID="storedID">
        <resolver:Dependency ref="storedID" />
        <resolver:AttributeEncoder xsi:type="enc:SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" />
        <resolver:AttributeEncoder xsi:type="enc:SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" />
    </resolver:AttributeDefinition>


Verify changes to attribute-resolver.xml

A number of changes have been made to the attribute-resolver.xml file. Before continuing you should verify the changes you have made by restarting the Tomcat server and checking the idp-process.log file for errors.



Joining the federation

To join your IdP to the AAF you must register it in the AAF Federation Registry. An overview of this process is provided in the Knowledge base article: How to technically join the Australian Access Federation

Register your IdP

  • Select the "Create Identity Provider" tab and follow the instructions. You need to provide various pieces of information about your identity providers including
    • The Organisation to which the IdP belongs
    • The host your IdP is running on
    • The scope for which the IdP can assert attributes
    • The public key (/opt/shibboleth-idp/credentials/idp.crt)
    • The attributes supported by the IdP
  • After you submit your IdP to be registered you will receive an an email stating the following:
AAF banner, Federation Registry

This email confirms that the Identity Provider which you've registered with the Australian Access Federation has been 
received but is not yet ready for use. 

Your Identity Provider will now move through a workflow process that requires approvals by AAF staff and potentially your organisation. 

Please allow up to 48 hours for this to occur. Upon completion of the process you will receive another email confirming activation of your Identity Provider and further instructions for completing your deployment. 

Important Details

Internal ID:9,999
Entity ID:https://example.uni.edu.au/idp/shibboleth
Display Name:Example IdP
Description:For demonstration purposes
Owner:Example


Please contact the AAF support desk if the details are incorrect or if you have not received a response within 48 hours.

  • When your IdP has been approved you will receive a followup email. 
  • READ this email carefully and follow all steps. There are important actions you must perform after your IdP is accepted.
AAF banner, Federation Registry

The Identity Provider which you've registered with the Australian Access Federation has been
accepted. You can now complete final setup tasks. 

Please keep this email for future reference. 

Your unique code for administrative access (required in step 4 below)
a69ff70478


Important Details

Internal ID:9,888
Entity ID:https://example.uni.aaf.edu.au/idp/shibboleth
Display Name:Example IdP
Description:For demonstration purposes
Owner:Example

Next Steps

1. Validate EntityID 
Your Identity Provider must use a unique EntityID to identify it to the rest of the federation and this value must match both your local configuration and Federation Registry. 

Please verify your Identity Provider configuration uses the EntityID shown above under 'Important Details'. If it doesn't, you can't go any further. Contact the AAF support desk for help in resolving this fault. 

2. Ensure Time Sync 
The server which runs your Identity Provider must be synchronized to a suitable NTP source and remain in sync at all times. 

Users from an Identity Provider which is out of time sync will fail to login to remote services.

3. Configure Attribute Release 
Configure your Identity Provider to correctly release attributes to the federation as documented in Automating Attribute Release. When asked for the value of [YOUR UNIQUE URL] please provide https://manager.test.aaf.edu.au/federationregistry/attributefilter/generate/9999. 


Ensure at least an hour has passed since you received this email before continuing. This allows distribution of metadata including details of your new Identity Provider to circulate to the federation. 


4. Claim your administrative access 
Navigate to your Identity Provider's management page and access the administrator tab. Enter the unique code provided below in the box labelled CODE. This can only be used once. Once applied you can then provide access to other administrators on your team. 

Your unique code for administrative access in Federation Registry:
a69ff70478


5. Double check all information associated with your Identity Provider that is stored in Federation Registry making changes if you note any inaccuracies. 

6. Ensure you've applied appropriate branding to all of your Identity Providers pages including the login screen and all error pages. 

Branding should be consistent with that used on your organisation's website. 

7. Test your new Identity Provider with other services connected to the federation, especially those which are of importance to your organisation. 

8. You're all done! Welcome to the Australian Access Federation.

Logging into the Federation Registry

After you receive the email confirming the successful activation of your IdP several changes to the federation will occur within 60 minutes.
  • Your IdP will be listed on in the Where are You From (WAYF) 
  • Your IdP's metadata will be included in the federation metadata
You must wait until both of these events have completed before attempting to login to the AAF Federation Registry for the first time.
Note: You may have to restart Tomcat to get your IdP to load the latest Metadata with your IdP included as your IdP may take up to 2 hours to do so automatically.

You are now ready to login to the Federation Registry for the first time. Navigate to the Federation Registry and select Login. This will take you to the WAYF, select you IdP and login. If all went well you should be logged into the Federation Registry.

The most common issue that occurs when logging in for the first time is missing required attributes. The Federation Registry will tell you which attributes where missing.

Becoming an Identity Provider Administrator 

When your Identity Provider was approved you will have received an email "Your Identity Provider has been accepted. Important information and next steps."In this email is a unique code that will enable you to become an administrator.
This email will also describe how to use this code.
  • Click on this link and login to the Federation Registry with the account you wish to use as Administrator.
As Identity Provider administrator you will be able to perform the following functions on your Identity Provider.
  • Add and modify the lists of contacts. See the list above for available contact roles.
  • Add and modify Identity provider administrators
  • Modify Identity Provider details.
Warning: Changing details of your Identity Provider can result in changes to the federation metadata which may impact on the operation of your IdP.

Registering SAML1.x Endpoints

Some Identity provides will need to work with older SAML1 (Shibboleth 1.3.x) service providers. By default the Federation Registry does not create the SAML1.x endpoints. Log a job with support@aaf.edu.au to request the addition of SAML 1.x endpoint. For more details set the Knowledge base article: SAML 1.x endpoints and Federation Registry

Advanced IdP Configuration

Enabling automatic reload

To automatically reload a service configuration (such as the attribute-filter.xml file), one has to add two attributes to the service definition: configurationResourcePollingFrequency (in milliseconds) and configurationResourcePollingRetryAttempts.

  • The change done to /opt/shibboleth-idp/conf/service.xml is thus:
     <srv:Service id="shibboleth.AttributeResolver"
              configurationResourcePollingFrequency="PT5.000S" 
     configurationResourcePollingRetryAttempts="10"
              xsi:type="attribute-resolver:ShibbolethAttributeResolver">
         <srv:ConfigurationResource file="/opt/shibboleth-idp/conf/attribute-resolver.xml" xsi:type="resource:FilesystemResource" />
     </srv:Service>

     <srv:Service id="shibboleth.AttributeFilterEngine"
              configurationResourcePollingFrequency="PT5.000S" 
              configurationResourcePollingRetryAttempts="10"
              xsi:type="attribute-afp:ShibbolethAttributeFilteringEngine">
         <srv:ConfigurationResource file="/opt/shibboleth-idp/conf/attribute-filter.xml" xsi:type="resource:FilesystemResource" />
     </srv:Service>


and

     <srv:Service id="shibboleth.RelyingPartyConfigurationManager"
          configurationResourcePollingFrequency="PT5.000S" 
          configurationResourcePollingRetryAttempts="10"
          xsi:type="relyingParty:SAMLMDRelyingPartyConfigurationManager"
          depends-on="shibboleth.SAML1AttributeAuthority shibboleth.SAML2AttributeAuthority">
        <srv:ConfigurationResource file="/opt/shibboleth-idp/conf/relying-party.xml" xsi:type="resource:FilesystemResource" />
     </srv:Service>

     <srv:Service id="shibboleth.HandlerManager"
          configurationResourcePollingFrequency="PT5.000S" 
          configurationResourcePollingRetryAttempts="10" 
          depends-on="shibboleth.RelyingPartyConfigurationManager"
          xsi:type="profile:IdPProfileHandlerManager">
        <srv:ConfigurationResource file="/opt/shibboleth-idp/conf/handler.xml" xsi:type="resource:FilesystemResource" />
     </srv:Service>




Customization and Branding

Customizing and branding IdP login screen

In a default install, the IdP login screen is displaying the Shibboleth project logo, a default prompt for username and password, and text saying that this screen should be customized. To establish trust with users, this page should at the very least have the proper institution logo and name and the instructions to customize the page should be removed. Each institution may also wish to customize the graphics to match the style of their login pages. The instructions below show how to change the style of the login screen to match the style of the uApprove screen.

The instructions add a bit of functional logic into the login page - instead of displaying just the entityId of the login page, displaying the full name of the service as configured in the metadata (if available), followed by the hostname of the service.

All of the customization has to be done in the Shibboleth installation directory ($SHIB_INST_HOME, in particular to src/main/webapp/login.jsp) - and after any changes, it is necessary to re-deploy the IdP web application (re-run ./install.sh and restart Tomcat).

For reference, see the Shibboleth Login Page customization instructions at https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAuthUserPassLoginPage

To customize the login screen with your institutional branding:
  • Copy your institution's logo into $SHIB_INST_HOME/src/main/webapp/images/inst_logo.gif (change the filename here and later on as suitable)
  • Edit $SHIB_INST_HOME/src/main/webapp/login.jsp and:
  • Set head->title to "Institution-name Login" (with your institution name)
  • Do the same for the <h1> element (and for formatting purposes, demote this to an <h2> element)
  • Delete the paragraph saying this is a sample login page
  • Change link to the logo image from /images/logo.jpg (Shibboleth logo) to /images/inst_logo.gif (your institution's logo)
  • Nice framing: wrap the whole HTML body in the following DIV element - applying the same style as what the uApprove screen is using:
<div style="width: 650px; margin-left:auto; margin-right:auto; border-style: solid; border-color: #00247D; border-width: 1px; padding: 10px; text-align: left; ">

  • If suitable, change the phrasing on the login prompt and change the formatting from "<h2>" to just plain paragraphs ("<p>"):
<p>You are accessing <strong><%= loginContext.getRelyingPartyId() %></strong></p>
<p>Please login with your AUT username and password.</p>

As of Shibboleth IdP 2.3.0, the default login page now displays not just the service entityID but also the service DisplayName and Description if available in the metadata. This is facilitated through tags from the idpui tag library, documented at the IdPAuthUserPassLoginPage. However, some of the features used by the default login page (like the service logo) are not currently  available in the metadata produced by the Federation Registry, so we still recommend to customize this page heavily: remove the left/right frame arrangement, and also display the service hostname (extracted from the entityID).

  • Add the following code snippet into login.jsp to construct the hostname:
<!-- Local extension: display the name of the service -->
<%!
String GetHostnameByURI(String uri)
{
  /* reusing uApprove's Controller.getResourceHost code */
    int i1 = uri.indexOf("//");
    int i2 = uri.indexOf("/", i1+2);
    // LOG.debug("uri received = \"" + uri + "\"");

    // return just the sp.example.org component out of https://sp.example.org/shibboleth
    if ( i2 >= 0 )
       uri = uri.substring(i1 + 2, i2);
    else if ( i1 >= 0 )
       uri = uri.substring(i1 + 2);

    // return just the sp.example.org component out of urn:mace:federation.org:sp.example.org
    if (uri.indexOf(':')>=0) {
        uri = uri.substring(uri.lastIndexOf(':')+1);
    }
    //LOG.debug("hostname extracted = \"" + uri + "\"");

  return uri;
}
%>

<!-- getting relying party full name -->
<%@ page import="edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager" %>
<%@ page import="edu.internet2.middleware.shibboleth.idp.util.HttpServletHelper" %>
<%@ page import="org.opensaml.util.storage.StorageService" %>
<%@ page import="edu.internet2.middleware.shibboleth.idp.authn.LoginContext" %>
<%@ page import="org.opensaml.saml2.metadata.EntityDescriptor" %>
<%
   StorageService storageService = HttpServletHelper.getStorageService(application);
   LoginContext loginContext = HttpServletHelper.getLoginContext(storageService,application, request);
   String hostname = loginContext.getRelyingPartyId();
   try {
       hostname = GetHostnameByURI(loginContext.getRelyingPartyId());
   } catch (Exception e) {
       /* Intentionally ignored:
        * Could not get detailed service name, will display basic name only */
   };
%>

Note: this snippet uses code from https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAuthUserPassLoginPage as well as code developed for the AAF.
  • Further edits to login.jsp:
    • Comment out the <div class="rightpane"> section with the right panel.
    • Comment out the opening and closing div tags for loginbox, leftpane and content
    • Replace the prompt "The web site described to the right has asked you to log in..." with:
          
<p>You are accessing service <strong><idpui:serviceName/> at <%= hostname %></strong><br>
           <em><idpui:serviceDescription/></em></p>
           <p>This site has asked you to log in and you have chosen <strong>YOUR-INSTITUTION</strong> as your home institution.<br>
           Please login with your YOUR-INSTITUTION username and password.</p></p>
  • Finally, re-deploy the IdP with:
cd $SHIB_INST_HOME
./install.sh
service $TOMCAT_NAME restart


Customizing and branding uApprove

The uApprove web application by default displays the SWITCH AAI branding. To customize this for the local institution (display the institution logo), one has to edit the header.jsp template in the uApprove web application installation tree and rebuild the web application. Note also that the explanation message given to the user (for why the user is visiting this application) can be customized in /opt/uApprove/viewer-$UAPPROVE_VERSION/webapp/WEB-INF/classes/attributes_en.properties.

  • Backup the original header.jsp file:
cp /opt/shib-src/uApprove/viewer-$UAPPROVE_VERSION/webapp/header.jsp /opt/uApprove/viewer-$UAPPROVE_VERSION/webapp/header.jsp.orig

  • Copy your institiution logo into /opt/shib-src/uApprove/viewer-$UAPPROVE_VERSION/webapp/images/inst_logo.gif (adjust filename as suitable)
  • Edit /opt/uApprove/viewer-$UAPPROVE_VERSION/webapp/header.jsp
    • Replace link to SWITCH AAI logo (images/switch-aai.gif) with images/inst_logo.gif
    • Delete the AAI specific links just below that
  • Rebuild the uApprove web application:
cd /opt/shib-src/uApprove/viewer-$UAPPROVE_VERSION/
ant deploy -Duapprove.deployment=/opt/uApprove/war

  • Restart tomcat:
service $TOMCAT_NAME restart

Friendly attribute names

By default, uApprove would be representing attributes by their local alias - which may not provide the best possible user experience. Names like "eduPersonPrincipalName" look quite cryptic to an ordinary user. The metadata syntax allows to provide friendly names (even locale-specific multiple names) in the attribute-resolver.xml file, and uApprove will pick the attribute names from there.

The syntax for specifying the attribute names is:

<resolver:AttributeDefinition xsi:type="ad:Simple" id="email" sourceAttributeID="mail">
    <resolver:Dependency ref="myLDAP" />
    <resolver:DisplayName xml:lang="en">Email address</resolver:DisplayName>
    <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mail" />
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" />
</resolver:AttributeDefinition>

Add the following attribute descriptions for the respective attributes into attribute-resolver.xml, right between the Dependency and AttributeEncoder elements:

uid:                           <resolver:DisplayName xml:lang="en">Local user ID</resolver:DisplayName>
email:                         <resolver:DisplayName xml:lang="en">Email address</resolver:DisplayName>
commonName:                    <resolver:DisplayName xml:lang="en">Common name</resolver:DisplayName>
surname:                       <resolver:DisplayName xml:lang="en">Surname</resolver:DisplayName>
givenName:                <resolver:DisplayName xml:lang="en">Given name</resolver:DisplayName>
eduPersonPrincipalName:        <resolver:DisplayName xml:lang="en">Global username (EPPN)</resolver:DisplayName>
displayName:                <resolver:DisplayName xml:lang="en">Display name</resolver:DisplayName>
organizationName:              <resolver:DisplayName xml:lang="en">Institution name</resolver:DisplayName>
homeOrganization:              <resolver:DisplayName xml:lang="en">Institution domain</resolver:DisplayName>
homeOrganizationType:          <resolver:DisplayName xml:lang="en">Institution type</resolver:DisplayName>
eduPersonAffiliation:          <resolver:DisplayName xml:lang="en">Affiliation type</resolver:DisplayName>
eduPersonScopedAffiliation:    <resolver:DisplayName xml:lang="en">Affiliation type (with institution)</resolver:DisplayName>
eduPersonEntitlement:          <resolver:DisplayName xml:lang="en">Entitlements</resolver:DisplayName>
eduPersonAssurance:            <resolver:DisplayName xml:lang="en">Identity assurance level</resolver:DisplayName>
auEduPersonSharedToken:        <resolver:DisplayName xml:lang="en">Shared token</resolver:DisplayName>
auEduPersonAffiliation         <resolver:DisplayName xml:lang="en">Affiliation type (Australian extensions)</resolver:DisplayName>


Testing

The best way to test an IdP is to try to log into a Service Provider in the federation - and the most convenient way for that is to access an attribute reflector - a page that displays all of the attributes received in the Shibboleth session. The AAF is running an attribute reflector in both AAF and AAF-TEST. Both reflectors are running on the VHO (Virtual Home Organization) server and are requesting all attributes available in the federation - hence, they work very well for testing all the attributes released by your IdP.

The attribute reflector URLs are:
An alternative tool for testing IdP is the Attribute Authority Command Line Interface client - aacli.sh. For a given user TEST_USERNAME, invoke the tool with:

$SHIB_HOME/bin/aacli.sh --principal $TEST_USERNAME --requester https://vho.aaf.edu.au/shibboleth

  • The tool output is the whole set of attributes that would be released for this user to the given application (the AAF VHO in this case). If testing for another service, pass the entityId of the service in the --requester option.
Note that the tool may fail with: ClassNotFoundException: javax.servlet.ServletRequest. To remedy this, link the Tomcat servlet.jar library into $SHIB_HOME/lib (needs to be re-done after each rebuild of the Shibboleth IdP):
ln -s /usr/share/java/servlet.jar $SHIB_HOME/lib/

Summary

The installation of an Identity Provider into the Australian Access Federation is not a difficult task, but, given the large number of steps currently involved, there is a lot of room for error. Debugging some of these errors can be time consuming. We recommend that you follow this guide from start to finish and ensure all test points throughout are successfully completed before moving on.

The AAF strongly recommends that you deploy an Identity provider into the AAF Test Federation first to become familiar with the software and its configuration. Further we recommend that you maintain your Test IdP using it for upgrade testing and making it available as a test platform for service providers deploying services on behalf of your organisation.

Finally, the AAF team is here to help. If you have any issues with regards to your IdP deployment, please contact us at support@aaf.edu.au, or search for solutions at the AAF Knowledge base.