====== Shibboleth IdP ======
This section is split in two parts -- installation and configuration. Installation itself is trivial, takes minimum time and differences are very simple, for example, entering entity ID, etc. Configuration is, on the other hand, quite complex depending on particular needs such as whether using LDAP or Active Directory, etc.
===== IdP installation =====
Shibboleth IdP is installed by downloading [[https://shibboleth.net/downloads/identity-provider/3.2.1/|source code]], extracting it and running a shell script ''install.sh'' from within the extracted directory. Checking SHA256 fingerprints is highly recommended.
# Downloading Shibboleth IdP
mkdir -p /opt/src
chown -R idp:idp /opt/src
su idp
cd /opt/src
wget https://shibboleth.net/downloads/identity-provider/3.2.1/shibboleth-identity-provider-3.2.1.tar.gz \
https://shibboleth.net/downloads/identity-provider/3.2.1/shibboleth-identity-provider-3.2.1.tar.gz.asc \
https://shibboleth.net/downloads/identity-provider/3.2.1/shibboleth-identity-provider-3.2.1.tar.gz.sha256
# Checking SHA256 fingerprints
sha256sum shibboleth-identity-provider-3.2.1.tar.gz && cat shibboleth-identity-provider-3.2.1.tar.gz.sha256
# Checking GPG signature
# Importing key 07CEEB8B
gpg --keyserver hkp://keys.gnupg.net --search-keys 07CEEB8B
# Checking the signature
gpg --verify shibboleth-identity-provider-3.2.1.tar.gz.asc
#
# Run EXIT command to become 'root' user back again
#
exit
Now, with source code downloaded and checked, installation might proceed.
# Installing Shibboleth (as user root)
cd /opt
tar -xzf src/shibboleth-identity-provider-3.2.1.tar.gz
cd shibboleth-identity-provider-3.2.1/
./bin/install.sh
After running the installation script:
- accept source installation directory
- fill in server hostname (might be set correctly by default)
- accept entityID (or choosing a different one, for example, the one already existing [never change entityID after choosing one])
- enter organization scope
- enter two passwords asked for (''pwgen'' might help)
The output of the installation script ''install.sh'' might look like this:
$ ./bin/install.sh
Source (Distribution) Directory: [/opt/shibboleth-identity-provider-3.2.1]
Installation Directory: [/opt/shibboleth-idp]
Hostname: [localhost.localdomain]
whoami-dev.cesnet.cz
SAML EntityID: [https://whoami-dev.cesnet.cz/idp/shibboleth]
Attribute Scope: [localdomain]
cesnet.cz
TLS Private Key Password:
Re-enter password:
Cookie Encryption Key Password:
Re-enter password:
Warning: /opt/shibboleth-idp/bin does not exist.
Warning: /opt/shibboleth-idp/dist does not exist.
Warning: /opt/shibboleth-idp/doc does not exist.
Warning: /opt/shibboleth-idp/system does not exist.
Warning: /opt/shibboleth-idp/webapp does not exist.
Generating Signing Key, CN = whoami-dev.cesnet.cz URI = https://whoami-dev.cesnet.cz/idp/shibboleth ...
...done
Creating Encryption Key, CN = whoami-dev.cesnet.cz URI = https://whoami-dev.cesnet.cz/idp/shibboleth ...
...done
Creating TLS keystore, CN = whoami-dev.cesnet.cz URI = https://whoami-dev.cesnet.cz/idp/shibboleth ...
...done
Creating cookie encryption key files...
...done
Rebuilding /opt/shibboleth-idp/war/idp.war ...
...done
BUILD SUCCESSFUL
Total time: 1 minute 0 seconds
It is required to change the ownership of ''/opt/shibboleth-idp/'' and ''/opt/shibboleth-identity-provider-3.*/'' directories to the user ''idp'' belonging to the group ''idp''.
# Changing the ownership (as root user)
chown -R idp:idp /opt/shibboleth-id*
Restart Jetty to load Shibboleth IdP into the web server:
# Restarting Jetty
/etc/init.d/jetty restart
It is time to check Shibboleth IdP. The following test requires Jetty to listen on HTTP, i.e. port 80. Otherwise ''-u'' parameter is mandatory since default value is ''http://localhost/idp''.
# Shibboleth IdP status
cd /opt/shibboleth-idp/
./bin/status.sh
If everything is set correctly, the following output shall be seen:
### Operating Environment Information
operating_system: Linux
operating_system_version: 3.16.0-4-amd64
operating_system_architecture: amd64
jdk_version: 1.8.0_91
available_cores: 1
used_memory: 311 MB
maximum_memory: 958 MB
### Identity Provider Information
idp_version: 3.2.1
start_time: 2016-05-09T15:04:57+02:00
current_time: 2016-05-10T16:53:33+02:00
uptime: 92916009 ms
service: shibboleth.LoggingService
last successful reload attempt: 2016-05-09T13:03:48Z
last reload attempt: 2016-05-09T13:03:48Z
service: shibboleth.ReloadableAccessControlService
last successful reload attempt: 2016-05-09T13:03:55Z
last reload attempt: 2016-05-09T13:03:55Z
service: shibboleth.MetadataResolverService
last successful reload attempt: 2016-05-09T13:03:53Z
last reload attempt: 2016-05-09T13:03:53Z
metadata source: ShibbolethMetadata
last refresh attempt: 2016-05-10T14:48:57Z
last update: 2016-05-10T14:48:57Z
service: shibboleth.RelyingPartyResolverService
last successful reload attempt: 2016-05-09T13:03:53Z
last reload attempt: 2016-05-09T13:03:53Z
service: shibboleth.NameIdentifierGenerationService
last successful reload attempt: 2016-05-09T13:03:52Z
last reload attempt: 2016-05-09T13:03:52Z
service: shibboleth.AttributeResolverService
last successful reload attempt: 2016-05-09T13:03:50Z
last reload attempt: 2016-05-09T13:03:50Z
DataConnector myStoredId: has never failed
DataConnector myLDAPgroups: has never failed
DataConnector staticAttributes: has never failed
DataConnector myLDAP: has never failed
service: shibboleth.AttributeFilterService
last successful reload attempt: 2016-05-09T13:03:50Z
last reload attempt: 2016-05-09T13:03:50Z
Accessing ''https://HOSTNAME/idp'' is also possible, however, no useful information is displayed compared to ''status.sh'' script.
{{:cs:tech:idp:shib-no_service.png|}}
===== IdP configuration =====
Shibboleth IdP configuration might be very complex depending on particular needs and requirements of an organization. Here, just basic configuration is presented, but anyone should be able to modify it to meet any requirements.
//The guide is written in a step by step manner. Skipping parts of this guide might easily lead to misconfiguration.//
==== conf/access-control.xml ====
In this configuration file, IP ranges (or better just IP addresses) allowed to access the diagnostic page (''https://HOSTNAME/idp/status'') and other administrative features such as reloading particular configuration (metadata feeds, etc.) are defined.
//I recommend to allow just necessary IP addresses such as admin's workstation IP.//
# Edit access-control.xml
vi /opt/shibboleth-idp/conf/access-control.xml
In this example, ''1.2.3.4/32'' IPv4 address and ''2001:1:2:3::4/128'' IPv6 address are chosen. The addresses must be specified with the address mask.
p:allowedRanges="#{ {'127.0.0.1/32', '::1/128', '1.2.3.4/32', '2001:1:2:3::4:5/128'} }"
Shibboleth IdP configuration (Access Control List) should be reloaded in order to allow access from defined IP addresses.
# Reloading ACLs
cd /opt/shibboleth-idp
./bin/reload-service.sh -id shibboleth.ReloadableAccessControlService
Accessing the diagnostic page (''https://HOSTNAME/idp/status'') from the above defined IP addresses will display status information simlarly to ''status.sh'' shell script run from console earlier.
==== conf/ldap.properties ====
All the information related to LDAP connection are set in ''conf/ldap.properties'' configuration file.
# Edit ldap.properties
vi /opt/shibboleth-idp/conf/ldap.properties
The following options are the most important ones:
idp.authn.LDAP.authenticator = bindSearchAuthenticator
idp.authn.LDAP.ldapURL = ldaps://ldap1.example.org:636 \
ldaps://ldap2.example.org:636
idp.authn.LDAP.useStartTLS = false
idp.authn.LDAP.useSSL = true
idp.authn.LDAP.sslConfig = certificateTrust
idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt
idp.authn.LDAP.baseDN = ou=people,dc=example,dc=org
idp.authn.LDAP.subtreeSearch = true
idp.authn.LDAP.bindDN = uid=shibboleth,ou=users,dc=example,dc=org
idp.authn.LDAP.bindDNCredential = nejakeheslo
idp.attribute.resolver.LDAP.returnAttributes = givenName,sn,cn,o,schacHomeOrg,eduPersonPrincipalName,uid,mail
The first variable ''idp.authn.LDAP.authenticator'' specifies authentication strategy. If set to //bindSearchAuthenticator// Shibboleth will bind to LDAP. Default value is //anonSearchAuthenticator// for anonymous searching.
Option ''idp.authn.LDAP.ldapURL'' specifies LDAP server(s) to connect to. In the example above, IdP is set to connect to server ''ldap1.example.org'' and ''ldap2.example.org''. Connection is secured by SSL on the standard port ''636''.
//ldapURL comment:// There must not be a slash (/) at the end of the ldapURL such as ''[[ldaps://ldap1.example.org:636/]]''! In that case, Shibboleth will not start and output an error ''java.lang.NumberFormatException: For input string: "636/".'' to its log file.
Configuration options ''idp.authn.LDAP.useStartTLS'' and ''idp.authn.LDAP.useSSL'' define SSL usage instead of TLS. The following option ''idp.authn.LDAP.trustCertificates'' contains path to a certificate.
Finally, ''idp.authn.LDAP.baseDN'' sets so called "base DN" in an LDAP directory, ''idp.authn.LDAP.bindDN'' and ''idp.authn.LDAP.bindDNCredential'' define username and password used for accessing LDAP directory when asking for users' attributes.
==== conf/metadata-providers.xml ====
Metadata sources are defined in ''conf/metadata-providers.xml'' configuration file. In the following example, a production federation eduID.cz is used. Metadata is downloaded and saved locally.
# Editing metadata-providers.xml
vi /opt/shibboleth-idp/conf/metadata-providers.xml
//Code block stated above (element ) has to be put inside the element in ''metadata-providers.xml'' configuration file otherwise it will not work. A valid XML file has to contain only ONE root element.//
Description of individual [[https://wiki.shibboleth.net/confluence/display/IDP30/HTTPMetadataProviders|]] element's attributes follows:
* id -- metadata provider identifier (used for logging, etc.)
* xsi:type -- defines the type of the plugin used for metadata reading
* backingFile -- specifies the file for local metadata cache
* metadataURL -- source URL address
* [[https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration#MetadataConfiguration-AttributesAttributes|maxRefreshDelay]] -- upper bound on the next refresh
Metadata is valid only for specific time and then it is invalid, which means untrustworthy and not usable. The default reaload interval is set to 4 hours. You can tweak it using [[https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration#MetadataConfiguration-AttributesAttributes|maxRefreshDelay]] element of [[https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration|]] as shown above.
If federation metadata is not digitally signed '''' is meaningless. However, production federation should definitelly sign metadata and entities within the federation should definitelly validate the signature.
To reload federation metadata manually, just run these commands:
# Reloading federation metadata
cd /opt/shibboleth-idp
./bin/reload-service.sh -id shibboleth.MetadataResolverService
In the metadata directory (''/opt/shibboleth-idp/metadata/'') a cached federation metadata should be available:
# Listing downloaded metadata
ls -1 metadata/
# Downloaded metadata
eduidcz.xml
idp-metadata.xml
==== conf/attribute-resolver.xml ====
Users' attributes will be obtained from an LDAP server. As a basic for such configuration it is wise to take an take advantage of the prepared configuration file ''attribute-resolver-ldap.xml'' which contains an LDAP connector. The original file ''attribute-resolver.xml'' can be safely overwritten as it will not be needed anymore.
# Preparing attribute-resolver.xml
cd /opt/shibboleth-idp/conf
cp attribute-resolver-ldap.xml attribute-resolver.xml
vi attribute-resolver.xml
Following attributes are user-specific and are to be obtained from an LDAP server. There is no need to specify "scope" for ''eduPersonPrincipalName'' since it is loaded from ''idp.properties'' configuration file. The scope is defined during Shibboleth IdP installation
''o'' (organization name) and ''schacHomeOrg'' attributes are so called static. That means they are the same for every single user. It does not make sense to store them in an LDAP, but to have it defined statically.
Attributes received from an LDAP server employs ''myLDAP'' connector. All the information for the LDAP have been already set in the configuration file ''conf/ldap.properties''. Static attributes are obtained from static data connector:
EXAMPLE, Ltd.
example.org
==== conf/attribute-filter.xml ====
After defining attributes it is needed to specify which ones will be released to service providers. This is defined in ''conf/attribute-filter.xml'' configuration file.
# Editing attribute-filter.xml
vi /opt/shibboleth-idp/conf/attribute-filter.xml
There are three different policies. One can release attributes to:
* any service
* a group of services (''groupID'', for example to a federation)
* a specific service (''entityID'')
The following code releases ''givenName'', ''sn'', ''cn'' and ''o'' attributes for any service available in the federation.
The following example releases ''givenName'', ''sn'', ''cn'', ''o'' and ''schacHomeOrg'' to a group of services identified as ''https://example.org/metadata''.
The last example releases attributes to a specific service identified by ''https://www.myservice.org'' entitiyID. The code releases ''givenName'', ''sn'', ''cn'', ''o'', ''schacHomeOrg'', ''eduPersonPrincipalName'', ''uid'' and ''mail'', so every single attribute we have defined earlier.
==== metadata/idp-metadata.xml ====
Identity Provider's metadata (''metadata/idp-metadata.xml'') contains information about "endpoints" (where to connect for authentization, etc.), however, it should always also include some non-technical/administration information such as '''' element inside '''' element as follows:
# Editing idp-metadata.xml
vi /opt/shibboleth-idp/metadata/idp-metadata.xml
example.org
ORGANIZATION
ORGANIZACE
Identity Provider for ORGANIZATION employees.
Identity Provider pro zaměstnance ORGANIZACE.
http://www.example.org/en/
http://www.example.org/cs/
https://img.example.org/logo-200.gif
https://img.example.org/logo-400.gif
https://img.example.org/logo-800.gif
There should also be specified the organization's name in '''' element within '''' element:
Organization
Organizace
ORGANIZATION
ORGANIZACE
http://www.example.org/en/
http://www.example.org/cs/
The last thing is a technical contact person, including e-mail address, specified within '''' element. It might put right after '''' element:
GivenName
Surname
mailto:firtname.lastname@example.org
Complete metadata of CESNET's IdP is available at https://whoami.cesnet.cz/idp/shibboleth address.
==== Login page customisation ====
The default login page looks similarly to the following screenshot.
{{:cs:tech:idp:shib-loginpage-default.png|Default login page appearance.}}
It is possible to tweak the appearance. All the modifications are made in ''/opt/shibboleth-idp/edit-webapp/'' directory. This directory is not overwritten after upgrading Shibboleth IdP installation, so there is no need to be affraid of loosing modifications.
When done with tweaking the web appearance, a new ''idp.war'' file has to be build and Jetty restarted using the following commands:
# Rebuilding idp.war
cd /opt/shibboleth-idp
./bin/build.sh
# Restarting Jetty
service jetty restart
# Rebuilding idp.war and restarting Jetty terminal output
Installation Directory: [/opt/shibboleth-idp]
Rebuilding /opt/shibboleth-idp/war/idp.war ...
...done
BUILD SUCCESSFUL
Total time: 3 seconds
Stopping Jetty: OK
Starting Jetty: . . . . . . . . . . . . OK Tue Aug 11 13:15:19 CEST 2015
===== Adding metadata to a federation =====
To be a part of a federation, IdP's metadata has to be added into a federation metadata. Depending on the federation, metadata is registered using web-based management system or sent to the federation operator via email.
===== Startup and testing =====
Now, everything should be set properly and ready to test. If Jetty is not started yet, now it is the right time to run it:
# Starting Jetty
service jetty start
If Jetty is already running, but any configuration changes have been made like customizing login web page, restart should take place now. Restarting Jetty also verifies that everything works correctly and starts as expected after operating system reboot:
# Restarting Jetty
service jetty restart
Everything should be set correctly and run smoothly, thus it is time to test it out using any service within the federation the IdP is now a part of.