The University of Queensland Homepage
School of ITEE ITEE Main Website

 IdP setup for the AAF

This page is a lame HTML conversion of a private wiki entry. I will do better reformatting it Real Soon Now (why oh why did I let them talk me into doing it as a wiki entry??)

The Wiki source text


This page will assist in setting up and configuring a "dummy" '''Shibboleth Identity Provider''' (IdP) which emulates the operation of a typical member of the '''Australian Authentication Federation''' (AAF), together with one or more '''Service Providers''' (SP) to operate with it. The SP and IdP exist in a peer-to-peer relationship with each having explicit knowledge of the other through the configuration files. As a typical development machine will be inside a firewall, establishing a connection with an external IdP is somewhere between difficult to impossible, hence the need for an AAF-like service that can be totally inside the firewall, but will provide a realistic environment for development and testing. For the UQ eResearch group, a fully functional setup has been configured to run on the g709-0157.itee.uq.edu.au host. 

'''''This document does not replace the referenced on-line setup guides.'''''

It is intended simply to fill in the gaps and address incorrect or misleading information found by the author while following the guides. It also adds some explanation of how the various configuration items relate to each other—another item rather obscure in the on-line guides—under the theory that a degree of understanding of what the various XML elements are doing is an aid to problem solving.

Rather than clutter the example code with place holders for installation-specific values, I have used snippits from an actual installation. The following URLs are specific to this setup and must be changed as required:

* http://g909-0157.itee.uq.edu.au is the machine hosting the IdP
* http://redactor.itee.uq.edu.au  is the machine hosting the SP
* [["ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au"]] is the LDAP tree path to user identities.



==Prerequisites==
The IdP requires:
* Apache
* Tomcat
* Shibboleth
* The Internet2 IdP application (Java webapp)
* LDAP (optional, but required to really emulate AAF attributes)
* mySQL (optional for caching persistent ID values. IdP will regenerate as needed if not present)

No versions are given as it has been found that using the "latest" is a good plan. The only exception may be Shibboleth itself as the installation RPM must be built from source RPMs unless you are running Centos 5, or SUSE. Even then it may be best to build the RPMs to ensure you have all the required dependencies are available and at the required revision level.

Basic setup information is reasonably well covered by 
* http://spaces.internet2.edu/display/SHIB2/Home and 
* http://spaces.internet2.edu/display/SHIB2/IdPInstall. 

This page will not repeat those instructions except where clarification is necessary.

==Basic Operation==
The IdP is a Java web service that requires a Tomcat container. The Apache daemon (''httpd'') front-ends Tomcat and interacts with the Shibboleth daemon (''shibd'') via the mod-shib.so library to perform Single Sign On (SSO) and inject an authenticated user's attributes as headers in the HTTP response that will (eventually) travel back to the application that requested the SSO operation via a Shibboleth Service Provider (SP). IdP's and SP's exist in a peer-to-peer relationship (the Shibboleth documentation calls them ''Relying Parties'' as they rely on each other).  Explicit metadata relating to an IdP must be copied to the shibd configuration file on the SP. Similarly, the host identity of each SP must be configured into the shibd configuration of the IdP. Additionally, explicit knowledge of a SP ''may'' be entered into the ''shibd'' and IdP filter configuration files.

The ''shibd'' configuration file (default location <code>/etc/shibboleth/shibboleth2.xml</code>) contains a reference to the URL of the IdP webapp that is run by Tomcat and front-ended by Apache so it can be accessed through ports 80, 443, and 8443. The IdP webapp config specifies where user data are located. This may be a flat file, LDAP, or an RDBMS. Once authenticated, user attribute data are extracted, filtered, encoded using Security Assertion Markup Language (SAML2), and sent to the SP ''shibd'' where SAML2 OID attributes are mapped to local attribute identifiers and optionally filtered again before setting the name value pairs into the HTTP response headers for return to the requesting service. 

This may appear confusing at first as the attribute names known and set in the LDAP schemas (for example) are mapped to different names by the default ''shibd'' configuration files! For example, the IdP webapp may be configured to generate a universally unique user attribute named ''eduPersonTargettedID'' using a hash of the URLs for the IdP, requesting SP, and the authenticated users login name (the latter is never exposed for very good security reasons). However, the default ''attribute-map.xml'' file installed with Shibboleth maps this name to an alias of ''persistent-id'' and that is how it will appear in the HTTP header sent to the client service. 

The opportunity for initial confusion is considerable, so when things are not working as expected, set ''shibd'' logging to DEBUG at both ends, and follow through the chain in the logs at both ends to see if the attribute being extracted, and if so, where it got filtered away. The chain begins with the <code>$IDP_HOME/log/idp-process.log</code> at the IdP host, then to the IdP ''shibd'' in <code>/var/log/shibboleth/shibd.log</code> and ultimately to the SP host in <code>/var/log/shibboleth/shibd.log</code>. Examine each and modify the appropriate attribute map or filter file until it is passed/encoded. DEBUG level logging is quite verbose, so be sure to set it back to INFO when the problem is solved to prevent excessive log file growth.

==Configuration==
Setup is done by editing .XML files in <code>$SHIB_HOME</code> (default <code>/etc/shibboleth</code>) and <code>$IDP_HOME/config</code> (default <code>/usr/local/idp</code>). 

In addition to those attributes for which definitions already exist in the standard configuration, we will undertake the task of providing the following attributes to all relying parties as an illustration of the various ways data can be collected and associated with user attributes:

{| class="wikitable"

! Attribute Name !! Name in HTTP header !! Description
|-
| locality
| l
| A static attribute set to '''Brisbane'''.
|-
| stateProvince
| st
| Another static attribute common to all users set to '''Queensland'''.
|-
| displayName
| (same)
| A composite attribute formed from the LDAP ''givenName'' and ''sn'' (surname) attributes.
|-
| auEduPersonAffiliation 
| (same)
| This is an optional attribute that will be loaded from LDAP which has a finer granularity than eduPersonAffiliation (also fetched from LDAP).
|-
| eduPersonTargetedID
| persistent-id
| This attribute is useful to applications that need to perform local authorization based on a unique user "key" and although a ''mandatory'' AAF attribute, is not part of the standard, default, IdP/Shibboleth distribution configuration. We will also see how this computed value can be stored in a RDBMS for quick lookup.
|}

===Apache===
This LDAP-specific config information for Apache is hard to locate and confusing within the twisty maze of http://spaces.internet2.edu documentation pages. We need a &lt;Location&gt; entry in the Apache config that securely directs requests http and https to the IdP servlet. This could be placed in <code>/etc/http/httpd.conf</code> but is probably better placed in <code>/etc/http/conf.d/ssl.conf</code> (another option would be <code>/etc/http/conf.d/shibd.conf</code> but that might be too confusing as it is not really related directly to shibd). In it, we must tell Apache the servlet path and some parameters:

 <source lang="apache">

 <Location /idp/Authn/UsernamePassword>
    AuthType LDAP
    require valid-user
 </Location>
 </source>

Alternatively, if we were doing file-based authentication, the entry would be as follows nominating the path to the flat file holding users and encrypted passwords. This may be useful as an interim setup to confirm IdP/SP operation before adding the complexity of LDAP which is the easiest option for supplying per-user attribute values.

 <source lang="apache">
 <Location /idp/Authn/RemoteUser>

    AuthType Basic
    AuthName "eResearch Development Identity Provider"
    AuthUserFile /usr/local/idp/credentials/user.db
    require valid-user
 </Location>
</source>

===Tomcat===
The Tomcat configuration will need configuring so the IdP can use the Java Authentication and Authorization Service (JAAS) to talk with LDAP. This is done by adding a new Relam to the <code>$CATALINA_HOME/config/service.xml</code> file:

 <source lang="xml">

  <Service name="Catalina">
    ...
    <connector  port="8443"
                scheme="https"
                secure="true"

                clientAuth="true"
                sslProtocol="TLS"
                sslImplementation="edu.internet2.middleware.shibboleth.tomcat.DelegateToApplicationJSSEImplementation" />

    <Connector port="8009"

               enableLookups="false"
               redirectPort="8443"
               protocol="AJP/1.3"
               request.tomcatAuthentication="false"
               address="g709-0157.itee.uq.edu.au" />

    ...
    <Engine name="Catalina" defaultHost="localhost">
      ...
      <!-- added by RC (see also ./jaas.conf file) -->
      <Realm className="org.apache.catalina.realm.JAASRealm"
             appName="Tomcat"

             userClassName="edu.vt.middleware.ldap.jaas.LdapPrincipal"
             roleClassName="edu.vt.middleware.ldap.jaas.LdapRole" />
    </Engine>
  </Service>   
 </source>

We must now create a <code>$CATALINA_HOME/config/jaas.conf</code> with an entry matching the ''appName'' attribute above:

 <source lang="apache">
 Tomcat {
   edu.vt.middleware.ldap.jaas.LdapLoginModule required
   host="g709-0157.itee.uq.edu.au"
   base="ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au"

   port="389"
   serviceUser="Manager@maenad.itee.uq.edu.au"
   serviceCredential="secret"
   userField="uid"
   userRoleAttribute="objectClass"

   subtreeSearch="true";
 };
 </source>

===LDAP===
Following a standard openLDAP install, we need to add the schemas for <code>auEduPerson</code> and <code>eduPerson</code> which will be needed by some user attributes (note that <code>auEduPerson</code> is a finer grained attribute than ''eduPersonAffiliation'' and may not be applicable to every user in the directory).
For full details on configuring LDAP for use with the IdP, see:
* http://maenad.itee.uq.edu.au/wiki/LDAP

===IdP===
Configuration guides for the IdP are located at 
* https://manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+Installation
* https://manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+2.1+on+Redhat 
* and "children" pages of those pages.

'''''NOTE with Caution!''''' All AAF doco pages have errors, omissions, and missing vital information. The AAF (Terry Smith) is aware and acknowledges this. Another set of instructions that are less flawed, but also less AAF specific that may be useful can be found at:

* https://www.switch.ch/aai/docs/shibboleth/SWITCH/2.1/idp/install-idp-2.1-debian.html#shibboleth-idp

As stated, it is best to get the '''''latest''''' IdP builder from http://shibboleth.internet2.edu/downloads/shibboleth/idp/latest/ selecting the zip file at the end of that path. At the time of writing, it was <code>shibboleth-identityprovider-2.1.5-bin.zip</code>.

After unzipping into a user directory, you wil run an Ant script that asks some questions, then configures the IdP webapp war file, creates a directory tree (you specify where, but creating it will probably need root access) and copies the war, default configuration files, and other files to it. The answers you gave are stored to disc so you can re-run the process to regenerate the war file without trashing the config file which you will have customized. It's a good idea to set up a job which backs up your IdP conf files though. You can customize things like the login jsp page by editing it in the unzipped project (follow the <code>src</code> tree) and regenerating the war file.

The IdP should periodically check its config file timestamps and reload if required, but I suggest you restart Tomcat after making any changes to the configuration. It is not necessary to restart Apache, nor ''shibd'' unless changes were made to the Shibboleth configuration, filter, or map files. These too refresh every five minutes or so, but a restart is quicker. The order of a multy-restart is not important.

====handler.xml====
The IdP login handlers are specified in the <code>$IDP_HOME/conf/handler.xml</code> file. By default, the file will make the servlet use Apache mediated username/password lookup from a flat file. To disable this, the "RemoteUser" handler must be deleted or commented out and the UserPassword handler un-commented. But the default file is missing a property from this element! The actual entry is shown below:

 <source lang="xml">

    <LoginHandler xsi:type="UsernamePassword"
                  authenticationServletURL="Authn/UserPassword"
                  jaasConfigurationLocation="file:///usr/local/idp/conf/login.config">
        <AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthenticationMethod>

    </LoginHandler>
 </source>

