INSTALLATION MANUAL DISCLAIMER: The information contained in this manual is subject to change by INFED Team without any prior notice. INFED gives no warranty of any kind whatsoever, either explicitly or implicitly. It is created for the purpose of assisting the Institution in more easily adopting the use of the INFED. Make clear that the guidance are offered without warranty, and disclaiming liability for damages resulting from using the guide.
Shibboleth Identity Provider (IdP) - Installation Guide
For the Shibboleth IdP version 4, INFED recommends relying on an enterprise-grade Linux distribution with long term support: specifically, either Ubuntu Server LTS or Red Hat Enterprise Linux / CentOS.
- size: 80x60 px (or other that respect the aspect-ratio)
- format: PNG
- style: with a transparent background
- size: 16x16 px (or other that respect the aspect-ratio)
- format: PNG
- style: with a transparent background
Please remember to replace all occurencences of the
yourdomain.ac.in
value with
the IdP domain name and
idp.yourdomain.ac.in
value with the Full Qualified
Name of the Identity Provider.
sudo su -
(It will return something like this
"
There is only one alternative in link group java (providing /usr/bin/java):
"
)
sudo su -
(
ATTENTION
: Replace
idp.yourdomain.ac.in
with your IdP Full
Qualified Domain Name and
< HOSTNAME >
with the IdP hostname)
vim /etc/hosts
hostnamectl set-hostname <HOSTNAME >
JAVA_HOME
in
/etc/environment
The Identity Provider (IdP) is responsible for user authentication and providing user information to the Service Provider (SP). It is located at the home organization, which is the organization which maintains the user\'s account. It is a Java Web Application that can be deployed with its WAR file.
sudo su -
cd /usr/local/src
wget http://shibboleth.net/downloads/identity-provider/4.1.4/shibboleth-identity-provider-4.1.4.tar.gz
tar -xzf shibboleth-identity-provider-4.*.tar.gz
install.sh:
cd /usr/local/src/shibboleth-identity-provider-4.*/bin
bash install.sh -Didp.host.name=$(hostname -f) -Didp.keysize=3072
ATTENTION: Replace the default value of \'Attribute Scope\' with the domain name of your institution.
Buildfile: /usr/local/src/shibboleth-identity-provider-4.1.4/bin/build.xml
install:
Source (Distribution) Directory (press
<
enter
>
to accept default):
[/usr/local/src/shibboleth-identity-provider-4.1.4]
?
Installation Directory: [/opt/shibboleth-idp]
?
Backchannel PKCS12 Password: ###PASSWORD-FOR-BACKCHANNEL###
Re-enter password:
###PASSWORD-FOR-BACKCHANNEL###
Cookie Encryption Key Password: ###PASSWORD-FOR-COOKIE-ENCRYPTION###
Re-enter password:
###PASSWORD-FOR-COOKIE-ENCRYPTION###
SAML EntityID: [https://idp.yourdomain.ac.in/idp/shibboleth]
?
Attribute Scope: [yourdomain.ac.in]
?
By starting from this point, the variable idp.home refers to the directory:
/opt/shibboleth-idp
Save the
###PASSWORD-FOR-BACKCHANNEL###
value somewhere to be able to
find it when you need it.
The
###PASSWORD-FOR-COOKIE-ENCRYPTION###
will be saved into
/opt/shibboleth-idp/credentials/secrets.properties
as
idp.sealer.storePassword
and
idp.sealer.keyPassword
value.
Jetty is a Web server and a Java Servlet container. It will be used to run the IdP application through its WAR file.
sudo su -
jetty-src
folder as a symbolic link. It will be useful for
future Jetty updates:
jetty
that can run the web server (without home
directory):
service jetty check
(Jetty NOT running)
service jetty start
service jetty check
(Jetty running pid=XXXX)
If you receive an error likes " Job for jetty.service failed because the control process exited with error code. See "systemctl status jetty.service" and "journalctl -xe" for details. ", try this:
rm /var/run/jetty.pid
systemctl start jetty.service
sudo su -
systemctl restart jetty.service
The Apache HTTP Server will be configured as a reverse proxy and it will be used for SSL offloading.
sudo su -
/etc/ssl/certs
/etc/ssl/private
/etc/ssl/certs
(
$(hostname -f)
will provide your IdP Full Qualified Domain Name)
https://idp.example.org/idp/shibboleth
Shibboleth Documentation reference: https://wiki.shibboleth.net/confluence/display/IDP4/StorageConfiguration
The IdP provides a number of general-purpose storage facilities that can be used by core subsystems like session management and consent.
The HTML Local Storage requires JavaScript be enabled because reading and writing to the client requires an explicit page be rendered. Note that this feature is safe to enable globally. The implementation is written to check for this capability in each client, and to back off to cookies. The default configuration generates encrypted assertions that a large percentage of non-Shibboleth SPs are going to be unable to decrypt, resulting a wide variety of failures and error messages. Some old Shibboleth SPs or software running on old Operating Systems will also fail to work.
If you don\'t change anything, the IdP stores data in a browser session cookie or HTML local storage and encrypt his assertions with AES-GCM encryption algorithm.
See the configuration files and the Shibboleth documentation for details.
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure the Directory (openLDAP or AD) Connection
This Storage service will memorize User Consent data on persistent database SQL.
sudo su -
vim /root/.my.cnf
StorageRecords
table on
storageservice
database:
shib-ss-db.sql
before import
and add the following directives to the tail, just before the last
</beans>
tag:
<!-- DB-independent Configuration -->
<bean
id
="storageservice.JPAStorageService"
class
="org.opensaml.storage.impl.JPAStorageService"
p:cleanupInterval
="%{idp.storage.cleanupInterval:PT10M}"
c:factory-ref
="storageservice.JPAStorageService.EntityManagerFactory"/>
<bean
id
="storageservice.JPAStorageService.EntityManagerFactory"
class
="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property
name
="packagesToScan"
value
="org.opensaml.storage.impl"/>
<property
name
="dataSource"
ref
="storageservice.JPAStorageService.DataSource"/>
<property
name
="jpaVendorAdapter"
ref
="storageservice.JPAStorageService.JPAVendorAdapter"/>
<property
name
="jpaDialect">
<bean
class
="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<!-- DB-dependent Configuration -->
<bean
id
="storageservice.JPAStorageService.JPAVendorAdapter"
class
="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property
name
="database"
value
="MYSQL" />
</bean>
<!-- Bean to store IdP data unrelated with persistent
identifiers on \'storageservice\' database -->
<bean id="storageservice.JPAStorageService.DataSource"
class
="org.apache.commons.dbcp.BasicDataSource"
destroy-method
="close"
lazy-init
="true"
p:driverClassName
="org.mariadb.jdbc.Driver"
p:url
="jdbc:mysql://localhost:3306/storageservice?autoReconnect=true"
p:username
="###_SS-USERNAME-CHANGEME_###"
p:password
="###_SS-DB-USER-PASSWORD-CHANGEME_###"
p:maxActive
="10"
p:maxIdle
="5"
p:maxWait
="15000"
p:testOnBorrow
="true"
p:validationQuery
="select 1"
p:validationQueryTimeout
="5" />
remember to change "
###_SS-USERNAME-CHANGEME_###
" and
"
###_SS-DB-USER-PASSWORD-CHANGEME_###
" with your DB user and password data
vim /opt/shibboleth-idp/conf/idp.properties
Proceed with Configure the Directory (openLDAP or AD) Connection
sudo su -
ldap-utils
package:
-
slapcat | grep dn
the baseDN (
-b
parameter)
==>
ou=people,dc=yourdomain,dc=ac,dc=in
(branch containing the
registered users)
the bindDN (
-D
parameter) ==>
cn=idpuser,ou=system,dc=yourdomain,dc=ac,dc=in
(distinguished name for
the user that can made queries on the LDAP)
-
(uid=
==
(uid=$resolutionContext.principal)
searchFilter into
conf/ldap.properties
file
(sAMAccountName=
==>
(sAMAccountName=$resolutionContext.principal)
searchFilter
(
conf/ldap.properties
)
- Solution 1 - LDAP + STARTTLS:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldap://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= true
idp.authn.LDAP.sslConfig
= certificateTrust
idp.authn.LDAP.trustCertificates
=
%{idp.home}/credentials/ldap-server.crt
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
ou
=people,
dc
=yourdomain,
dc
=ac,
dc
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
cn
=idpuser,
ou
=system,
dc
=yourdomain,
dc
=ac,
dc
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
uid
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
uid
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
- Solution 2 - LDAP + TLS:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=
%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldaps://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= false
idp.authn.LDAP.sslConfig
= certificateTrust
idp.authn.LDAP.trustCertificates
=
%{idp.home}/credentials/ldap-server.crt
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
ou
=people,
dc
=yourdomain,
dc
=ac,
dc
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
cn
=idpuser,
ou
=system,
dc
=yourdomain,
dc
=ac,
dc
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
uid
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
uid
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
- Solution 3 - plain LDAP:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=
%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldap://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= false
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
ou
=people,
dc
=yourdomain,
dc
=ac,
dc
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
cn
=idpuser,
ou
=system,
dc
=yourdomain,
dc
=ac,
dc
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
uid
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
uid
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
- Solution 1 - AD + STARTTLS:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldap://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= true
idp.authn.LDAP.sslConfig
= certificateTrust
idp.authn.LDAP.trustCertificates
=
%{idp.home}/credentials/ldap-server.crt
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
CN
=Users,
DC
=ad,
DC
=yourdomain,
DC
=ac,
DC
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
CN
=idpuser,
CN
=Users,
DC
=ad,
DC
=system,
DC
=yourdomain,
DC
=ac,
DC
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
sAMAccountName
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
sAMAccountName
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
- Solution 2 - AD + TLS:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=
%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldaps://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= false
idp.authn.LDAP.sslConfig
= certificateTrust
idp.authn.LDAP.trustCertificates
=
%{idp.home}/credentials/ldap-server.crt
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
CN
=Users,
DC
=ad,
DC
=yourdomain,
DC
=ac,
DC
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
CN
=idpuser,
CN
=Users,
DC
=ad,
DC
=system,
DC
=yourdomain,
DC
=ac,
DC
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
sAMAccountName
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
sAMAccountName
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
- Solution 3 - plain AD:
vim /opt/shibboleth-idp/credentials/secrets.properties
# Default access to LDAP authn and attribute stores.
idp.authn.LDAP.bindDNCredential
=
###IDPUSER_PASSWORD###
idp.attribute.resolver.LDAP.bindDNCredential
=
%{idp.authn.LDAP.bindDNCredential:undefined}
vim /opt/shibboleth-idp/conf/ldap.properties
The
ldap.yourdomain.ac.in
have to be replaced with the FQDN of the LDAP
server.
The
idp.authn.LDAP.baseDN
and
idp.authn.LDAP.bindDN
have to be
replaced with the right value.
The
idp.attribute.resolver.LDAP.exportAttributes
list MUST contains the
attribute chosen for the persistent-id generation
(idp.persistentId.sourceAttribute)
idp.authn.LDAP.authenticator
=
bindSearchAuthenticator
idp.authn.LDAP.ldapURL
=
ldap://ldap.yourdomain.ac.in
idp.authn.LDAP.useStartTLS
= false
# List of attributes to request during authentication
idp.authn.LDAP.returnAttributes
=
passwordExpirationTime,loginGraceRemaining
idp.authn.LDAP.baseDN
=
CN
=Users,
DC
=ad,
DC
=yourdomain,
DC
=ac,
DC
=in
idp.authn.LDAP.subtreeSearch
= false
idp.authn.LDAP.bindDN
=
CN
=idpuser,
CN
=Users,
DC
=ad,
DC
=system,
DC
=yourdomain,
DC
=ac,
DC
=in
# The userFilter is used to locate a directory entry to
bind against for LDAP authentication.
idp.authn.LDAP.userFilter
= (
sAMAccountName
={user})
# LDAP attribute configuration, see
attribute-resolver.xml
# Note, this likely won\'t apply to the use of legacy V2
resolver configurations
idp.attribute.resolver.LDAP.ldapURL
=
%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout
=
%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout
=
%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN
=
%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN
=
%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS
=
%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates
=
%{idp.authn.LDAP.trustCertificates:undefined}
# The searchFilter is used to find user attributes from
an LDAP source
idp.attribute.resolver.LDAP.searchFilter
= (
sAMAccountName
=$resolutionContext.principal)
# # List of attributes produced by the Data Connector
that should be directly exported as resolved IdPAttributes without requiring any
<AttributeDefinition>
idp.attribute.resolver.LDAP.exportAttributes
=
### List space-separated of attributes to retrieve
directly from the directory ###
Paste the content of OpenLDAP certificate into
/opt/shibboleth-idp/credentials/ldap-server.crt
Configure the right owner/group with:
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure Shibboleth Identity Provider to release the persistent NameID
Shibboleth Documentation reference: https://wiki.shibboleth.net/confluence/display/IDP4/PersistentNameIDGenerationConfiguration
SAML 2.0 (but not SAML 1.x) defines a kind of NameID called a "persistent" identifier that
every SP receives for the IdP users. This part will teach you how to release the
"persistent" identifiers with a database (Stored Mode) or without it (Computed Mode).
By default, a transient NameID will always be released to the Service Provider if the
persistent one is not requested.
sudo su -
persistent-id
with:
vim /opt/shibboleth-idp/conf/saml-nameid.properties
The
sourceAttribute
MUST be an attribute, or a list of comma-separated
attributes, that uniquely identify the subject of the generated
persistent-id
.
The
sourceAttribute
MUST be
Stable
,
Permanent
and
Not-reassignable
attribute.
# ... other things ...#
# OpenLDAP has the UserID into "uid" attribute
idp.persistentId.sourceAttribute
= uid
# Active Directory has the UserID into "sAMAccountName"
#idp.persistentId.sourceAttribute = sAMAccountName
# ... other things ...#
# BASE64 will match Shibboleth V2 values, we recommend
BASE32 encoding for new installs.
idp.persistentId.encoding
= BASE32
idp.persistentId.generator
=
shibboleth.ComputedPersistentIdGenerator
vim /opt/shibboleth-idp/conf/saml-nameid.xml
<ref bean="shibboleth.SAML2PersistentGenerator" />
vim /opt/shibboleth-idp/credentials/secrets.properties
Restart Jetty to apply the
changes:
systemctl restart jetty.service
Check IdP Status:
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure the attribute resolver (sample)
sudo su -
vim /root/.my.cnf
shibpid
table on
shibboleth
database:
shib-pid-db.sql
before import
and add the following directives to the tail, just before the last
</beans>
tag:
<!-- Bean to store persistent-id on \'shibboleth \'
database -->
<bean
id
="MyDataSource"
class
="org.apache.commons.dbcp.BasicDataSource"
destroy-method
="close"
lazy-init
="true"
p:driverClassName
="org.mariadb.jdbc.Driver"
p:url
="jdbc:mysql://localhost:3306/shibboleth?autoReconnect=true"
p:username
="###_SHIB-USERNAME-CHANGEME_###"
p:password
="###_SHIB-DB-USER-PASSWORD-CHANGEME_###"
p:maxActive
="10"
p:maxIdle
="5"
p:maxWait
="15000"
p:testOnBorrow
="true"
p:validationQuery
="select 1"
p:validationQueryTimeout
="5" />
remember to change "
###_SHIB-USERNAME-CHANGEME_###
" and
"
###_SHIB-DB-USER-PASSWORD-CHANGEME_###
" with your DB user and password
data
persistent-id :
vim /opt/shibboleth-idp/conf/saml-nameid.properties
The
sourceAttribute
MUST be an attribute, or a list of comma-separated
attributes, that uniquely identify the subject of the generated
persistent-id
.
The sourceAttribute MUST be Stable , Permanent and Not-reassignable attribute.
# ... other things ...#
# OpenLDAP has the UserID into "uid" attribute
idp.persistentId.sourceAttribute
= uid
# Active Directory has the UserID into "sAMAccountName"
#idp.persistentId.sourceAttribute = sAMAccountName
# BASE64 will match Shibboleth V2 values, we recommend
BASE32 encoding for new installs.
idp.persistentId.encoding
= BASE32
# ... other things ...#
idp.persistentId.generator
=
shibboleth.ComputedPersistentIdGenerator
# ... other things ...#
idp.persistentId.dataSource
= MyDataSource
# ... other things ...#
vim /opt/shibboleth-idp/credentials/secrets.properties
-
vim /opt/shibboleth-idp/conf/saml-nameid.xml
- Uncomment the line:
<ref bean="shibboleth.SAML2PersistentGenerator" />
-
vim /opt/shibboleth-idp/conf/c14n/subject-c14n.xml
- Uncomment the line:
<ref bean="c14n/SAML2Persistent" />
- (OPTIONAL)
vim /opt/shibboleth-idp/conf/c14n/subject-c14n.properties
Transform each letter of username, before storing in into the database, to Lowercase or Uppercase by setting the proper constant:
# Simple username -> principal name c14n
idp.c14n.simple.lowercase = true
#idp.c14n.simple.uppercase = false
idp.c14n.simple.trim = true
systemctl restart jetty.service
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure the attribute resolver (sample)
The attribute resolver contains attribute definitions and data connectors that collect information from a variety of sources, combine and transform it, and produce a final collection of IdPAttribute objects, which are an internal representation of user data not specific to SAML or any other supported identity protocol.
If you decide to use the Solutions plain LDAP/AD, remove or comment the following directives from your Attribute Resolver file:
Line 1: useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
Line 2: trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}"
Configure the right owner:
chown jetty /opt/shibboleth-idp/conf/attribute-resolver.xml
systemctl restart jetty.service
bash /opt/shibboleth-idp/bin/status.sh
eduPersonTargetedID is an abstracted version of the SAML V2.0 Name Identifier format of
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent".
To be able to follow these steps,
you need to have followed the previous steps on "persistent" NameID generation.
<AttributeDefinition>
and the
<DataConnector>
into the
attribute-resolver.xml
vim /opt/shibboleth-idp/conf/attribute-resolver.xml
<!-- ... other things ...-->
<!--AttributeDefinition for eduPersonTargetedID -
Computed Mode -->
<AttributeDefinition
xsi:type
= "SAML2NameID"
nameIdFormat
=
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
id
="eduPersonTargetedID">
<InputDataConnector
ref
="computed"
attributeNames
="computedId" />
</AttributeDefinition>
<!-- ... other things ...-->
<!-- Data Connector for eduPersonTargetedID -
Computed Mode -->
<DataConnector
id
="computed"
xsi:type
="ComputedId"
generatedAttributeID
="computedId"
salt
="%{idp.persistentId.salt}"
algorithm
="%{idp.persistentId.algorithm:SHA}"
encoding
="%{idp.persistentId.encoding:BASE32}">
<InputDataConnector
ref
="myLDAP"
attributeNames
="%{idp.persistentId.sourceAttribute}"
/>
</DataConnector>
eduPersonTargetedID.properties
file:
chown jetty:root /opt/shibboleth-idp/conf/attributes/custom/eduPersonTargetedID.properties
systemctl restart jetty.service
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure the attribute resolution with Attribute Registry
<AttributeDefinition>
and the
<DataConnector>
into the
attribute-resolver.xml
vim /opt/shibboleth-idp/conf/attribute-resolver.xml
<!-- ... other things ... -->
<!--AttributeDefinition for eduPersonTargetedID -
Stored Mode -->
<AttributeDefinition
xsi:type
= "SAML2NameID"
nameIdFormat
=
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
id
="eduPersonTargetedID">
<InputDataConnector
ref
="stored"
attributeNames
="storedId" />
</AttributeDefinition>
<!-- ... other things ... -->
<!-- Data Connector for eduPersonTargetedID -
Computed Mode -->
<DataConnector
id
="stored"
xsi:type
="StoredId"
generatedAttributeID
="storedId"
salt
="%{idp.persistentId.salt}"
queryTimeout
="0">
<InputDataConnector
ref
="myLDAP"
attributeNames
="%{idp.persistentId.sourceAttribute}"
/>
<BeanManagedConnection>MyDataSource</BeanManagedConnection>
</DataConnector>
eduPersonTargetedID.properties
file:
chown jetty:root /opt/shibboleth-idp/conf/attributes/custom/eduPersonTargetedID.properties
systemctl restart jetty.service
bash /opt/shibboleth-idp/bin/status.sh
Proceed with Configure the attribute resolution with Attribute Registry
File(s):
conf/attribute-registry.xml
,
conf/attributes/default-rules.xml
,
conf/attribute-resolver.xml
,
conf/attributes/custom/
sudo su -
schac.xml
into the right location:
chown jetty:root /opt/shibboleth-idp/conf/attributes/schac.xml
default-rules.xml
to include the new
schac.xml
file
in the list:
vim /opt/shibboleth-idp/conf/attributes/default-rules.xml
<!-- ... other things ... -->
<import
resource
="inetOrgPerson.xml" />
<import
resource
="eduPerson.xml" />
<import
resource
="eduCourse.xml" />
<import
resource
="samlSubject.xml" />
<import
resource
="schac.xml" />
</beans>
Enrich IDP logs with the authentication error occurred on LDAP:
Translate the IdP messages in your language:
messages_XX.properties
\' downloaded file into
/opt/shibboleth-idp/messages
directory
systemctl restart jetty.service
The
<AttributeAuthorityDescriptor>
role is needed ONLY IF you have SPs
that use AttributeQuery to request attributes to your IdP.
Shibboleth documentation
reference:
https://wiki.shibboleth.net/confluence/display/IDP4/SecurityAndNetworking#SecurityAndNetworking-AttributeQuery
vim /opt/shibboleth-idp/metadata/idp-metadata.xml
- Remove completely the initial default comment
<EntityDescriptor> Section:
- Remove `validUntil` XML attribute.
<IDPSSODescriptor> Section:
- Remove completely the comment containing <mdui:UIInfo>.
You will add it on the "IDEM Entity Registry", the web application provided by
the IDEM GARR AAI to manage metadata.
- Remove the endpoint:
<ArtifactResolutionService
Binding
="urn:oasis:names:tc:SAML:1.0:bindings:SOAP- binding"
Location
="https://idp.example.org:8443/idp/profile/SAML1/SOAP/ArtifactResolution"
index="1"/>
(and modify the index value of the next one to "1")
- Remove comment from SingleLogoutService endpoints
- Between the last <SingleLogoutService> and the first
<SingleSignOnService> endpoints add these 2 lines:
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
(because the IdP installed with this guide will release transient NameID, by
default, and persistent NameID if requested.)
- Remove the endpoint:
<SingleSignOnService
Binding
="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
Location
="https://idp.example.org/idp/profile/Shibboleth /SSO"/>
- Remove all ":8443" from the existing URL (such port is not used
anymore)
<AttributeAuthorityDescriptor> Section (Remember what was said at the
beginning of this section):
- From the list "protocolSupportEnumeration" replace the value:
- urn:oasis:names:tc:SAML:1.1:protocol
with:
- urn:oasis:names:tc:SAML:2.0:protocol
- Uncomment:
<AttributeService
Binding
="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
Location
="https://idp.example.org/idp/profile/SAML2 /SOAP/AttributeQuery"/>
- Remove the endpoint:
<AttributeService
Binding
="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-xbinding"
Location
="https://idp.example.org:8443/idp/profile
/SAML1/SOAP/AttributeQuery"/>
- Remove the comment starting with "If you uncomment..."
- Remove all ":8443" from the existing URL (such port is not used anymore)
Shibboleth Documentation reference: https://wiki.shibboleth.net/confluence/display/IDP4/SecretKeyManagement
The default configuration of the IdP relies on a component called a "DataSealer" which in turn uses an AES secret key to secure cookies and certain other data for the IdPs own use. This key must never be shared with anybody else, and must be copied to every server node making up a cluster. The Java "JCEKS" keystore file stores secret keys instead of public/private keys and certificates and a parallel file tracks the key version number.
These instructions will regularly update the secret key (and increase its version) and provide you the capability to push it to cluster nodes and continually maintain the secrecy of the key.
updateIDPsecrets.sh
into the right location:
sudo chmod +x /opt/shibboleth-idp/bin/updateIDPsecrets.sh
sudo vim /etc/cron.daily/updateIDPsecrets
#!/bin/bash
/opt/shibboleth-idp/bin/updateIDPsecrets.sh
sudo chmod +x /etc/cron.daily/updateIDPsecrets
sudo run-parts --test /etc/cron.daily
conf/idp.properties
if you need
to set different values than defaults:
idp.sealer._count
- Number of earlier keys to keep (default 30)
idp.sealer._sync_hosts
- Space separated list of hosts to scp the sealer
files to (default generate locally)
Follow these steps ONLY IF your organization is connected to the GARR Network
sudo su-
tmp/httpClientCache
" used by
"
shibboleth.FileCachingHttpClient
":
mkdir -p /opt/shibboleth-idp/tmp/httpClientCache ; chown jetty /opt/shibboleth-idp/tmp/httpClientCache
services.xml
":
vim /opt/shibboleth-idp/conf/services.xml
and add the following two beans on the top of the file, under the first
<beans>
TAG, only one time:
<bean
id
="MyHTTPClient"
parent
="shibboleth.FileCachingHttpClientFactory"
p:connectionTimeout
="PT30S"
p:connectionRequestTimeout
="PT30S"
p:socketTimeout
="PT30S"
p:cacheDirectory
="%{idp.home}/tmp/httpClientCache" />
<bean
id
="IdemAttributeFilterFull"
class
="net.shibboleth.ext.spring.resource.FileBackedHTTPResource"
c:client-ref
="MyHTTPClient"
c:url
="https://parichay.inflibnet.ac.in/idp4/idem-attribute-filter-v4-full.xml"
c:backingFile
="%{idp.home}/conf/idem-attribute-filter-v4-full.xml"/>
and enrich the "
AttributeFilterResources
" list with
"
IdemAttributeFilterFull
":
<!-- ...other things... -->
<util:list id ="shibboleth.AttributeFilterResources">
<value>%{idp.home}/conf/attribute-filter.xml</value>
<ref
bean
="IdemAttributeFilterFull"/>
</util:list>
<!-- ...other things... -->
systemctl restart jetty.service
bash /opt/shibboleth-idp/bin/status.sh
Follow these steps ONLY IF your organization is connected to the GARR Network
https://registry.idem.garr.it/
cd /opt/shibboleth-idp/metadata
openssl x509 -in federation-cert.pem -fingerprint -sha1 -noout
(sha1: D1:68:6C:32:A4:E3:D4:FE:47:17:58:E7:15:FC:77:A8:44:D8:40:4D)
openssl x509 -in federation-cert.pem -fingerprint -md5 -noout
(md5: 48:3B:EE:27:0C:88:5D:A3:E7:0B:7C:74:9D:24:24:E0)
vim /opt/shibboleth-idp/conf/metadata-providers.xml
and add before the last
</MetadataProvider>
this piece of code:
<!-- IDEM Test Federation -->
<MetadataProvider
id
="URLMD-IDEM-Federation"
xsi:type
="FileBackedHTTPMetadataProvider"
backingFile
="%{idp.home}/metadata/idem-test-metadata-sha256.xml"
metadataURL
="http://md.idem.garr.it/metadata/idem-test-metadata-sha256.xml">
<!--
Verify the signature on the root element of the metadata aggregate
using a trusted metadata signing certificate.
-->
<MetadataFilter
xsi:type
="SignatureValidation"
requireSignedRoot
="true"
certificateFile
="${idp.home}/metadata/federation-cert.pem"/>
<!--
Require a validUntil XML attribute on the root element and make
sure its value is no more than 10 days into the future.
-->
<MetadataFilter
xsi:type
="RequiredValidUntil"
maxValidityInterval
="P10D"/>
<!--
Consume only SP in the metadata aggregate
-->
<MetadataFilter
xsi:type
="EntityRoleWhiteList">
<RetainedRole>md:SPSSODescriptor</RetainedRole>
</MetadataFilter>
</MetadataProvider>
id shibboleth.MetadataResolverService
to retrieve
the Federation Metadata:
bash /opt/shibboleth-idp/bin/reload-service.sh -id shibboleth.MetadataResolverService
bash /opt/shibboleth-idp/bin/aacli.sh -n <USERNAME> -r https://sp.example.org/shibboleth --saml2
(the command will have a
transient
NameID into the Subject of the
assertion)
bash /opt/shibboleth-idp/bin/aacli.sh -n <USERNAME> -r https://sp.aai-test.garr.it/shibboleth --saml2
(the command will have a
persistent
NameID into the Subject of the
assertion)
Shibboleth Documentation reference: https://wiki.shibboleth.net/confluence/display/IDP4/ConsentConfiguration
The IdP includes the ability to require user consent to attribute release, as well as presenting a "terms of use" message prior to completing a login to a service, a simpler "static" form of consent.
cd /opt/shibboleth-idp
bin/module.sh -t idp.intercept.Consent || bin/module.sh -e idp.intercept.Consent
conf/relying-party.xml
with the right
postAuthenticationFlows:
<bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release" />
- to enable only Attribute Release Consent
<bean parent="SAML2.SSO" p:postAuthenticationFlows="#{ {\'terms-of-use\', \'attribute-release\'} }" />
- to enable both
sudo systemctl restart jetty.service
Follow these steps ONLY IF your need to import persistent-id database from another IdP
sudo su -
shibpid
table from the previous DB
shibboleth
on the OLD IdP:
cd /tmp
/tmp/shibboleth_shibpid.sql
of old IdP
into
/tmp/shibboleth_shibpid.sql
on the new IdP.
/tmp/shibboleth_shibpid.sql
into database of the new
IDP:
cd /tmp ; mysql -u root -p shibboleth < /tmp/shibboleth_shibpid.sql
/tmp/shibboleth_shibpid.sql
:
rm /tmp/shibboleth_shibpid.sql
Follow this if you need to find a problem of your IdP.
cd /opt/jetty/logs
ls -l *.stderrout.log
cd /opt/shibboleth-idp/logs
vim idp-audit.log
vim idp-consent-audit.log
vim idp-warn.log
vim idp-process.log
Shibboleth Documentation Reference:
Follow these steps IF your organization IS NOT connected to the GARR Network or IF you need to connect directly a Shibboleth Service Provider.
metadata-providers.xml
configuration file:
vim /opt/shibboleth-idp/conf/metadata-providers.xml
AttributeFilterPolicy
on the
conf/attribute-filter.xml
file:
/opt/shibboleth-idp/conf/attribute-filter.xml
before the last
elemen
<AttributeFilterPolicy>
t
systemctl restart jetty.service
export JAVA_HOME=/usr/lib/jvm/java-11-amazon-corretto
/opt/shibboleth-idp/edit-webapp/images
without renaming them.
cd /opt/shibboleth-idp/bin ; ./build.sh
systemctl restart jetty.service