Authentication will now be performed using the <code>$CATALINA_HOME/webapps/idp/login.jsp</code> page. If you want to change this page, edit it in the <code>src/</code> tree of the unpacked IdP zip, then regenerate the war file using the provided Ant script. The answers you gave during the initial build are conveniently recorded and become the new defaults&mdash;just be sure to answer '''"no"''' to the question about overwriting existing files unless you want all your IdP config files trashed! The process will then just reconfigure and regenerate the web archive into <code>$IDP_HOME/war</code>. Copy the war file to <code>$CATALINA_HOME/webapps</code> and restart Tomcat.

====login.conf====
The login handler defined in the previous entry specifies use of the Java Authentication and Authorization Service (JAAS) to talk with LDAP and nominates a config file path to <code>$LDAP_HOME/conf/login.conf</code>. This must provide the details details specific to our LDAP directory setup. In it, we set the LDAP host URL details (the port used here is the default and could have been omitted). It also specifies the base Distinguishing Name (dn) for locating the User login names and the LDAP attribute name for the user name [uid]. Other parameters could be included to supply the LDAP admin user credentials as illustrated in the AAF docs, but for read-only access, we don't need these and it's good policy not to expose more than you have to in unencrypted files.

 <source lang="apache">

 ShibUserPassAuth {
   edu.vt.middleware.ldap.jaas.LdapLoginModule required
      host="g709-0157.itee.uq.edu.au"
      port="389"
      ssl="true"
      base="ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au"
      userField="uid";
 };
 </source>

====relying-party.xml====
Then ensure that the SP is registered with the IdP by creating a MetadataProvider element for the SP host and associate with it a location to store the SP's metadata in a backing file in the <code>$IDP_HOME/conf/relying-party.xml</code> file. Each metadata provider must have a unique "id" value but this can be any unique id name and is not referenced by anything else.

 <source lang="xml">
    <MetadataProvider id="URLMD" xsi:type="FileBackedHTTPMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata"

                      metadataURL="https://redactor.itee.uq.edu.au/Shibboleth.sso/Metadata"
                      backingFile="/usr/local/idp/metadata/redactor.xml" />
 </source>

Note that the metadata URL specifies HTTPS protocol. This requires a genuine, signed certificate for the SP with a trust chain trusted by the IdP. You can't use a self-signed certificate because the IdP will reject it, not load the metadata, and the SP will not be configured. If you don't have a real one and must self-sign, use HTTP as the metadata transfer protocol. But fetching the SP metadata by HTTP results in the protol for ALL SP/IdP exchanges being made by HTTP. As this means Shibboleth exchanges in both directions will be unencrypted, it should be obvious that this is not a configuration you'd want to deploy for real!!

====attribute-resolver.xml====
Attribute definitions and the ways data are collected for them are specified in the <code>$IDP_HOME/conf/attribute-resolver.xml</code> file. 

The static attributes that will be set for all users are easy. We just need a DataConnector to provide the name value pairs which are then associated with the appropriate AttributeDefinition entries. Notice that the AttributeDefinitions reference the DataConnector's id as a dependency reference, with the sourceAttributeID attribute matching the value of the id attribute of one of the Attribute elementx contained in the static DataConnector. We could store the ''l'' and ''st'' values in LDAP and set the Dependency ref to ''myLDAP'', but that seems inefficient when all our users are co-located. Besides, it lets us play with static attribute values.

 <source lang="xml">

    <resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
              id="locality" 
              sourceAttributeID="l">
        <resolver:Dependency ref="staticAttributes" />

        <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
            name="urn:mace:dir:attribute-def:l" />
        <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"

            name="urn:oid:2.5.4.7" friendlyName="l" />
    </resolver:AttributeDefinition>
    
    <resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"

              id="stateProvince" 
              sourceAttributeID="st">
        <resolver:Dependency ref="staticAttributes" />
        <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"

              name="urn:mace:dir:attribute-def:st" />
        <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
              name="urn:oid:2.5.4.8" friendlyName="st" />

    </resolver:AttributeDefinition>
    ...
    <resolver:DataConnector xsi:type="Static" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
              id="staticAttributes" >
        <Attribute id="l">

            <Value>Brisbane</Value>
        </Attribute>
        <Attribute id="st">
            <Value>Queensland</Value>

        </Attribute>
    </resolver:DataConnector>
 </source>

The ''displayName'' AttributeDefinition is a little more complex, being formed from two space separated attributes sourced from LDAP. We do this with a Velocity Template, although this time we do not require a DataConnector as the source attributes are populated from the LDAP DataConnector:

 <source lang="xml">
    <resolver:AttributeDefinition xsi:type="Template" xmlns="urn:mace:shibboleth:2.0:resolver:ad"

              id="displayName" >
       <resolver:Dependency ref="myLDAP" />
       <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"

                 name="urn:mace:dir:attribute-def:displayName" />
       <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                 name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" />

       <Template><![CDATA[${givenName} ${sn}]]></Template>
       <SourceAttribute>givenName</SourceAttribute>
       <SourceAttribute>sn</SourceAttribute>
    </resolver:AttributeDefinition>

 </source>

Lastly, we add a definition for the ''auEduPersonAffiliation'' attribute: 

 <source lang="xml">
    <resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" 
              id="auEduPersonAffiliation" 
              sourceAttributeID="auEduPersonAffiliation">

        <resolver:Dependency ref="myLDAP" />
        <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                  name="urn:mace:dir:attribute-def:auEduPersonAffiliation" />

        <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                  name="urn:oid:1.3.6.1.4.1.27856.1.2.1" friendlyName="auEduPersonAffiliation" />
    </resolver:AttributeDefinition>

 </source>

As before, this defines the attribute, where it can be found in the LDAP service, and two encodings for it. If you have not already, make sure that the "myLDAP" DataConnector element has been configured in the <code>attribute-resolver.xml</code> file. The example below specifies the LDAP URL using the default port to connect to the service [ldapURL], the base Distinguishing Name for searching [baseDN], and the user login name template [principal]. The name entered interactively by the user will be substituted into the ''binduser'' field for the LDAP search.

 <source lang="xml">
   <resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"

             id="myLDAP" 
             searchScope="SUBTREE"
             ldapURL="ldap://g709-0157.itee.uq.edu.au:389"
             baseDN="ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au"
             principal="uid=binduser,ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au" >

        <FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </FilterTemplate>
    </resolver:DataConnector>
 </source>

=====Persistent ID's=====
The ''eduPersonTargettedID'' attribute provides a universally unique identity string but requires some configuration to make it work. It is generated by the IdP using the IdP host URL, the SP host URL and a the user's uid string, all hashed. Optionally, it can be cached in a mySQL (or Oracle) RDMBS table, however the config for generating on the fly, and fetching from an RDBMS are significantly different, as shown below.

======Computed ID======
Computed ID's are generated as required by a special Data Connector entry with the xsi:type ''ComputedId'' that is placed in the '''''attribute-resolver.xml''''' config file. The file provided with the distribution IdP has a commented out entry for this that can be just uncommented. Each DataConnector must have one and one only Dependency which is where the data comes from; in this case it references our LDAP DataConnector using the id we chose for that entry.  It is a bit sad that it re-uses the value "computedID" for two different attributes, namely '''id''' and '''generatedAttributeID'''.  This is confusing, but legal.

 <source lang="xml">

    <resolver:DataConnector xsi:type="ComputedId" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
              id="computedID"
              generatedAttributeID="computedID"
              sourceAttributeID="uid"

              salt="aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=">
        <resolver:Dependency ref="myLDAP" />
    </resolver:DataConnector>
 </source>

The ''salt'' value must be a random string with a minimum length of 16 characters (48 characters recommended). It is best generated using openssl:

 <source lang="bash">
 $ openssl rand -base64 48 2>/dev/null
 </source>

We will probably have to add an AttributeDefinition for the eduPersonTargetedID that will be encoded by the IdP for the SP. Add the definition with the others at the start of the file (the exact location is not that important). Note that it has a dependency reference of the DataConnector we just created as well as specifying the DataConnector's generatedAttributeID as the value source (as previously noted, these are different things which have the same value in this case).
 
 <source lang="xml">
    <resolver:AttributeDefinition xsi:type="SAML2NameID" xmlns="urn:mace:shibboleth:2.0:resolver:ad"

              id="eduPersonTargetedID" 
              nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
              sourceAttributeID="computedID">
        <resolver:Dependency ref="computedID" />

 
        <resolver:AttributeEncoder xsi:type="SAML1XMLObject" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" />
 
        <resolver:AttributeEncoder xsi:type="SAML2XMLObject" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"

                name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" />
    </resolver:AttributeDefinition>
 </source>

The Shibboleth attribute mapping will map the SAML2 OID for our eduPersonTargetedID attribute into the name '''persistent-id''' when it is placed in the HTTP headers&mdash;don't expect to find the actual element name there.

======Stored ID======
To use an RDBMS, we need simply (?) setup a database user and associated table space and table, change the DataConnector definition, and associate the AttributeDefinition to reference our new connection. The AAF documentation for this is especially bad at the time of writing; that from internet2.edu is better, but not really complete. Assuming you have a mySQL database server at rel 5.0 or higher available and have copied the JDBC connector jar to the <code>$CATALINA_HOME/lib</code> directory, the interaction below creates the database, table, and user. It assumes that the MySQL server resides on the IdP host machine (localhost) and naturally, you will change the username for the user to something sensible.

 <source lang="mysql">

 $ mysql -u root -p 
 SET NAMES 'utf8'; 
 SET CHARACTER SET utf8; 
 CHARSET utf8; 
 CREATE DATABASE IF NOT EXISTS shibboleth CHARACTER SET = utf8;
 USE shibboleth;
 
 CREATE TABLE IF NOT EXISTS shibpid ( 
 localEntity TEXT NOT NULL, 
 peerEntity TEXT NOT NULL, 
 principalName VARCHAR(255) NOT NULL default <nowiki>''</nowiki>, 
 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;
 
 USE mysql; 
 INSERT INTO user (Host,User,Password,
 Select_priv,Insert_priv,Update_priv,Delete_priv, 
 Create_tmp_table_priv,Lock_tables_priv,Execute_priv) 
 VALUES 
 ('localhost','shibboleth',PASSWORD('changeMeNOW'), 
 'Y','Y','Y','Y','Y','Y','Y'); 
 GRANT ALL ON shibboleth.* TO 'shibboleth'@'localhost' IDENTIFIED BY 'changeMeNOW'; 
 FLUSH PRIVILEGES; 
 QUIT
 </source>

Next we must edit the ''a'''attribute-resolver.xml''''' file to add a new DataConnector for the xsi:type ''StoredID'' that will get the user name from LDAP, hash it with IdP and SP URLs, and store the result in MySQL. We must also modify the existing AttributeDefinition for ''eduPersonTargetedID'' to make use of the new DataConnector. First the DataConnector as shown below (you do not need to comment out the previous xsi:type ''ComputedID'' as when we are done, nothing will reference it, though doing so may reduce the IdP footprint:

 <source lang="xml">
    <resolver:DataConnector xsi:type="StoredId" xmlns="urn:mace:shibboleth:2.0:resolver:dc"

              id="myStoredId"
              sourceAttributeID="uid"
              generatedAttributeID="persistentID"
              salt="aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=">
        <resolver:Dependency ref="myLDAP" />

        <ApplicationManagedConnection
            jdbcDriver="com.mysql.jdbc.Driver"
            jdbcURL="jdbc:mysql://localhost:3306/shibboleth?autoReconnect=true"
            jdbcUserName="shibboleth"
            jdbcPassword="changeMeNOW" />

    </resolver:DataConnector>
 
    <!-- Computed targeted ID connector -->
    <!-- This Conenctor now unused and may be commented out or deleted -->
    <resolver:DataConnector xsi:type="ComputedId" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
              id="computedID"

              generatedAttributeID="computedID"
              sourceAttributeID="uid"
              salt="aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=">
        <resolver:Dependency ref="myLDAP" />

    </resolver:DataConnector>
 </source>

Note the id for the connector and the generatedAttributeID values. These go into the AttributeDefinition for eduPersonTargetedID which appears earlier in the sale xml file:

 <source lang="xml">
    <resolver:AttributeDefinition xsi:type="SAML2NameID" xmlns="urn:mace:shibboleth:2.0:resolver:ad"

              id="eduPersonTargetedID" 
              nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
              sourceAttributeID="persistentID">   &lt;!-- was "computedID" -->
        <resolver:Dependency ref="myStoredId" />  &lt;!-- was "computedID" too -->

 
        <resolver:AttributeEncoder xsi:type="SAML1XMLObject" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" />
 
        <resolver:AttributeEncoder xsi:type="SAML2XMLObject" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"

                name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" />
    </resolver:AttributeDefinition>
 </source>

The persistent ID values for combinations of users and SP's will now be stored in the MySQL table which can be verified by doing a select all on the table. For our simple IdP this is a rather dubious value exercise, but it would have benefit on a real and large user base IdP, plus it was hard to figure out, so well worth recording here ;-)

====attribute-filter====
Finally, we need to ensure that all extracted attributes are encoded for sending to the relying SP. The <code>$IDP_HOME/conf/attribute-filter.xml</code> file provides per-SP filtering with AND/OR logic. For the simple case, we create an AttributeFilterPolicy that passes all AAF mandatory attributes, plus the optional ''locality'' and ''stateProvince'' attributes to all SP's this way:

 <source lang="xml">

    <AttributeFilterPolicy id="releaseToAnyone">
        <PolicyRequirementRule xsi:type="basic:ANY" />
        <AttributeRule attributeID="commonName">
            <PermitValueRule xsi:type="basic:ANY" />

        </AttributeRule>
        <AttributeRule attributeID="organizationName">
            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="surname">

            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="givenName">
            <PermitValueRule xsi:type="basic:ANY" />

        </AttributeRule>
        <AttributeRule attributeID="email">
            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="title">

            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="eduPersonAffiliation">
            <PermitValueRule xsi:type="basic:ANY" />

        </AttributeRule>
        <AttributeRule attributeID="auEduPersonAffiliation">
            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <!-- although part of the standard distribution, exposing the user login names is questionable idea. -->

        <AttributeRule attributeID="eduPersonPrincipalName">
            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="eduPersonTargetedID">

            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="locality">
            <PermitValueRule xsi:type="basic:ANY" />

        </AttributeRule>
        <AttributeRule attributeID="stateProvince">
            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
        <AttributeRule attributeID="displayName">

            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
    </AttributeFilterPolicy>
 </source>

Filtering stops after the first match. The provided default filter file includes a sample filter at the start that filters the legal values for ''eduPersonAffiliation'' to any of three distinct SP URL's. This means that even though we've included the attribute in our "releaseToAnyone" rule, as the attribute will match the (unidentified) rule, but be rejected as not being in the allowable SP URL PolicyRequirementRule, the value will be filtered out. If you want this attribute (a coarser-grained value for Affiliation than auEduPersonAffiliation), either add your SP URL to the list, or comment out/delete the rule all together.

====Adding ARCS Shared Token Support====
The auEduPersonSharedToken is a [[mandatory]] AAF attribute, but (obviously) cannot be provided "out of the box" in the IdP which is maintained by a non-Australian group. To generate it, we need a library available from ARCS, and some configuration. There are multiple references on how to do this on-line at ARCS, all of which have errors and omissions at the time this was written. The best of them is:

* http://projects.arcs.org.au/trac/systems/wiki/HowTo/InstallIdP/IdP-Installation-CentOS5/IMAST-Installation

Note that '''the ARCS jar requires IdP v 2.1.x'''. The notes below should be read in conjunction with the ARCS notes.

1. Obtain the ARCS Shared Token jar. This can be downloaded in binary, or built from source (best) using Maven. The end result will be a jar named <code>arcs-shibext-x.x.x.jar</code> (where x.x.x is the version - 1.5.2 at the time of writing).

2. Copy the jar to the <code>lib</code> directory of the unzipped IdP project that builds the IdP war file, and regenerate the IdP using the Ant script. Be sure to answer '''no''' to the "is this a new installation" question or the build will overwrite your config files!

3. Copy the newly regenerated war file from <code>$IDP_HOME/war</code> to the tomcat <code>webapps</code> directory.

4. Decide where you are going to persist the Shared Token values. We suggest mySQL as this allows you to easily inspect the values which can help in determining if all is well, and may help client side debug as well. The other possibility is LDAP.

5. Assuming mySQL for the storage, follow the ARCS instructions to create the tablespace, table, and a user (you could place it in the persistent-id tablespace and use the same user&mdash;there are no clashes).

6. Edit the <code>$IDP_HOME/conf/attribute-resolver.xml</code> file. Here is where ARCS doco is badly wrong. We need to add a Data Connector which uses non-standard attributes that are defined in a ARCS XSD schema&mdash;hence they must be name-space qualified! So the resolver file needs the ANDS schema reference added to the schema locations, the new attribute definition, and the new data connector as shown below (note the all-important '''arcs:''' added to tell the parser who supplies certain non-standard identifiers!)

 <source lang="xml">

    xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd
    ...
                       urn:mace:arcs.org.au:shibboleth:2.0:resolver:dc classpath:/schema/arcs-shibext-dc.xsd">
    ...
    <resolver:AttributeDefinition id="auEduPersonSharedToken" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
              sourceAttributeID="auEduPersonSharedToken">

        <resolver:Dependency ref="sharedToken" />
        <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                  name="urn:mace:federation.org.au:attribute:auEduPersonSharedToken" />

        <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                  name="urn:oid:1.3.6.1.4.1.27856.1.2.5" friendlyName="auEduPersonSharedToken" />
    </resolver:AttributeDefinition>

    ...
    <resolver:DataConnector xsi:type="arcs:SharedToken" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                            id="sharedToken"
                            sourceAttributeID="uid"
                            storeDatabase="true"

                            salt="aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=">
        <resolver:Dependency ref="myLDAP" />
        <arcs:DatabaseConnection
            jdbcDriver="com.mysql.jdbc.Driver"
            jdbcURL="jdbc:mysql://localhost:3306/imast?autoReconnect=true"

            jdbcUserName="imast"
            jdbcPassword="secret"
            primaryKeyName="uid" />
    </resolver:DataConnector>

 </source>

If you haven't already, add a new rule to the <code>$IDP_HOME/conf/attribute-filter.xml</code> config to pass on the generated attribute:

 <source lang="xml">
        <AttributeRule attributeID="auEduPersonSharedToken">

            <PermitValueRule xsi:type="basic:ANY" />
        </AttributeRule>
 </source>

Now restart Tomcat to load the new configuration and authenticate through an SP. If you are using the phpinfo demonstration/test SP, you should see a new [Shib-AEP-SharedToken] attribute in the HTTP headers. Looking in the mySQL <code>tb_st</code> table will show mapping of shared token values to user names, confirming it is being generated.

===Shibboleth (IdP side)===
The default home location for Shibboleth is <code>/etc/shibboleth</code>. Configuration is required in <code>$SHIBD_HOME/shibboleth2.xml</code>, <code>$SHIBD_HOME/attribute-map.xml</code>, and <code>$SHIBD_HOME/attribute-policy.xml</code>. The daemon should be restarted after making any changes.

A reasonable commentary on how the IdP attributes are assembled can be read at https://spaces.internet2.edu/display/SHIB2/IdPAddAttribute.

====shibboleth2.xml====
The daemon needs to know the location of the interface to the IdP. The de-commented section will look like the snippet below. The IdP URL has been configured into attributes of the ApplicationDefaults and SessionInitiator elements.

 <source lang="xml">

    <ApplicationDefaults id="default" policyId="default"
        entityID="https://g709-0157.itee.uq.edu.au/idp/shibboleth"
        REMOTE_USER="eppn persistent-id targeted-id"
        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">
 
            <SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="Intranet"

                    relayState="cookie" entityID="https://g709-0157.itee.uq.edu.au/idp/shibboleth">
                <SessionInitiator type="SAML2" acsIndex="1" template="bindingTemplate.html"/>

                <SessionInitiator type="Shib1" acsIndex="5"/>
            </SessionInitiator>
            ...
        </Sessions>
        ...
    </ApplicationDefaults>

 </source>

====attribute-map.xml====
This config file plays no part in the sending of attributes to the SP (VERIFY!!).

====attribute-policy.xml====
This config file plays no part in the sending of attributes to the SP (VERIFY!!).

===Shibboleth (SP side)===
====shibboleth2.xml====
On the SP side, the ''shibd'' needs a copy of the IdP metadata. The process might go like this:

 <source lang="bash">
 $ rsync root@idp_host:/usr/local/idp/metadata/idp-metadata.xml /etc/shibboleth/
 </source>

This file location must now be configured into the main ''shibd'' config file, <code>$SHIBD_HOME/shibboleth2.xml</code>.

 <source lang="xml">

    <ApplicationDefaults id="default" policyId="default"
        entityID="https://redactor.itee.uq.edu.au/shibboleth"
        REMOTE_USER="eppn persistent-id targeted-id"
        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">
 
        ...
 
       <MetadataProvider type="Chaining">

            <MetadataProvider type="XML" uri="https://g709-0157.itee.uq.edu.au/idp/shibboleth"
                 backingFilePath="idp-metadata.xml" reloadInterval="7200">
               <MetadataFilter type="Signature" certificate="fedsigner.pem"/>

            </MetadataProvider>
 
            ...
 
            <MetadataProvider type="XML" file="/etc/shibboleth/idp-metadata.xml"/>
 
       </MetadataProvider>
 
       ...
 
    </ApplicationDefaults>

 </source>

====attribute-map.xml====
This file maps attributes provided by the IdP to the header names that will be associated with them when passed from SP to the service. For example, the attribute ''eduPersonTargetedID'' is remapped to ''persistent-id''. As we don't want to alias our auEduPersonAffiliation, there's nothing to do here.

Should you want to remap an attribute, create Attribute elements for the OID and URN forms for SAML2 and SAML1 respectively:

 <source lang="xml">
    <Attribute name="urn:oid:1.3.6.1.4.1.27856.1.2.1" id="foobar"/>
    <Attribute name="xurn:mace:dir:attribute-def:auEduPersonAffiliation" id="foobar"/>

 </source>

Most Shibboleth and IdP services today use SAML2 encoding so the URN form could be omitted. Use both if you want to feel safe.

====attribute-policy.xml====
Attributes must match a rule in the attribute-policy file in order to be forwarded. Advanced usage even allows the user themselves to veto release of attributes, but we want to send our ''auEduPersonEntitlement'' through, unmolested. The easiest way to do this is place a catch-all rule at the bottom of the file:

 <source lang="xml">
    <afp:AttributeFilterPolicy>
 
        ...
 
       <afp:AttributeRule attributeID="*">
           <afp:PermitValueRule xsi:type="ANY"/>

       </afp:AttributeRule>
 
    </afp:AttributeFilterPolicy>
 </source>

A more advanced policy might check for valid "staff" values per the controlled vocabulary as specified by CAUDIT, filtering out all "students". To do this, we create a PermitValueRule and reference it from an explicit AttributeRule for the attribute name:

 <source lang="xml">

    <afp:PermitValueRule id="auEduPersonStaffAffiliationValues" xsi:type="OR">
        <Rule xsi:type="AttributeValueString" value="visiting-staff"/>
        <Rule xsi:type="AttributeValueString" value="emeritus-staff"/>

        <Rule xsi:type="AttributeValueString" value="contractor"/>
        <Rule xsi:type="AttributeValueString" value="physically-present"/> 
    </afp:PermitValueRule>

 
    ...
 
    <afp:AttributeFilterPolicy>
        ...
        <afp:AttributeRule attributeID="auEduPersonAffiliation">
            <afp:PermitValueRuleReference ref="auEduPersonStaffAffiliationValues"/>
        </afp:AttributeRule>

        ...
    </afp:AttributeFilterPolicy>
 </source>

==Problem Solving==
The log files for the IdP and ''shibd'', together with the usual ''httpd'' and <code>$CATALINA_HOME/logs/catalina.out</code> logs will generally provide enough information to diagnose "why is it doing that?" problems. The tricky ones are the type likely to be encountered during first deployment and startup; things like "Connection Refused", and "cannot connect to shibd process" messages at the client rather than the SP, or IdP. The notes below may be useful.

===Connection Refused===
First check that the firewalls on SP and IdP are open to the required ports. By default these will be 80 and 443. Tomcat will probably be configured to use 8080, 8443 and 8009, but as their use is local to the IdP host, they do not need to be open to the outside world; likewise port 389 for LDAP. The entries below are taken from a Tomcat 6.6 <code>$CATALINA_HOME/conf/server.xml</code> config file setup to run the IdP.

 <source lang="apache">

   <Connector port="8080" protocol="HTTP/1.1"
              connectionTimeout="20000"
              redirectPort="8443" />

 
   <connector port="8443"
              scheme="https"
              secure="true"
              clientAuth="true"
              sslProtocol="TLS"

              sslImplementation="edu.internet2.middleware.shibboleth.tomcat.DelegateToApplicationJSSEImplementation"
              keystoreFile="/usr/local/idp/credentials/idp.jks"
              keystorePass="secret" />
 
   <Connector port="8009"

              enableLookups="false"
              redirectPort="8443" 
              protocol="AJP/1.3"
              request.tomcatAuthentication="false" 
              address="g709-0157.itee.uq.edu.au" />

 </source>

In this case, the IdP host is "g709-0157.itee.uq.edu.au". In the default Tomcat server.xml, this will probably default to "127.0.0.1". This has been observed as a source of "connection refused" problems. Use the fully qualified host name.

The corresponding config for Apache is done in <code>/etc/httpd/conf/httpd.conf</code>:

 <source lang="dos">

 # httpd.conf setup to pass requests to Tomcat.
 ProxyPass /idp/ ajp://g709-0157.itee.uq.edu.au:8009/idp/
 </source> 

==Resources==
For convenience, configuration files for AAF complaint installations for the IdP and SP's can be downloaded using the links listed below.
Not wishing to instruct grandmothers on the fine art of egg-sucking, right-click and save-as. If you just click on the links, be sure to "view source" otherwise they may look rather messy.

===IdP Config files===
* http:///maenad.itee.uq.edu.au/ron/relying-party.xml
* http:///maenad.itee.uq.edu.au/ron/attribute-filter.xml
* http:///maenad.itee.uq.edu.au/ron/attribute-resolver.xml

===SP Config files===
* http:///maenad.itee.uq.edu.au/ron/attribute-map.xml
* http:///maenad.itee.uq.edu.au/ron/attribute-policy.xml


[[Category:Software]]


HTML produced by any_wiki_tohtml()


<p>This page will assist in setting up and configuring a &quot;dummy&quot; <strong>Shibboleth Identity Provider</strong> (IdP) which emulates the operation of a typical member of the <strong>Australian Authentication Federation</strong> (AAF), together with one or more <strong>Service Providers</strong> (SP) to operate with it. The SP and IdP exist in a peer-to-peer relationship with each having explicit knowledge of the other through the configuration files. As a typical development machine will be inside a firewall, establishing a connection with an external IdP is somewhere between difficult to impossible, hence the need for an AAF-like service that can be totally inside the firewall, but will provide a realistic environment for development and testing. For the UQ eResearch group, a fully functional setup has been configured to run on the g709-0157.itee.uq.edu.au host. </p>

<p><strong>''This document does not replace the referenced on-line setup guides.</strong>''</p>

<p>It is intended simply to fill in the gaps and address incorrect or misleading information found by the author while following the guides. It also adds some explanation of how the various configuration items relate to each other&amp;mdash;another item rather obscure in the on-line guides&amp;mdash;under the theory that a degree of understanding of what the various XML elements are doing is an aid to problem solving.</p>

<p>Rather than clutter the example code with place holders for installation-specific values, I have used snippits from an actual installation. The following URLs are specific to this setup and must be changed as required:</p>


<ul>
<li><a href="http://g909-0157.itee.uq.edu.au">g909-0157.itee.uq.edu.au</a> is the machine hosting the IdP</li>
<li><a href="http://redactor.itee.uq.edu.au">redactor.itee.uq.edu.au</a>  is the machine hosting the SP</li>

<li>[[&quot;ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au&quot;]] is the LDAP tree path to user identities.</li>
</ul>

<p>==Prerequisites==<br/>
The IdP requires:</p>

<ul>
<li>Apache</li>
<li>Tomcat</li>
<li>Shibboleth</li>
<li>The Internet2 IdP application (Java webapp)</li>

<li>LDAP (optional, but required to really emulate AAF attributes)</li>
<li>mySQL (optional for caching persistent ID values. IdP will regenerate as needed if not present)</li>
</ul>

<p>No versions are given as it has been found that using the &quot;latest&quot; is a good plan. The only exception may be Shibboleth itself as the installation RPM must be built from source RPMs unless you are running Centos 5, or SUSE. Even then it may be best to build the RPMs to ensure you have all the required dependencies are available and at the required revision level.</p>

<p>Basic setup information is reasonably well covered by </p>

<ul>
<li><a href="http://spaces.internet2.edu/display/SHIB2/Home">spaces.internet2.edu/display/SHIB2/Home</a> and</li>

<li><a href="http://spaces.internet2.edu/display/SHIB2/IdPInstall.">spaces.internet2.edu/display/SHIB2/IdPInstall.</a></li>
</ul>

<p>This page will not repeat those instructions except where clarification is necessary.</p>

<p>==Basic Operation==<br/>

The IdP is a Java web service that requires a Tomcat container. The Apache daemon (<em>httpd</em>) front-ends Tomcat and interacts with the Shibboleth daemon (<em>shibd</em>) via the mod-shib.so library to perform Single Sign On (SSO) and inject an authenticated user's attributes as headers in the HTTP response that will (eventually) travel back to the application that requested the SSO operation via a Shibboleth Service Provider (SP). IdP's and SP's exist in a peer-to-peer relationship (the Shibboleth documentation calls them <em>Relying Parties</em> as they rely on each other).  Explicit metadata relating to an IdP must be copied to the shibd configuration file on the SP. Similarly, the host identity of each SP must be configured into the shibd configuration of the IdP. Additionally, explicit knowledge of a SP <em>may</em> be entered into the <em>shibd</em> and IdP filter configuration files.</p>

<p>The <em>shibd</em> configuration file (default location &lt;code&gt;/etc/shibboleth/shibboleth2.xml&lt;/code&gt;) contains a reference to the URL of the IdP webapp that is run by Tomcat and front-ended by Apache so it can be accessed through ports 80, 443, and 8443. The IdP webapp config specifies where user data are located. This may be a flat file, LDAP, or an RDBMS. Once authenticated, user attribute data are extracted, filtered, encoded using Security Assertion Markup Language (SAML2), and sent to the SP <em>shibd</em> where SAML2 OID attributes are mapped to local attribute identifiers and optionally filtered again before setting the name value pairs into the HTTP response headers for return to the requesting service. </p>

<p>This may appear confusing at first as the attribute names known and set in the LDAP schemas (for example) are mapped to different names by the default <em>shibd</em> configuration files! For example, the IdP webapp may be configured to generate a universally unique user attribute named <em>eduPersonTargettedID</em> using a hash of the URLs for the IdP, requesting SP, and the authenticated users login name (the latter is never exposed for very good security reasons). However, the default <em>attribute-map.xml</em> file installed with Shibboleth maps this name to an alias of <em>persistent-id</em> and that is how it will appear in the HTTP header sent to the client service. </p>

<p>The opportunity for initial confusion is considerable, so when things are not working as expected, set <em>shibd</em> logging to DEBUG at both ends, and follow through the chain in the logs at both ends to see if the attribute being extracted, and if so, where it got filtered away. The chain begins with the &lt;code&gt;$IDP_HOME/log/idp-process.log&lt;/code&gt; at the IdP host, then to the IdP <em>shibd</em> in &lt;code&gt;/var/log/shibboleth/shibd.log&lt;/code&gt; and ultimately to the SP host in &lt;code&gt;/var/log/shibboleth/shibd.log&lt;/code&gt;. Examine each and modify the appropriate attribute map or filter file until it is passed/encoded. DEBUG level logging is quite verbose, so be sure to set it back to INFO when the problem is solved to prevent excessive log file growth.</p>

<p>==Configuration==<br/>
Setup is done by editing .XML files in &lt;code&gt;$SHIB_HOME&lt;/code&gt; (default &lt;code&gt;/etc/shibboleth&lt;/code&gt;) and &lt;code&gt;$IDP_HOME/config&lt;/code&gt; (default &lt;code&gt;/usr/local/idp&lt;/code&gt;). </p>

<p>In addition to those attributes for which definitions already exist in the standard configuration, we will undertake the task of providing the following attributes to all relying parties as an illustration of the various ways data can be collected and associated with user attributes:</p>

<p>{| class=&quot;wikitable&quot;<br/>
! Attribute Name !! Name in HTTP header !! Description<br/>
|-<br/>

| locality<br/>
| l<br/>
| A static attribute set to <strong>Brisbane</strong>.<br/>
|-<br/>
| stateProvince<br/>

| st<br/>
| Another static attribute common to all users set to <strong>Queensland</strong>.<br/>
|-<br/>
| displayName<br/>
| (same)<br/>

| A composite attribute formed from the LDAP <em>givenName</em> and <em>sn</em> (surname) attributes.<br/>
|-<br/>
| auEduPersonAffiliation <br/>

| (same)<br/>
| This is an optional attribute that will be loaded from LDAP which has a finer granularity than eduPersonAffiliation (also fetched from LDAP).<br/>
|-<br/>
| eduPersonTargetedID<br/>
| persistent-id<br/>
| This attribute is useful to applications that need to perform local authorization based on a unique user &quot;key&quot; and although a <em>mandatory</em> AAF attribute, is not part of the standard, default, IdP/Shibboleth distribution configuration. We will also see how this computed value can be stored in a RDBMS for quick lookup.<br/>

|}</p>

<p>===Apache===<br/>
This LDAP-specific config information for Apache is hard to locate and confusing within the twisty maze of <a href="http://spaces.internet2.edu">spaces.internet2.edu</a> documentation pages. We need a &amp;lt;Location&amp;gt; entry in the Apache config that securely directs requests http and https to the IdP servlet. This could be placed in &lt;code&gt;/etc/http/httpd.conf&lt;/code&gt; but is probably better placed in &lt;code&gt;/etc/http/conf.d/ssl.conf&lt;/code&gt; (another option would be &lt;code&gt;/etc/http/conf.d/shibd.conf&lt;/code&gt; but that might be too confusing as it is not really related directly to shibd). In it, we must tell Apache the servlet path and some parameters:</p>

<p> &lt;source lang=&quot;apache&quot;&gt;<br/>
 &lt;Location /idp/Authn/UsernamePassword&gt;<br/>
    AuthType LDAP<br/>

    require valid-user<br/>
 &lt;/Location&gt;<br/>
 &lt;/source&gt;</p>

<p>Alternatively, if we were doing file-based authentication, the entry would be as follows nominating the path to the flat file holding users and encrypted passwords. This may be useful as an interim setup to confirm IdP/SP operation before adding the complexity of LDAP which is the easiest option for supplying per-user attribute values.</p>

<p> &lt;source lang=&quot;apache&quot;&gt;<br/>
 &lt;Location /idp/Authn/RemoteUser&gt;<br/>
    AuthType Basic<br/>

    AuthName &quot;eResearch Development Identity Provider&quot;<br/>
    AuthUserFile /usr/local/idp/credentials/user.db<br/>
    require valid-user<br/>
 &lt;/Location&gt;<br/>

&lt;/source&gt;</p>

<p>===Tomcat===<br/>
The Tomcat configuration will need configuring so the IdP can use the Java Authentication and Authorization Service (JAAS) to talk with LDAP. This is done by adding a new Relam to the &lt;code&gt;$CATALINA_HOME/config/service.xml&lt;/code&gt; file:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
  &lt;Service name=&quot;Catalina&quot;&gt;<br/>
    ...<br/>

    &lt;connector  port=&quot;8443&quot;<br/>
                scheme=&quot;https&quot;<br/>
                secure=&quot;true&quot;<br/>

                clientAuth=&quot;true&quot;<br/>
                sslProtocol=&quot;TLS&quot;<br/>
                sslImplementation=&quot;edu.internet2.middleware.shibboleth.tomcat.DelegateToApplicationJSSEImplementation&quot; /&gt;</p>

<p>    &lt;Connector port=&quot;8009&quot;<br/>
               enableLookups=&quot;false&quot;<br/>
               redirectPort=&quot;8443&quot;<br/>

               protocol=&quot;AJP/1.3&quot;<br/>
               request.tomcatAuthentication=&quot;false&quot;<br/>
               address=&quot;g709-0157.itee.uq.edu.au&quot; /&gt;<br/>

    ...<br/>
    &lt;Engine name=&quot;Catalina&quot; defaultHost=&quot;localhost&quot;&gt;<br/>
      ...<br/>

      <!-- added by RC (see also ./jaas.conf file) --><br/>
      &lt;Realm className=&quot;org.apache.catalina.realm.JAASRealm&quot;<br/>
             appName=&quot;Tomcat&quot;<br/>
             userClassName=&quot;edu.vt.middleware.ldap.jaas.LdapPrincipal&quot;<br/>

             roleClassName=&quot;edu.vt.middleware.ldap.jaas.LdapRole&quot; /&gt;<br/>
    &lt;/Engine&gt;<br/>
  &lt;/Service&gt;   <br/>

 &lt;/source&gt;</p>

<p>We must now create a &lt;code&gt;$CATALINA_HOME/config/jaas.conf&lt;/code&gt; with an entry matching the <em>appName</em> attribute above:</p>

<p> &lt;source lang=&quot;apache&quot;&gt;<br/>
 Tomcat {<br/>
   edu.vt.middleware.ldap.jaas.LdapLoginModule required<br/>

   host=&quot;g709-0157.itee.uq.edu.au&quot;<br/>
   base=&quot;ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au&quot;<br/>
   port=&quot;389&quot;<br/>

   serviceUser=&quot;Manager@maenad.itee.uq.edu.au&quot;<br/>
   serviceCredential=&quot;secret&quot;<br/>
   userField=&quot;uid&quot;<br/>

   userRoleAttribute=&quot;objectClass&quot;<br/>
   subtreeSearch=&quot;true&quot;;<br/>
 };<br/>
 &lt;/source&gt;</p>

<p>===LDAP===<br/>
Following a standard openLDAP install, we need to add the schemas for &lt;code&gt;auEduPerson&lt;/code&gt; and &lt;code&gt;eduPerson&lt;/code&gt; which will be needed by some user attributes (note that &lt;code&gt;auEduPerson&lt;/code&gt; is a finer grained attribute than <em>eduPersonAffiliation</em> and may not be applicable to every user in the directory).<br/>

For full details on configuring LDAP for use with the IdP, see:</p>

<ul>
<li><a href="http://maenad.itee.uq.edu.au/wiki/LDAP">maenad.itee.uq.edu.au/wiki/LDAP</a></li>
</ul>

<p>===IdP===<br/>

Configuration guides for the IdP are located at </p>

<ul>
<li><a href="https://manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+Installation">manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+Installation</a></li>
<li><a href="https://manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+2.1+on+Redhat">manager.test.aaf.edu.au/wiki/display/IDP/Shibboleth+IdP+2.1+on+Redhat</a></li>

<li>and &quot;children&quot; pages of those pages.</li>
</ul>

<p><strong>''NOTE with Caution!</strong>'' All AAF doco pages have errors, omissions, and missing vital information. The AAF (Terry Smith) is aware and acknowledges this. Another set of instructions that are less flawed, but also less AAF specific that may be useful can be found at:</p>

<ul>
<li><a href="https://www.switch.ch/aai/docs/shibboleth/SWITCH/2.1/idp/install-idp-2.1-debian.html#shibboleth-idp">www.switch.ch/aai/docs/shibboleth/SWITCH/2.1/idp/install-idp-2.1-debian.html#shibboleth-idp</a></li>
</ul>

<p>As stated, it is best to get the <strong>''latest</strong>'' IdP builder from <a href="http://shibboleth.internet2.edu/downloads/shibboleth/idp/latest/">shibboleth.internet2.edu/downloads/shibboleth/idp/latest/</a> selecting the zip file at the end of that path. At the time of writing, it was &lt;code&gt;shibboleth-identityprovider-2.1.5-bin.zip&lt;/code&gt;.</p>

<p>After unzipping into a user directory, you wil run an Ant script that asks some questions, then configures the IdP webapp war file, creates a directory tree (you specify where, but creating it will probably need root access) and copies the war, default configuration files, and other files to it. The answers you gave are stored to disc so you can re-run the process to regenerate the war file without trashing the config file which you will have customized. It's a good idea to set up a job which backs up your IdP conf files though. You can customize things like the login jsp page by editing it in the unzipped project (follow the &lt;code&gt;src&lt;/code&gt; tree) and regenerating the war file.</p>

<p>The IdP should periodically check its config file timestamps and reload if required, but I suggest you restart Tomcat after making any changes to the configuration. It is not necessary to restart Apache, nor <em>shibd</em> unless changes were made to the Shibboleth configuration, filter, or map files. These too refresh every five minutes or so, but a restart is quicker. The order of a multy-restart is not important.</p>

<p>====handler.xml====<br/>
The IdP login handlers are specified in the &lt;code&gt;$IDP_HOME/conf/handler.xml&lt;/code&gt; file. By default, the file will make the servlet use Apache mediated username/password lookup from a flat file. To disable this, the &quot;RemoteUser&quot; handler must be deleted or commented out and the UserPassword handler un-commented. But the default file is missing a property from this element! The actual entry is shown below:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>

    &lt;LoginHandler xsi:type=&quot;UsernamePassword&quot;<br/>
                  authenticationServletURL=&quot;Authn/UserPassword&quot;<br/>
                  jaasConfigurationLocation=&quot;file:///usr/local/idp/conf/login.config&quot;&gt;<br/>

        &lt;AuthenticationMethod&gt;urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport&lt;/AuthenticationMethod&gt;<br/>
    &lt;/LoginHandler&gt;<br/>
 &lt;/source&gt;</p>

<p>Authentication will now be performed using the &lt;code&gt;$CATALINA_HOME/webapps/idp/login.jsp&lt;/code&gt; page. If you want to change this page, edit it in the &lt;code&gt;src/&lt;/code&gt; tree of the unpacked IdP zip, then regenerate the war file using the provided Ant script. The answers you gave during the initial build are conveniently recorded and become the new defaults&amp;mdash;just be sure to answer <strong>&quot;no&quot;</strong> to the question about overwriting existing files unless you want all your IdP config files trashed! The process will then just reconfigure and regenerate the web archive into &lt;code&gt;$IDP_HOME/war&lt;/code&gt;. Copy the war file to &lt;code&gt;$CATALINA_HOME/webapps&lt;/code&gt; and restart Tomcat.</p>

<p>====login.conf====<br/>
The login handler defined in the previous entry specifies use of the Java Authentication and Authorization Service (JAAS) to talk with LDAP and nominates a config file path to &lt;code&gt;$LDAP_HOME/conf/login.conf&lt;/code&gt;. This must provide the details details specific to our LDAP directory setup. In it, we set the LDAP host URL details (the port used here is the default and could have been omitted). It also specifies the base Distinguishing Name (dn) for locating the User login names and the LDAP attribute name for the user name [uid]. Other parameters could be included to supply the LDAP admin user credentials as illustrated in the AAF docs, but for read-only access, we don't need these and it's good policy not to expose more than you have to in unencrypted files.</p>

<p> &lt;source lang=&quot;apache&quot;&gt;<br/>

 ShibUserPassAuth {<br/>
   edu.vt.middleware.ldap.jaas.LdapLoginModule required<br/>
      host=&quot;g709-0157.itee.uq.edu.au&quot;<br/>
      port=&quot;389&quot;<br/>

      ssl=&quot;true&quot;<br/>
      base=&quot;ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au&quot;<br/>
      userField=&quot;uid&quot;;<br/>

 };<br/>
 &lt;/source&gt;</p>

<p>====relying-party.xml====<br/>
Then ensure that the SP is registered with the IdP by creating a MetadataProvider element for the SP host and associate with it a location to store the SP's metadata in a backing file in the &lt;code&gt;$IDP_HOME/conf/relying-party.xml&lt;/code&gt; file. Each metadata provider must have a unique &quot;id&quot; value but this can be any unique id name and is not referenced by anything else.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;MetadataProvider id=&quot;URLMD&quot; xsi:type=&quot;FileBackedHTTPMetadataProvider&quot; xmlns=&quot;urn:mace:shibboleth:2.0:metadata&quot;<br/>

                      metadataURL=&quot;<a href="https://redactor.itee.uq.edu.au/Shibboleth.sso/Metadata">redactor.itee.uq.edu.au/Shibboleth.sso/Metadata</a>&quot;<br/>
                      backingFile=&quot;/usr/local/idp/metadata/redactor.xml&quot; /&gt;<br/>

 &lt;/source&gt;</p>

<p>Note that the metadata URL specifies HTTPS protocol. This requires a genuine, signed certificate for the SP with a trust chain trusted by the IdP. You can't use a self-signed certificate because the IdP will reject it, not load the metadata, and the SP will not be configured. If you don't have a real one and must self-sign, use HTTP as the metadata transfer protocol. But fetching the SP metadata by HTTP results in the protol for ALL SP/IdP exchanges being made by HTTP. As this means Shibboleth exchanges in both directions will be unencrypted, it should be obvious that this is not a configuration you'd want to deploy for real!!</p>

<p>====attribute-resolver.xml====<br/>
Attribute definitions and the ways data are collected for them are specified in the &lt;code&gt;$IDP_HOME/conf/attribute-resolver.xml&lt;/code&gt; file. </p>

<p>The static attributes that will be set for all users are easy. We just need a DataConnector to provide the name value pairs which are then associated with the appropriate AttributeDefinition entries. Notice that the AttributeDefinitions reference the DataConnector's id as a dependency reference, with the sourceAttributeID attribute matching the value of the id attribute of one of the Attribute elementx contained in the static DataConnector. We could store the <em>l</em> and <em>st</em> values in LDAP and set the Dependency ref to <em>myLDAP</em>, but that seems inefficient when all our users are co-located. Besides, it lets us play with static attribute values.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:AttributeDefinition xsi:type=&quot;Simple&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>

              id=&quot;locality&quot; <br/>
              sourceAttributeID=&quot;l&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;staticAttributes&quot; /&gt;<br/>

        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
            name=&quot;urn:mace:dir:attribute-def:l&quot; /&gt;<br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

            name=&quot;urn:oid:2.5.4.7&quot; friendlyName=&quot;l&quot; /&gt;<br/>
    &lt;/resolver:AttributeDefinition&gt;<br/>
    <br/>

    &lt;resolver:AttributeDefinition xsi:type=&quot;Simple&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>
              id=&quot;stateProvince&quot; <br/>
              sourceAttributeID=&quot;st&quot;&gt;<br/>

        &lt;resolver:Dependency ref=&quot;staticAttributes&quot; /&gt;<br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
              name=&quot;urn:mace:dir:attribute-def:st&quot; /&gt;<br/>

        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
              name=&quot;urn:oid:2.5.4.8&quot; friendlyName=&quot;st&quot; /&gt;<br/>

    &lt;/resolver:AttributeDefinition&gt;<br/>
    ...<br/>
    &lt;resolver:DataConnector xsi:type=&quot;Static&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>

              id=&quot;staticAttributes&quot; &gt;<br/>
        &lt;Attribute id=&quot;l&quot;&gt;<br/>
            &lt;Value&gt;Brisbane&lt;/Value&gt;<br/>

        &lt;/Attribute&gt;<br/>
        &lt;Attribute id=&quot;st&quot;&gt;<br/>
            &lt;Value&gt;Queensland&lt;/Value&gt;<br/>

        &lt;/Attribute&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>
 &lt;/source&gt;</p>

<p>The <em>displayName</em> AttributeDefinition is a little more complex, being formed from two space separated attributes sourced from LDAP. We do this with a Velocity Template, although this time we do not require a DataConnector as the source attributes are populated from the LDAP DataConnector:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:AttributeDefinition xsi:type=&quot;Template&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>

              id=&quot;displayName&quot; &gt;<br/>
       &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>
       &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

                 name=&quot;urn:mace:dir:attribute-def:displayName&quot; /&gt;<br/>
       &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
                 name=&quot;urn:oid:2.16.840.1.113730.3.1.241&quot; friendlyName=&quot;displayName&quot; /&gt;<br/>

       &lt;Template&gt;&lt;![CDATA[${givenName} ${sn}]]&gt;&lt;/Template&gt;<br/>
       &lt;SourceAttribute&gt;givenName&lt;/SourceAttribute&gt;<br/>
       &lt;SourceAttribute&gt;sn&lt;/SourceAttribute&gt;<br/>

    &lt;/resolver:AttributeDefinition&gt;<br/>
 &lt;/source&gt;</p>

<p>Lastly, we add a definition for the <em>auEduPersonAffiliation</em> attribute: </p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:AttributeDefinition xsi:type=&quot;Simple&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot; <br/>

              id=&quot;auEduPersonAffiliation&quot; <br/>
              sourceAttributeID=&quot;auEduPersonAffiliation&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>

        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
                  name=&quot;urn:mace:dir:attribute-def:auEduPersonAffiliation&quot; /&gt;<br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

                  name=&quot;urn:oid:1.3.6.1.4.1.27856.1.2.1&quot; friendlyName=&quot;auEduPersonAffiliation&quot; /&gt;<br/>
    &lt;/resolver:AttributeDefinition&gt;<br/>
 &lt;/source&gt;</p>

<p>As before, this defines the attribute, where it can be found in the LDAP service, and two encodings for it. If you have not already, make sure that the &quot;myLDAP&quot; DataConnector element has been configured in the &lt;code&gt;attribute-resolver.xml&lt;/code&gt; file. The example below specifies the LDAP URL using the default port to connect to the service [ldapURL], the base Distinguishing Name for searching [baseDN], and the user login name template [principal]. The name entered interactively by the user will be substituted into the <em>binduser</em> field for the LDAP search.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
   &lt;resolver:DataConnector xsi:type=&quot;LDAPDirectory&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>
             id=&quot;myLDAP&quot; <br/>

             searchScope=&quot;SUBTREE&quot;<br/>
             ldapURL=&quot;ldap://g709-0157.itee.uq.edu.au:389&quot;<br/>
             baseDN=&quot;ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au&quot;<br/>

             principal=&quot;uid=binduser,ou=people,dc=maenad,dc=itee,dc=uq,dc=edu,dc=au&quot; &gt;<br/>
        &lt;FilterTemplate&gt;<br/>
            &lt;![CDATA[<br/>
                (uid=$requestContext.principalName)<br/>

            ]]&gt;<br/>
        &lt;/FilterTemplate&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>
 &lt;/source&gt;</p>

<p>=====Persistent ID's=====<br/>
The <em>eduPersonTargettedID</em> attribute provides a universally unique identity string but requires some configuration to make it work. It is generated by the IdP using the IdP host URL, the SP host URL and a the user's uid string, all hashed. Optionally, it can be cached in a mySQL (or Oracle) RDMBS table, however the config for generating on the fly, and fetching from an RDBMS are significantly different, as shown below.</p>

<p>======Computed ID======<br/>

Computed ID's are generated as required by a special Data Connector entry with the xsi:type <em>ComputedId</em> that is placed in the <strong>''attribute-resolver.xml</strong>'' config file. The file provided with the distribution IdP has a commented out entry for this that can be just uncommented. Each DataConnector must have one and one only Dependency which is where the data comes from; in this case it references our LDAP DataConnector using the id we chose for that entry.  It is a bit sad that it re-uses the value &quot;computedID&quot; for two different attributes, namely <strong>id</strong> and <strong>generatedAttributeID</strong>.  This is confusing, but legal.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:DataConnector xsi:type=&quot;ComputedId&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>

              id=&quot;computedID&quot;<br/>
              generatedAttributeID=&quot;computedID&quot;<br/>
              sourceAttributeID=&quot;uid&quot;<br/>

              salt=&quot;aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>

 &lt;/source&gt;</p>

<p>The <em>salt</em> value must be a random string with a minimum length of 16 characters (48 characters recommended). It is best generated using openssl:</p>

<p> &lt;source lang=&quot;bash&quot;&gt;<br/>

 $ openssl rand -base64 48 2&gt;/dev/null<br/>
 &lt;/source&gt;</p>

<p>We will probably have to add an AttributeDefinition for the eduPersonTargetedID that will be encoded by the IdP for the SP. Add the definition with the others at the start of the file (the exact location is not that important). Note that it has a dependency reference of the DataConnector we just created as well as specifying the DataConnector's generatedAttributeID as the value source (as previously noted, these are different things which have the same value in this case).<br/>
 <br/>

 &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:AttributeDefinition xsi:type=&quot;SAML2NameID&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>
              id=&quot;eduPersonTargetedID&quot; <br/>

              nameIdFormat=&quot;urn:oasis:names:tc:SAML:2.0:nameid-format:persistent&quot;<br/>
              sourceAttributeID=&quot;computedID&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;computedID&quot; /&gt;<br/>

 <br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1XMLObject&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
                name=&quot;urn:oid:1.3.6.1.4.1.5923.1.1.1.10&quot; /&gt;<br/>

 <br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2XMLObject&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
                name=&quot;urn:oid:1.3.6.1.4.1.5923.1.1.1.10&quot; friendlyName=&quot;eduPersonTargetedID&quot; /&gt;<br/>

    &lt;/resolver:AttributeDefinition&gt;<br/>
 &lt;/source&gt;</p>

<p>The Shibboleth attribute mapping will map the SAML2 OID for our eduPersonTargetedID attribute into the name <strong>persistent-id</strong> when it is placed in the HTTP headers&amp;mdash;don't expect to find the actual element name there.</p>

<p>======Stored ID======<br/>
To use an RDBMS, we need simply (?) setup a database user and associated table space and table, change the DataConnector definition, and associate the AttributeDefinition to reference our new connection. The AAF documentation for this is especially bad at the time of writing; that from internet2.edu is better, but not really complete. Assuming you have a mySQL database server at rel 5.0 or higher available and have copied the JDBC connector jar to the &lt;code&gt;$CATALINA_HOME/lib&lt;/code&gt; directory, the interaction below creates the database, table, and user. It assumes that the MySQL server resides on the IdP host machine (localhost) and naturally, you will change the username for the user to something sensible.</p>

<p> &lt;source lang=&quot;mysql&quot;&gt;<br/>

 $ mysql -u root -p <br/>
 SET NAMES 'utf8'; <br/>
 SET CHARACTER SET utf8; <br/>
 CHARSET utf8; <br/>
 CREATE DATABASE IF NOT EXISTS shibboleth CHARACTER SET = utf8;<br/>

 USE shibboleth;<br/>
 <br/>
 CREATE TABLE IF NOT EXISTS shibpid ( <br/>
 localEntity TEXT NOT NULL, <br/>
 peerEntity TEXT NOT NULL, <br/>

 principalName VARCHAR(255) NOT NULL default &lt;nowiki&gt;''&lt;/nowiki&gt;, <br/>
 localId VARCHAR(255) NOT NULL, <br/>
 persistentId VARCHAR(36) NOT NULL, <br/>
 peerProvidedId VARCHAR(255) default NULL, <br/>

 creationDate timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, <br/>
 deactivationDate timestamp NULL default NULL, <br/>
 KEY persistentId (persistentId), <br/>
 KEY persistentId_2 (persistentId, deactivationDate), <br/>
 KEY localEntity (localEntity(16), peerEntity(16),localId), <br/>

 KEY localEntity_2 (localEntity(16), peerEntity(16), localId, deactivationDate) )<br/>
 ENGINE=MyISAM DEFAULT CHARSET=utf8;<br/>
 <br/>
 USE mysql; <br/>
 INSERT INTO user (Host,User,Password,<br/>

 Select_priv,Insert_priv,Update_priv,Delete_priv, <br/>
 Create_tmp_table_priv,Lock_tables_priv,Execute_priv) <br/>
 VALUES <br/>
 ('localhost','shibboleth',PASSWORD('changeMeNOW'), <br/>
 'Y','Y','Y','Y','Y','Y','Y'); <br/>

 GRANT ALL ON shibboleth.* TO 'shibboleth'@'localhost' IDENTIFIED BY 'changeMeNOW'; <br/>
 FLUSH PRIVILEGES; <br/>
 QUIT<br/>
 &lt;/source&gt;</p>

<p>Next we must edit the <em>a<strong>attribute-resolver.xml</strong></em> file to add a new DataConnector for the xsi:type <em>StoredID</em> that will get the user name from LDAP, hash it with IdP and SP URLs, and store the result in MySQL. We must also modify the existing AttributeDefinition for <em>eduPersonTargetedID</em> to make use of the new DataConnector. First the DataConnector as shown below (you do not need to comment out the previous xsi:type <em>ComputedID</em> as when we are done, nothing will reference it, though doing so may reduce the IdP footprint:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:DataConnector xsi:type=&quot;StoredId&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>

              id=&quot;myStoredId&quot;<br/>
              sourceAttributeID=&quot;uid&quot;<br/>
              generatedAttributeID=&quot;persistentID&quot;<br/>

              salt=&quot;aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>
        &lt;ApplicationManagedConnection<br/>

            jdbcDriver=&quot;com.mysql.jdbc.Driver&quot;<br/>
            jdbcURL=&quot;jdbc:mysql://localhost:3306/shibboleth?autoReconnect=true&quot;<br/>
            jdbcUserName=&quot;shibboleth&quot;<br/>

            jdbcPassword=&quot;changeMeNOW&quot; /&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>
 <br/>
    <!-- Computed targeted ID connector --><br/>

    <!-- This Conenctor now unused and may be commented out or deleted --><br/>
    &lt;resolver:DataConnector xsi:type=&quot;ComputedId&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>
              id=&quot;computedID&quot;<br/>

              generatedAttributeID=&quot;computedID&quot;<br/>
              sourceAttributeID=&quot;uid&quot;<br/>
              salt=&quot;aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=&quot;&gt;<br/>

        &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>
 &lt;/source&gt;</p>

<p>Note the id for the connector and the generatedAttributeID values. These go into the AttributeDefinition for eduPersonTargetedID which appears earlier in the sale xml file:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;resolver:AttributeDefinition xsi:type=&quot;SAML2NameID&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>

              id=&quot;eduPersonTargetedID&quot; <br/>
              nameIdFormat=&quot;urn:oasis:names:tc:SAML:2.0:nameid-format:persistent&quot;<br/>
              sourceAttributeID=&quot;persistentID&quot;&gt;   &amp;lt;!-- was &quot;computedID&quot; --&gt;<br/>

        &lt;resolver:Dependency ref=&quot;myStoredId&quot; /&gt;  &amp;lt;!-- was &quot;computedID&quot; too --&gt;<br/>
 <br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1XMLObject&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

                name=&quot;urn:oid:1.3.6.1.4.1.5923.1.1.1.10&quot; /&gt;<br/>
 <br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2XMLObject&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

                name=&quot;urn:oid:1.3.6.1.4.1.5923.1.1.1.10&quot; friendlyName=&quot;eduPersonTargetedID&quot; /&gt;<br/>
    &lt;/resolver:AttributeDefinition&gt;<br/>
 &lt;/source&gt;</p>

<p>The persistent ID values for combinations of users and SP's will now be stored in the MySQL table which can be verified by doing a select all on the table. For our simple IdP this is a rather dubious value exercise, but it would have benefit on a real and large user base IdP, plus it was hard to figure out, so well worth recording here ;-)</p>

<p>====attribute-filter====<br/>
Finally, we need to ensure that all extracted attributes are encoded for sending to the relying SP. The &lt;code&gt;$IDP_HOME/conf/attribute-filter.xml&lt;/code&gt; file provides per-SP filtering with AND/OR logic. For the simple case, we create an AttributeFilterPolicy that passes all AAF mandatory attributes, plus the optional <em>locality</em> and <em>stateProvince</em> attributes to all SP's this way:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;AttributeFilterPolicy id=&quot;releaseToAnyone&quot;&gt;<br/>
        &lt;PolicyRequirementRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;AttributeRule attributeID=&quot;commonName&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;organizationName&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;surname&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;givenName&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;email&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;title&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;eduPersonAffiliation&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        &lt;AttributeRule attributeID=&quot;auEduPersonAffiliation&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

        <!-- although part of the standard distribution, exposing the user login names is questionable idea. --><br/>
        &lt;AttributeRule attributeID=&quot;eduPersonPrincipalName&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;/AttributeRule&gt;<br/>
        &lt;AttributeRule attributeID=&quot;eduPersonTargetedID&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;/AttributeRule&gt;<br/>
        &lt;AttributeRule attributeID=&quot;locality&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;/AttributeRule&gt;<br/>
        &lt;AttributeRule attributeID=&quot;stateProvince&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;/AttributeRule&gt;<br/>
        &lt;AttributeRule attributeID=&quot;displayName&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>

        &lt;/AttributeRule&gt;<br/>
    &lt;/AttributeFilterPolicy&gt;<br/>
 &lt;/source&gt;</p>

<p>Filtering stops after the first match. The provided default filter file includes a sample filter at the start that filters the legal values for <em>eduPersonAffiliation</em> to any of three distinct SP URL's. This means that even though we've included the attribute in our &quot;releaseToAnyone&quot; rule, as the attribute will match the (unidentified) rule, but be rejected as not being in the allowable SP URL PolicyRequirementRule, the value will be filtered out. If you want this attribute (a coarser-grained value for Affiliation than auEduPersonAffiliation), either add your SP URL to the list, or comment out/delete the rule all together.</p>

<p>====Adding ARCS Shared Token Support====<br/>
The auEduPersonSharedToken is a [[mandatory]] AAF attribute, but (obviously) cannot be provided &quot;out of the box&quot; in the IdP which is maintained by a non-Australian group. To generate it, we need a library available from ARCS, and some configuration. There are multiple references on how to do this on-line at ARCS, all of which have errors and omissions at the time this was written. The best of them is:</p>


<ul>
<li><a href="http://projects.arcs.org.au/trac/systems/wiki/HowTo/InstallIdP/IdP-Installation-CentOS5/IMAST-Installation">projects.arcs.org.au/trac/systems/wiki/HowTo/InstallIdP/IdP-Installation-CentOS5/IMAST-Installation</a></li>

</ul>

<p>Note that <strong>the ARCS jar requires IdP v 2.1.x</strong>. The notes below should be read in conjunction with the ARCS notes.</p>

<p>1. Obtain the ARCS Shared Token jar. This can be downloaded in binary, or built from source (best) using Maven. The end result will be a jar named &lt;code&gt;arcs-shibext-x.x.x.jar&lt;/code&gt; (where x.x.x is the version - 1.5.2 at the time of writing).</p>

<p>2. Copy the jar to the &lt;code&gt;lib&lt;/code&gt; directory of the unzipped IdP project that builds the IdP war file, and regenerate the IdP using the Ant script. Be sure to answer <strong>no</strong> to the &quot;is this a new installation&quot; question or the build will overwrite your config files!</p>

<p>3. Copy the newly regenerated war file from &lt;code&gt;$IDP_HOME/war&lt;/code&gt; to the tomcat &lt;code&gt;webapps&lt;/code&gt; directory.</p>

<p>4. Decide where you are going to persist the Shared Token values. We suggest mySQL as this allows you to easily inspect the values which can help in determining if all is well, and may help client side debug as well. The other possibility is LDAP.</p>

<p>5. Assuming mySQL for the storage, follow the ARCS instructions to create the tablespace, table, and a user (you could place it in the persistent-id tablespace and use the same user&amp;mdash;there are no clashes).</p>

<p>6. Edit the &lt;code&gt;$IDP_HOME/conf/attribute-resolver.xml&lt;/code&gt; file. Here is where ARCS doco is badly wrong. We need to add a Data Connector which uses non-standard attributes that are defined in a ARCS XSD schema&amp;mdash;hence they must be name-space qualified! So the resolver file needs the ANDS schema reference added to the schema locations, the new attribute definition, and the new data connector as shown below (note the all-important <strong>arcs:</strong> added to tell the parser who supplies certain non-standard identifiers!)</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    xsi:schemaLocation=&quot;urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd<br/>
    ...<br/>

                       urn:mace:arcs.org.au:shibboleth:2.0:resolver:dc classpath:/schema/arcs-shibext-dc.xsd&quot;&gt;<br/>
    ...<br/>
    &lt;resolver:AttributeDefinition id=&quot;auEduPersonSharedToken&quot; xsi:type=&quot;Simple&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:ad&quot;<br/>

              sourceAttributeID=&quot;auEduPersonSharedToken&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;sharedToken&quot; /&gt;<br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML1String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>

                  name=&quot;urn:mace:federation.org.au:attribute:auEduPersonSharedToken&quot; /&gt;<br/>
        &lt;resolver:AttributeEncoder xsi:type=&quot;SAML2String&quot; xmlns=&quot;urn:mace:shibboleth:2.0:attribute:encoder&quot;<br/>
                  name=&quot;urn:oid:1.3.6.1.4.1.27856.1.2.5&quot; friendlyName=&quot;auEduPersonSharedToken&quot; /&gt;<br/>

    &lt;/resolver:AttributeDefinition&gt;<br/>
    ...<br/>
    &lt;resolver:DataConnector xsi:type=&quot;arcs:SharedToken&quot; xmlns=&quot;urn:mace:shibboleth:2.0:resolver:dc&quot;<br/>

                            id=&quot;sharedToken&quot;<br/>
                            sourceAttributeID=&quot;uid&quot;<br/>
                            storeDatabase=&quot;true&quot;<br/>

                            salt=&quot;aFOtejE5Emlw+cxndlBWzglQjYpd0dfX+/jGS2Sky4k=&quot;&gt;<br/>
        &lt;resolver:Dependency ref=&quot;myLDAP&quot; /&gt;<br/>
        &lt;arcs:DatabaseConnection<br/>

            jdbcDriver=&quot;com.mysql.jdbc.Driver&quot;<br/>
            jdbcURL=&quot;jdbc:mysql://localhost:3306/imast?autoReconnect=true&quot;<br/>
            jdbcUserName=&quot;imast&quot;<br/>

            jdbcPassword=&quot;secret&quot;<br/>
            primaryKeyName=&quot;uid&quot; /&gt;<br/>
    &lt;/resolver:DataConnector&gt;<br/>

 &lt;/source&gt;</p>

<p>If you haven't already, add a new rule to the &lt;code&gt;$IDP_HOME/conf/attribute-filter.xml&lt;/code&gt; config to pass on the generated attribute:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>

        &lt;AttributeRule attributeID=&quot;auEduPersonSharedToken&quot;&gt;<br/>
            &lt;PermitValueRule xsi:type=&quot;basic:ANY&quot; /&gt;<br/>
        &lt;/AttributeRule&gt;<br/>

 &lt;/source&gt;</p>

<p>Now restart Tomcat to load the new configuration and authenticate through an SP. If you are using the phpinfo demonstration/test SP, you should see a new [Shib-AEP-SharedToken] attribute in the HTTP headers. Looking in the mySQL &lt;code&gt;tb_st&lt;/code&gt; table will show mapping of shared token values to user names, confirming it is being generated.</p>

<p>===Shibboleth (IdP side)===<br/>

The default home location for Shibboleth is &lt;code&gt;/etc/shibboleth&lt;/code&gt;. Configuration is required in &lt;code&gt;$SHIBD_HOME/shibboleth2.xml&lt;/code&gt;, &lt;code&gt;$SHIBD_HOME/attribute-map.xml&lt;/code&gt;, and &lt;code&gt;$SHIBD_HOME/attribute-policy.xml&lt;/code&gt;. The daemon should be restarted after making any changes.</p>

<p>A reasonable commentary on how the IdP attributes are assembled can be read at <a href="https://spaces.internet2.edu/display/SHIB2/IdPAddAttribute.">spaces.internet2.edu/display/SHIB2/IdPAddAttribute.</a></p>

<p>====shibboleth2.xml====<br/>
The daemon needs to know the location of the interface to the IdP. The de-commented section will look like the snippet below. The IdP URL has been configured into attributes of the ApplicationDefaults and SessionInitiator elements.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;ApplicationDefaults id=&quot;default&quot; policyId=&quot;default&quot;<br/>

        entityID=&quot;<a href="https://g709-0157.itee.uq.edu.au/idp/shibboleth">g709-0157.itee.uq.edu.au/idp/shibboleth</a>&quot;<br/>
        REMOTE_USER=&quot;eppn persistent-id targeted-id&quot;<br/>
        signing=&quot;false&quot; encryption=&quot;false&quot;&gt;<br/>

 <br/>
        &lt;Sessions lifetime=&quot;28800&quot; timeout=&quot;3600&quot; checkAddress=&quot;false&quot;<br/>
            handlerURL=&quot;/Shibboleth.sso&quot; handlerSSL=&quot;false&quot;<br/>

            exportLocation=&quot;<a href="http://localhost/Shibboleth.sso/GetAssertion">localhost/Shibboleth.sso/GetAssertion</a>&quot; exportACL=&quot;127.0.0.1&quot;<br/>
            idpHistory=&quot;false&quot; idpHistoryDays=&quot;7&quot;&gt;<br/>

 <br/>
            &lt;SessionInitiator type=&quot;Chaining&quot; Location=&quot;/Login&quot; isDefault=&quot;true&quot; id=&quot;Intranet&quot;<br/>
                    relayState=&quot;cookie&quot; entityID=&quot;<a href="https://g709-0157.itee.uq.edu.au/idp/shibboleth">g709-0157.itee.uq.edu.au/idp/shibboleth</a>&quot;&gt;<br/>

                &lt;SessionInitiator type=&quot;SAML2&quot; acsIndex=&quot;1&quot; template=&quot;bindingTemplate.html&quot;/&gt;<br/>
                &lt;SessionInitiator type=&quot;Shib1&quot; acsIndex=&quot;5&quot;/&gt;<br/>

            &lt;/SessionInitiator&gt;<br/>
            ...<br/>
        &lt;/Sessions&gt;<br/>
        ...<br/>

    &lt;/ApplicationDefaults&gt;<br/>
 &lt;/source&gt;</p>

<p>====attribute-map.xml====<br/>
This config file plays no part in the sending of attributes to the SP (VERIFY!!).</p>

<p>====attribute-policy.xml====<br/>
This config file plays no part in the sending of attributes to the SP (VERIFY!!).</p>

<p>===Shibboleth (SP side)===<br/>
====shibboleth2.xml====<br/>
On the SP side, the <em>shibd</em> needs a copy of the IdP metadata. The process might go like this:</p>

<p> &lt;source lang=&quot;bash&quot;&gt;<br/>
 $ rsync root@idp_host:/usr/local/idp/metadata/idp-metadata.xml /etc/shibboleth/<br/>
 &lt;/source&gt;</p>

<p>This file location must now be configured into the main <em>shibd</em> config file, &lt;code&gt;$SHIBD_HOME/shibboleth2.xml&lt;/code&gt;.</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>

    &lt;ApplicationDefaults id=&quot;default&quot; policyId=&quot;default&quot;<br/>
        entityID=&quot;<a href="https://redactor.itee.uq.edu.au/shibboleth">redactor.itee.uq.edu.au/shibboleth</a>&quot;<br/>

        REMOTE_USER=&quot;eppn persistent-id targeted-id&quot;<br/>
        signing=&quot;false&quot; encryption=&quot;false&quot;&gt;<br/>
 <br/>

       &lt;Sessions lifetime=&quot;28800&quot; timeout=&quot;3600&quot; checkAddress=&quot;false&quot;<br/>
            handlerURL=&quot;/Shibboleth.sso&quot; handlerSSL=&quot;false&quot;<br/>

            exportLocation=&quot;<a href="http://localhost/Shibboleth.sso/GetAssertion">localhost/Shibboleth.sso/GetAssertion</a>&quot; exportACL=&quot;127.0.0.1&quot;<br/>
            idpHistory=&quot;false&quot; idpHistoryDays=&quot;7&quot;&gt;<br/>

 <br/>
        ...<br/>
 <br/>
       &lt;MetadataProvider type=&quot;Chaining&quot;&gt;<br/>

            &lt;MetadataProvider type=&quot;XML&quot; uri=&quot;<a href="https://g709-0157.itee.uq.edu.au/idp/shibboleth">g709-0157.itee.uq.edu.au/idp/shibboleth</a>&quot;<br/>
                 backingFilePath=&quot;idp-metadata.xml&quot; reloadInterval=&quot;7200&quot;&gt;<br/>

               &lt;MetadataFilter type=&quot;Signature&quot; certificate=&quot;fedsigner.pem&quot;/&gt;<br/>
            &lt;/MetadataProvider&gt;<br/>
 <br/>

            ...<br/>
 <br/>
            &lt;MetadataProvider type=&quot;XML&quot; file=&quot;/etc/shibboleth/idp-metadata.xml&quot;/&gt;<br/>
 <br/>

       &lt;/MetadataProvider&gt;<br/>
 <br/>
       ...<br/>
 <br/>
    &lt;/ApplicationDefaults&gt;<br/>

 &lt;/source&gt;</p>

<p>====attribute-map.xml====<br/>
This file maps attributes provided by the IdP to the header names that will be associated with them when passed from SP to the service. For example, the attribute <em>eduPersonTargetedID</em> is remapped to <em>persistent-id</em>. As we don't want to alias our auEduPersonAffiliation, there's nothing to do here.</p>

<p>Should you want to remap an attribute, create Attribute elements for the OID and URN forms for SAML2 and SAML1 respectively:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>
    &lt;Attribute name=&quot;urn:oid:1.3.6.1.4.1.27856.1.2.1&quot; id=&quot;foobar&quot;/&gt;<br/>

    &lt;Attribute name=&quot;xurn:mace:dir:attribute-def:auEduPersonAffiliation&quot; id=&quot;foobar&quot;/&gt;<br/>
 &lt;/source&gt;</p>

<p>Most Shibboleth and IdP services today use SAML2 encoding so the URN form could be omitted. Use both if you want to feel safe.</p>

<p>====attribute-policy.xml====<br/>
Attributes must match a rule in the attribute-policy file in order to be forwarded. Advanced usage even allows the user themselves to veto release of attributes, but we want to send our <em>auEduPersonEntitlement</em> through, unmolested. The easiest way to do this is place a catch-all rule at the bottom of the file:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>

    &lt;afp:AttributeFilterPolicy&gt;<br/>
 <br/>
        ...<br/>
 <br/>
       &lt;afp:AttributeRule attributeID=&quot;*&quot;&gt;<br/>

           &lt;afp:PermitValueRule xsi:type=&quot;ANY&quot;/&gt;<br/>
       &lt;/afp:AttributeRule&gt;<br/>
 <br/>
    &lt;/afp:AttributeFilterPolicy&gt;<br/>

 &lt;/source&gt;</p>

<p>A more advanced policy might check for valid &quot;staff&quot; values per the controlled vocabulary as specified by CAUDIT, filtering out all &quot;students&quot;. To do this, we create a PermitValueRule and reference it from an explicit AttributeRule for the attribute name:</p>

<p> &lt;source lang=&quot;xml&quot;&gt;<br/>

    &lt;afp:PermitValueRule id=&quot;auEduPersonStaffAffiliationValues&quot; xsi:type=&quot;OR&quot;&gt;<br/>
        &lt;Rule xsi:type=&quot;AttributeValueString&quot; value=&quot;visiting-staff&quot;/&gt;<br/>

        &lt;Rule xsi:type=&quot;AttributeValueString&quot; value=&quot;emeritus-staff&quot;/&gt;<br/>
        &lt;Rule xsi:type=&quot;AttributeValueString&quot; value=&quot;contractor&quot;/&gt;<br/>

        &lt;Rule xsi:type=&quot;AttributeValueString&quot; value=&quot;physically-present&quot;/&gt; <br/>
    &lt;/afp:PermitValueRule&gt;<br/>
 <br/>

    ...<br/>
 <br/>
    &lt;afp:AttributeFilterPolicy&gt;<br/>
        ...<br/>
        &lt;afp:AttributeRule attributeID=&quot;auEduPersonAffiliation&quot;&gt;<br/>

            &lt;afp:PermitValueRuleReference ref=&quot;auEduPersonStaffAffiliationValues&quot;/&gt;<br/>
        &lt;/afp:AttributeRule&gt;<br/>
        ...<br/>
    &lt;/afp:AttributeFilterPolicy&gt;<br/>

 &lt;/source&gt;</p>

<p>==Problem Solving==<br/>
The log files for the IdP and <em>shibd</em>, together with the usual <em>httpd</em> and &lt;code&gt;$CATALINA_HOME/logs/catalina.out&lt;/code&gt; logs will generally provide enough information to diagnose &quot;why is it doing that?&quot; problems. The tricky ones are the type likely to be encountered during first deployment and startup; things like &quot;Connection Refused&quot;, and &quot;cannot connect to shibd process&quot; messages at the client rather than the SP, or IdP. The notes below may be useful.</p>

<p>===Connection Refused===<br/>
First check that the firewalls on SP and IdP are open to the required ports. By default these will be 80 and 443. Tomcat will probably be configured to use 8080, 8443 and 8009, but as their use is local to the IdP host, they do not need to be open to the outside world; likewise port 389 for LDAP. The entries below are taken from a Tomcat 6.6 &lt;code&gt;$CATALINA_HOME/conf/server.xml&lt;/code&gt; config file setup to run the IdP.</p>

<p> &lt;source lang=&quot;apache&quot;&gt;<br/>

   &lt;Connector port=&quot;8080&quot; protocol=&quot;HTTP/1.1&quot;<br/>
              connectionTimeout=&quot;20000&quot;<br/>
              redirectPort=&quot;8443&quot; /&gt;<br/>

 <br/>
   &lt;connector port=&quot;8443&quot;<br/>
              scheme=&quot;https&quot;<br/>
              secure=&quot;true&quot;<br/>

              clientAuth=&quot;true&quot;<br/>
              sslProtocol=&quot;TLS&quot;<br/>
              sslImplementation=&quot;edu.internet2.middleware.shibboleth.tomcat.DelegateToApplicationJSSEImplementation&quot;<br/>

              keystoreFile=&quot;/usr/local/idp/credentials/idp.jks&quot;<br/>
              keystorePass=&quot;secret&quot; /&gt;<br/>
 <br/>
   &lt;Connector port=&quot;8009&quot;<br/>

              enableLookups=&quot;false&quot;<br/>
              redirectPort=&quot;8443&quot; <br/>
              protocol=&quot;AJP/1.3&quot;<br/>

              request.tomcatAuthentication=&quot;false&quot; <br/>
              address=&quot;g709-0157.itee.uq.edu.au&quot; /&gt;<br/>
 &lt;/source&gt;</p>

<p>In this case, the IdP host is &quot;g709-0157.itee.uq.edu.au&quot;. In the default Tomcat server.xml, this will probably default to &quot;127.0.0.1&quot;. This has been observed as a source of &quot;connection refused&quot; problems. Use the fully qualified host name.</p>

<p>The corresponding config for Apache is done in &lt;code&gt;/etc/httpd/conf/httpd.conf&lt;/code&gt;:</p>

<p> &lt;source lang=&quot;dos&quot;&gt;</p>
<ol>
<li>httpd.conf setup to pass requests to Tomcat.</li>
</ol>

<p> ProxyPass /idp/ ajp://g709-0157.itee.uq.edu.au:8009/idp/<br/>
 &lt;/source&gt; </p>

<p>==Resources==<br/>
For convenience, configuration files for AAF complaint installations for the IdP and SP's can be downloaded using the links listed below.<br/>

Not wishing to instruct grandmothers on the fine art of egg-sucking, right-click and save-as. If you just click on the links, be sure to &quot;view source&quot; otherwise they may look rather messy.</p>

<p>===IdP Config files===</p>

<ul>
<li><a href="http:///maenad.itee.uq.edu.au/ron/relying-party.xml">/maenad.itee.uq.edu.au/ron/relying-party.xml</a></li>

<li><a href="http:///maenad.itee.uq.edu.au/ron/attribute-filter.xml">/maenad.itee.uq.edu.au/ron/attribute-filter.xml</a></li>
<li><a href="http:///maenad.itee.uq.edu.au/ron/attribute-resolver.xml">/maenad.itee.uq.edu.au/ron/attribute-resolver.xml</a></li>
</ul>

<p>===SP Config files===</p>

<ul>
<li><a href="http:///maenad.itee.uq.edu.au/ron/attribute-map.xml">/maenad.itee.uq.edu.au/ron/attribute-map.xml</a></li>
<li><a href="http:///maenad.itee.uq.edu.au/ron/attribute-policy.xml">/maenad.itee.uq.edu.au/ron/attribute-policy.xml</a></li>

</ul>

<p>[[Category:Software]]</p>