Changes between Initial Version and Version 1 of idpiam2018


Ignore:
Timestamp:
Sep 3, 2018, 7:09:22 AM (6 years ago)
Author:
admin
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • idpiam2018

    v1 v1  
     1= Shibboleth IdP v3.3.2 on Ubuntu Linux LTS 18.04 =
     2
     3Installation assumes you have already installed Ubuntu Server 18.04 with default configuration and has a public IP connectivity with DNS setup
     4
     5Lets Assume your server hostname as '''idp.YOUR-DOMAIN'''
     6
     7All commands are to be run as root and you may use `sudo su` to become root
     8
     91. Install the packages required:
     10   {{{
     11apt-get install vim default-jdk ca-certificates openssl tomcat8 apache2 ntp expat
     12}}}
     13   
     14
     152. Modify `/etc/hosts`:
     16   {{{
     17vim /etc/hosts
     18}}} 
     19    {{{
     20     127.0.0.1 idp.YOUR-DOMAIN idp
     21    }}}
     22
     23   (Replace `idp.YOUR-DOMAIN` with your IdP FQDN)
     24
     253. Define the costants `JAVA_HOME` and `IDP_SRC` inside `/etc/environment`:
     26 * 
     27{{{
     28update-alternatives --config java
     29}}}
     30 (copy the path without /bin/java)
     31 *
     32{{{
     33vim /etc/environment```
     34}}}
     35{{{
     36     JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
     37     IDP_SRC=/usr/local/src/shibboleth-identity-provider-3.3.2
     38}}}
     39 *
     40{{{
     41source /etc/environment
     42}}}
     43 *
     44{{{
     45export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
     46}}}
     47 *
     48{{{
     49export IDP_SRC=/usr/local/src/shibboleth-identity-provider-3.3.2
     50}}} 
     51
     524. Configure '''/etc/default/tomcat8''':
     53 *
     54{{{
     55update-alternatives --config java
     56}}}
     57 (copy the path without /bin/java)
     58 *
     59{{{
     60update-alternatives --config javac
     61}}}
     62 *
     63{{{
     64vim /etc/default/tomcat8
     65}}} 
     66     {{{
     67     JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
     68     ...
     69     JAVA_OPTS="-Djava.awt.headless=true -XX:+DisableExplicitGC -XX:+UseParallelOldGC -Xms256m -Xmx1g -Djava.security.egd=file:/dev/./urandom"
     70     }}}
     71
     72     (This settings configure the memory of the JVM that will host the IdP Web Application.
     73     The Memory value depends on the phisical memory installed on the machine.
     74     On production environment Set the "'''Xmx'''" (max heap space available to the JVM) at least to '''2GB''')
     75
     76
     775. Download the Shibboleth Identity Provider v3.3.2:
     78 *
     79{{{
     80cd /usr/local/src
     81}}}
     82 *
     83{{{
     84wget http://shibboleth.net/downloads/identity-provider/3.3.2/shibboleth-identity-provider-3.3.2.tar.gz
     85}}}
     86 *
     87{{{
     88tar -xzvf shibboleth-identity-provider-3.3.2.tar.gz
     89}}}
     90 *
     91{{{
     92cd shibboleth-identity-provider-3.3.2
     93}}}
     94
     95
     966. Generate Passwords for later use in the installation
     97 *
     98{{{
     99   tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
     100}}}
     101   
     102> '''Note: You will need two password string, ###PASSWORD-FOR-BACKCHANNEL### and ###PASSWORD-FOR-COOKIE-ENCRYPTION###'''
     103   
     1047. Run the installer `install.sh` to install Shibboleth Identity Provider v3.3.2:
     105 *
     106{{{
     107   ./bin/install.sh
     108}}}
     109{{{
     110   root@idp:/usr/local/src/shibboleth-identity-provider-3.3.2# ./bin/install.sh
     111   Source (Distribution) Directory: [/usr/local/src/shibboleth-identity-provider-3.3.2]
     112   Installation Directory: [/opt/shibboleth-idp]
     113   Hostname: [localhost.localdomain]
     114   idp.YOUR-DOMAIN
     115   SAML EntityID: [https://idp.YOUR-DOMAIN/idp/shibboleth]
     116   Attribute Scope: [localdomain]
     117   YOUR-DOMAIN
     118   Backchannel PKCS12 Password: ###PASSWORD-FOR-BACKCHANNEL###
     119   Re-enter password:           ###PASSWORD-FOR-BACKCHANNEL###
     120   Cookie Encryption Key Password: ###PASSWORD-FOR-COOKIE-ENCRYPTION###
     121   Re-enter password:              ###PASSWORD-FOR-COOKIE-ENCRYPTION###
     122}}}
     123 
     124   From this point the variable '''idp.home''' refers to the directory: `/opt/shibboleth-idp`
     125
     1268. Import the JST libraries to visualize the IdP `status` page:
     127 *
     128   {{{
     129   cd /opt/shibboleth-idp/edit-webapp/WEB-INF/lib
     130}}}
     131 *
     132   {{{
     133   wget https://build.shibboleth.net/nexus/service/local/repositories/thirdparty/content/javax/servlet/jstl/1.2/jstl-1.2.jar
     134 }}}
     135 *
     136{{{
     137   cd /opt/shibboleth-idp/bin ; ./build.sh -Didp.target.dir=/opt/shibboleth-idp
     138}}}
     139
     1409. Change the owner to enable '''tomcat8''' user to access on the following directories:
     141 *
     142   {{{
     143   chown -R tomcat8 /opt/shibboleth-idp/logs/
     144}}}
     145 *
     146   {{{
     147   chown -R tomcat8 /opt/shibboleth-idp/metadata/
     148}}}
     149 *
     150   {{{
     151   chown -R tomcat8 /opt/shibboleth-idp/credentials/
     152}}}
     153 *
     154   {{{
     155   chown -R tomcat8 /opt/shibboleth-idp/conf/
     156}}}
     157
     158== Configure SSL on Apache2 with Letsencrypt ==
     159If you do this installation in Lab setup please skip to implementing https with self-signed certificates as described in '''step 13'''.
     160
     16110. Disable default apache configuration:
     162 *
     163   {{{
     164   a2dissite 000-default
     165}}}
     166   
     16711. Create a new configuration file as `idp.conf` with the following:
     168 *
     169   {{{
     170   vim /etc/apache2/site-available/idp.conf
     171}}}
     172 
     173{{{
     174   <VirtualHost *:80>
     175     ServerName idp.YOUR-DOMAIN
     176     ServerAdmin admin@YOUR-DOMAIN
     177     DocumentRoot /var/www/html
     178   </VirtualHost>
     179}}}
     180   
     181   Enable Apache2 modules:
     182 *
     183   {{{
     184   a2enmod proxy_http ssl headers alias include negotiation
     185}}}
     186   Restart the Apache service:
     187 *
     188   {{{
     189   service apache2 restart
     190}}}
     191
     19212. Install Letsencrypt and enable HTTPS:
     193
     194 *
     195   {{{
     196   add-apt-repository ppa:certbot/certbot
     197}}}
     198 *
     199   {{{
     200   apt install python-certbot-apache
     201}}}
     202 *
     203   {{{
     204   certbot --apache -d idp.YOUR-DOMAIN
     205}}}
     206   
     207{{{
     208   Plugins selected: Authenticator apache, Installer apache
     209   Enter email address (used for urgent renewal and security notices) (Enter 'c' to
     210   cancel): YOU@YOUR-DOMAIN
     211
     212   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     213   Please read the Terms of Service at
     214   https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
     215   agree in order to register with the ACME server at
     216   https://acme-v02.api.letsencrypt.org/directory
     217   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     218   (A)gree/(C)ancel: A
     219
     220   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     221   Would you be willing to share your email address with the Electronic Frontier
     222   Foundation, a founding partner of the Let's Encrypt project and the non-profit
     223   organization that develops Certbot? We'd like to send you email about our work
     224   encrypting the web, EFF news, campaigns, and ways to support digital freedom.
     225   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     226   (Y)es/(N)o: Y
     227   
     228   Obtaining a new certificate
     229   Performing the following challenges:
     230   http-01 challenge for idp.YOUR-DOMAIN
     231   Waiting for verification...
     232   Cleaning up challenges
     233   Created an SSL vhost at /etc/apache2/sites-available/idp-le-ssl.conf
     234   Enabled Apache socache_shmcb module
     235   Enabled Apache ssl module
     236   Deploying Certificate to VirtualHost /etc/apache2/sites-available/idp-le-ssl.conf
     237   Enabling available site: /etc/apache2/sites-available/idp-le-ssl.conf
     238   
     239   
     240   Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
     241   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     242   1: No redirect - Make no further changes to the webserver configuration.
     243   2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
     244   new sites, or if you're confident your site works on HTTPS. You can undo this
     245   change by editing your web server's configuration.
     246   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     247   Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
     248   Redirecting vhost in /etc/apache2/sites-enabled/rr3.conf to ssl vhost in /etc/apache2/sites-available/rr3-le-ssl.conf
     249   
     250   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     251   Congratulations! You have successfully enabled https://idp.YOUR-DOMAIN
     252}}}
     253 
     254
     255
     25613. (OPTIONAL) If you haven't follow the letsencrypt method Create a Certificate and a Key self-signed for HTTPS
     257 *
     258   {{{
     259   mkdir /root/certificates
     260}}}
     261 *
     262   {{{
     263   openssl req -x509 -newkey rsa:4096 -keyout /root/certificates/idp-key-server.key -out /root/certificates/idp-cert-server.crt -nodes -days 1095
     264}}}
     265   If you purchased SSL certificates from a Public CA, move the Certificate and the Key file for HTTPS server to `/root/certificates`:
     266   
     267 *
     268   {{{
     269   mv /location-to-crts/idp-cert-server.crt /root/certificates
     270}}}
     271 *
     272   {{{
     273   mv /location-to-crts/idp-key-server.key /root/certificates
     274}}}
     275 *
     276   {{{
     277   mv /location-to-crts/PublicCA.crt /root/certificates
     278}}}
     279   
     280   Then,
     281   
     282 *
     283   {{{
     284   chmod 400 /root/certificates/idp-key-server.key
     285}}}
     286 *
     287   {{{
     288   chmod 644 /root/certificates/idp-cert-server.crt
     289}}}
     290 *
     291   {{{
     292   chmod 644 /root/certificates/PublicCA.crt
     293}}}
     294
     295   Create the file `/etc/apache2/sites-available/idp-ssl.conf` as follows:
     296
     297   {{{
     298   <IfModule mod_ssl.c>
     299      SSLStaplingCache        shmcb:/var/run/ocsp(128000)
     300      <VirtualHost _default_:443>
     301        ServerName idp.YOUR-DOMAIN:443
     302        ServerAdmin admin@example.org
     303        DocumentRoot /var/www/html
     304       
     305        ...
     306        SSLEngine On
     307       
     308        SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
     309        SSLCipherSuite "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
     310
     311        SSLHonorCipherOrder on
     312
     313        # Disable SSL Compression
     314        SSLCompression Off
     315       
     316        # OCSP Stapling, only in httpd/apache >= 2.3.3
     317        SSLUseStapling          on
     318        SSLStaplingResponderTimeout 5
     319        SSLStaplingReturnResponderErrors off
     320       
     321        # Enable HTTP Strict Transport Security with a 2 year duration
     322        Header always set Strict-Transport-Security "max-age=63072000;includeSubDomains;preload"
     323        ...
     324        SSLCertificateFile /root/certificates/idp-cert-server.crt
     325        SSLCertificateKeyFile /root/certificates/idp-key-server.key
     326        SSLCertificateChainFile /root/certificates/publicCA.crt
     327        ...
     328      </VirtualHost>
     329   </IfModule>
     330}}}
     331   Enable '''proxy_http''', '''SSL''' and '''headers''' Apache2 modules:
     332 *
     333   {{{
     334   a2enmod proxy_http ssl headers alias include negotiation
     335}}}
     336 *
     337   {{{
     338   a2ensite idp-ssl.conf
     339}}}
     340 *
     341   {{{
     342   service apache2 restart
     343}}}
     344
     345   Configure Apache2 to redirect all on HTTPS:
     346 *
     347   {{{
     348   vim /etc/apache2/sites-enabled/000-default.conf
     349}}}
     350   
     351{{{
     352   <VirtualHost *:80>
     353        ServerName "idp.YOUR-DOMAIN"
     354        Redirect "/" "https://idp.YOUR-DOMAIN/"
     355   </VirtualHost>
     356}}}
     357
     358== Configure Apache Tomcat 8 ==
     359
     360
     36114. Modify `server.xml`:
     362 *
     363   {{{
     364   vim /etc/tomcat8/server.xml
     365}}}
     366 
     367     Comment out the Connector 8080 (HTTP):
     368   
     369{{{
     370     <!-- A "Connector" represents an endpoint by which requests are received
     371          and responses are returned. Documentation at :
     372          Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
     373          Java AJP  Connector: /docs/config/ajp.html
     374          APR (HTTP/AJP) Connector: /docs/apr.html
     375          Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
     376     -->
     377     <!--
     378     <Connector port="8080" protocol="HTTP/1.1"
     379                connectionTimeout="20000"
     380                URIEncoding="UTF-8"
     381                redirectPort="8443" />
     382     -->
     383}}}
     384
     385     Enable the Connector 8009 (AJP):
     386
     387     ```apache
     388     <!-- Define an AJP 1.3 Connector on port 8009 -->
     389     <Connector port="8009" protocol="AJP/1.3" redirectPort="443" address="127.0.0.1" enableLookups="false" tomcatAuthentication="false"/>
     390     ```
     391   
     392     Check the integrity of XML files just edited with:
     393     ```xmlwf -e UTF-8 /etc/tomcat8/server.xml```
     394
     39515. Create and change the file ```idp.xml```:
     396 *
     397   {{{
     398   sudo vim /etc/tomcat8/Catalina/localhost/idp.xml```
     399
     400     ```apache
     401     <Context docBase="/opt/shibboleth-idp/war/idp.war"
     402              privileged="true"
     403              antiResourceLocking="false"
     404              swallowOutput="true"/>
     405     ```
     406
     40716. Create the Apache2 configuration file for IdP:
     408 *
     409   {{{
     410   vim /etc/apache2/sites-available/idp-proxy.conf```
     411 
     412     ```apache
     413     <IfModule mod_proxy.c>
     414       ProxyPreserveHost On
     415       RequestHeader set X-Forwarded-Proto "https"
     416
     417       <Proxy ajp://localhost:8009>
     418         Require all granted
     419       </Proxy>
     420
     421       ProxyPass /idp ajp://localhost:8009/idp retry=5
     422       ProxyPassReverse /idp ajp://localhost:8009/idp retry=5
     423     </IfModule>
     424     ```
     425
     42617. Enable **proxy_ajp** apache2 module and the new IdP site:
     427 *
     428   {{{
     429   a2enmod proxy_ajp```
     430 *
     431   {{{
     432   a2ensite idp-proxy.conf```
     433 *
     434   {{{
     435   service apache2 restart```
     436 
     43718. Modify **context.xml** to prevent error of *lack of persistence of the session objects* created by the IdP :
     438 *
     439   {{{
     440   vim /etc/tomcat8/context.xml```
     441
     442     and remove the comment from:
     443
     444     ```<Manager pathname="" />```
     445   
     44619. Restart Tomcat8:
     447 *
     448   {{{
     449   service tomcat8 restart```
     450
     45120. Verify if the IdP works by opening this page on your browser:
     452 *
     453   {{{
     454   https://idp.YOUR-DOMAIN/idp/shibboleth``` (you should see the IdP metadata)
     455
     456
     457
     458### Speed up Tomcat 8 startup
     459
     460 
     46121. Find out the JARs that can be skipped from the scanning:
     462  *
     463   {{{
     464   cd /opt/shibboleth-idp/```
     465  *
     466   {{{
     467   ls webapp/WEB-INF/lib | awk '{print $1",\\"}'```
     468 
     469    Insert the output list into ```/etc/tomcat8/catalina.properties``` at the tail of  ```tomcat.util.scan.StandardJarScanFilter.jarsToSkip```
     470    Make sure about the  ```,\``` symbols
     471   
     472    Restart Tomcat 8:
     473  *
     474   {{{
     475   service tomcat8 restart```
     476 
     477
     478### Configure Shibboleth Identity Provider v3.2.1 to release the persistent-id (Stored mode)
     479
     480
     48122. Test IdP by opening a terminal and running these commands:
     482 *
     483   {{{
     484   cd /opt/shibboleth-idp/bin```
     485 *
     486   {{{
     487   ./status.sh``` (You should see some informations about the IdP installed)
     488
     48923. Install **MySQL Connector Java** and other useful libraries used by Tomcat for MySQL DB (if you don't have them already):
     490 *
     491   {{{
     492   apt-get install mysql-server libmysql-java libcommons-dbcp-java libcommons-pool-java```
     493 *
     494   {{{
     495   cd /usr/share/tomcat8/lib/```
     496 *
     497   {{{
     498   ln -s ../../java/mysql.jar mysql-connector-java.jar```
     499 *
     500   {{{
     501   ln -s ../../java/commons-pool.jar commons-pool.jar```
     502 *
     503   {{{
     504   ln -s ../../java/commons-dbcp.jar commons-dbcp.jar```
     505 *
     506   {{{
     507   ln -s ../../java/tomcat-jbcp.jar tomcat-jbcp.jar```
     508   Ignore if you get errors for some of the ```ln``` commands as the files might be already there.
     509
     51024. Rebuild the **idp.war** of Shibboleth with the new libraries:
     511 *
     512   {{{
     513   cd /opt/shibboleth-idp/ ; ./bin/build.sh```
     514   You may need to press enter on `Installation Directory: [/opt/shibboleth-idp]`
     515
     51625. Create and prepare the "**shibboleth**" MySQL DB to host the values of the several **persistent-id** and **StorageRecords** MySQL DB to host other useful information about user consent:
     517
     518    * `mysql_secure_installation`
     519
     520
     521```
     522Securing the MySQL server deployment.
     523
     524Connecting to MySQL using a blank password.
     525
     526VALIDATE PASSWORD PLUGIN can be used to test passwords
     527and improve security. It checks the strength of password
     528and allows the users to set only those passwords which are
     529secure enough. Would you like to setup VALIDATE PASSWORD plugin?
     530
     531Press y|Y for Yes, any other key for No: y
     532
     533There are three levels of password validation policy:
     534
     535LOW    Length >= 8
     536MEDIUM Length >= 8, numeric, mixed case, and special characters
     537STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
     538
     539Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
     540Please set the password for root here.
     541
     542New password:
     543
     544Re-enter new password:
     545
     546Estimated strength of the password: 50
     547Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
     548By default, a MySQL installation has an anonymous user,
     549allowing anyone to log into MySQL without having to have
     550a user account created for them. This is intended only for
     551testing, and to make the installation go a bit smoother.
     552You should remove them before moving into a production
     553environment.
     554
     555Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
     556Success.
     557
     558Normally, root should only be allowed to connect from
     559'localhost'. This ensures that someone cannot guess at
     560the root password from the network.
     561
     562Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
     563Success.
     564
     565By default, MySQL comes with a database named 'test' that
     566anyone can access. This is also intended only for testing,
     567and should be removed before moving into a production
     568environment.
     569
     570
     571Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
     572 - Dropping test database...
     573Success.
     574
     575 - Removing privileges on test database...
     576Success.
     577
     578Reloading the privilege tables will ensure that all changes
     579made so far will take effect immediately.
     580
     581Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
     582Success.
     583
     584All done!
     585```
     586
     587   * log in to your MySQL Server:
     588     ```mysql -u root -p```
     589   
     590```sql
     591    SET NAMES 'utf8';
     592
     593    SET CHARACTER SET utf8;
     594
     595    CREATE DATABASE IF NOT EXISTS shibboleth CHARACTER SET=utf8;
     596
     597    GRANT ALL PRIVILEGES ON shibboleth.* TO root@localhost IDENTIFIED BY '##ROOT-DB-PASSWORD##';
     598    GRANT ALL PRIVILEGES ON shibboleth.* TO ##USERNAME##@localhost IDENTIFIED BY '##PASSWORD##';
     599
     600    FLUSH PRIVILEGES;
     601
     602    USE shibboleth;
     603
     604    CREATE TABLE IF NOT EXISTS shibpid
     605    (
     606    localEntity VARCHAR(255) NOT NULL,
     607    peerEntity VARCHAR(255) NOT NULL,
     608    persistentId VARCHAR(50) NOT NULL,
     609    principalName VARCHAR(50) NOT NULL,
     610    localId VARCHAR(50) NOT NULL,
     611    peerProvidedId VARCHAR(50) NULL,
     612    creationDate TIMESTAMP NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
     613    deactivationDate TIMESTAMP NULL default NULL,
     614    PRIMARY KEY (localEntity, peerEntity, persistentId)
     615    );
     616
     617    CREATE TABLE IF NOT EXISTS StorageRecords
     618    (
     619    context VARCHAR(255) NOT NULL,
     620    id VARCHAR(255) NOT NULL,
     621    expires BIGINT(20) DEFAULT NULL,
     622    value LONGTEXT NOT NULL,
     623    version BIGINT(20) NOT NULL,
     624    PRIMARY KEY (context, id)
     625    );
     626
     627    quit
     628```
     629     
     630     
     631   * Restart mysql service:
     632     ```service mysql restart```
     633
     63426. Enable the generation of the ```persistent-id``` (this replace the deprecated attribute *eduPersonTargetedID*)
     635   
     636  *
     637   {{{
     638   vim /opt/shibboleth-idp/conf/saml-nameid.properties```
     639   
     640   (the *sourceAttribute* MUST BE an attribute, or a list of comma-separated attributes, that uniquely identify the subject of the generated ```persistent-id```. It MUST BE: **Stable**, **Permanent** and **Not-reassignable**)
     641
     642     ```xml
     643     idp.persistentId.sourceAttribute = uid
     644     ...
     645     idp.persistentId.salt = ### result of 'openssl rand -base64 36'###
     646     ...
     647     idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator
     648     ...
     649     idp.persistentId.dataSource = MyDataSource
     650     ...
     651     idp.persistentId.computed = shibboleth.ComputedPersistentIdGenerator
     652     ```
     653
     654   * Enable the **SAML2PersistentGenerator**:
     655   *
     656   {{{
     657   vim /opt/shibboleth-idp/conf/saml-nameid.xml```
     658     
     659     Remove the comment from the line containing:
     660   
     661     ```xml
     662     <ref bean="shibboleth.SAML2PersistentGenerator" />
     663     ```
     664
     665   *
     666   {{{
     667   vim /opt/shibboleth-idp/conf/c14n/subject-c14n.xml```
     668     
     669     Remove the comment to the bean called "**c14n/SAML2Persistent**".
     670       
     671     ```xml
     672     <ref bean="c14n/SAML2Persistent" />
     673     ```
     674       
     67527. Enable **JPAStorageService** for the **StorageService** of the user consent:
     676 *
     677   {{{
     678   vim /opt/shibboleth-idp/conf/global.xml``` and add this piece of code to the tail before the ending \</beans\>:
     679
     680     ```xml
     681     <!-- A DataSource bean suitable for use in the idp.persistentId.dataSource property. -->
     682     <bean id="MyDataSource" class="org.apache.commons.dbcp.BasicDataSource"
     683           p:driverClassName="com.mysql.jdbc.Driver"
     684           p:url="jdbc:mysql://localhost:3306/shibboleth?autoReconnect=true"
     685           p:username="##USER_DB_NAME##"
     686           p:password="##PASSWORD##"
     687           p:maxActive="10"
     688           p:maxIdle="5"
     689           p:maxWait="15000"
     690           p:testOnBorrow="true"
     691           p:validationQuery="select 1"
     692           p:validationQueryTimeout="5" />
     693
     694     <bean id="shibboleth.JPAStorageService" class="org.opensaml.storage.impl.JPAStorageService"
     695           p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
     696           c:factory-ref="shibboleth.JPAStorageService.entityManagerFactory"/>
     697
     698     <bean id="shibboleth.JPAStorageService.entityManagerFactory"
     699           class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     700           <property name="packagesToScan" value="org.opensaml.storage.impl"/>
     701           <property name="dataSource" ref="MyDataSource"/>
     702           <property name="jpaVendorAdapter" ref="shibboleth.JPAStorageService.JPAVendorAdapter"/>
     703           <property name="jpaDialect">
     704             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
     705           </property>
     706     </bean>
     707
     708     <bean id="shibboleth.JPAStorageService.JPAVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
     709           <property name="database" value="MYSQL" />
     710     </bean>
     711     ```
     712     (and modify the "**USER_DB_NAME**" and "**PASSWORD**" for your "**shibboleth**" DB)
     713
     714   * Modify the IdP configuration file:
     715   *
     716   {{{
     717   vim /opt/shibboleth-idp/conf/idp.properties```
     718
     719       ```xml
     720       idp.session.StorageService = shibboleth.JPAStorageService
     721       idp.consent.StorageService = shibboleth.JPAStorageService
     722       idp.replayCache.StorageService = shibboleth.JPAStorageService
     723       idp.artifact.StorageService = shibboleth.JPAStorageService
     724       # Track information about SPs logged into
     725       idp.session.trackSPSessions = true
     726       # Support lookup by SP for SAML logout
     727       idp.session.secondaryServiceIndex = true
     728       ```
     729
     730       (This will indicate to IdP to store the data collected by User Consent into the "**StorageRecords**" table)
     731
     732
     73328. Connect the openLDAP to the IdP to allow the authentication of the users:
     734    * use ```openssl x509 -outform der -in /etc/ssl/certs/ldap_server.pem -out /opt/shibboleth-idp/credentials/ldap_server.crt``` to load the ldap certificate.
     735   
     736    If you host ldap in a seperate machine, copy the ldap_server.crt to  ```/opt/shibboleth-idp/credentials```
     737  *
     738   {{{
     739   vim /opt/shibboleth-idp/conf/ldap.properties```
     740
     741
     742     * Solution 1: LDAP + STARTTLS:
     743
     744       ```xml
     745       idp.authn.LDAP.authenticator = bindSearchAuthenticator
     746       idp.authn.LDAP.ldapURL = ldap://ldap.example.org:389
     747       idp.authn.LDAP.useStartTLS = true
     748       idp.authn.LDAP.useSSL = false
     749       idp.authn.LDAP.sslConfig = certificateTrust
     750       idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt
     751       idp.authn.LDAP.baseDN = ou=people,dc=example,dc=org
     752       idp.authn.LDAP.userFilter = (uid={user})
     753       idp.authn.LDAP.bindDN = cn=admin,dc=example,dc=org
     754       idp.authn.LDAP.bindDNCredential = ###LDAP_ADMIN_PASSWORD###
     755       idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates:undefined}
     756       ```
     757
     758     * Solution 2: LDAP + TLS:
     759
     760       ```xml
     761       idp.authn.LDAP.authenticator = bindSearchAuthenticator
     762       idp.authn.LDAP.ldapURL = ldaps://ldap.example.org:636
     763       idp.authn.LDAP.useStartTLS = false
     764       idp.authn.LDAP.useSSL = true
     765       idp.authn.LDAP.sslConfig = certificateTrust
     766       idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt
     767       idp.authn.LDAP.baseDN = ou=people,dc=example,dc=org
     768       idp.authn.LDAP.userFilter = (uid={user})
     769       idp.authn.LDAP.bindDN = cn=admin,dc=example,dc=org
     770       idp.authn.LDAP.bindDNCredential = ###LDAP_ADMIN_PASSWORD###
     771       idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates:undefined}
     772       ```
     773
     774     * Solution 3: plain LDAP
     775 
     776       ```xml
     777       idp.authn.LDAP.authenticator = bindSearchAuthenticator
     778       idp.authn.LDAP.ldapURL = ldap://ldap.example.org:389
     779       idp.authn.LDAP.useStartTLS = false
     780       idp.authn.LDAP.useSSL = false
     781       idp.authn.LDAP.baseDN = ou=people,dc=example,dc=org
     782       idp.authn.LDAP.userFilter = (uid={user})
     783       idp.authn.LDAP.bindDN = cn=admin,dc=example,dc=org
     784       idp.authn.LDAP.bindDNCredential = ###LDAP_ADMIN_PASSWORD###
     785       ```
     786       (If you decide to use the Solution 3, you have to remove (or comment out) the following code from your Attribute Resolver file:
     787     
     788       ```xml
     789       </dc:FilterTemplate>
     790       <!--
     791       <dc:StartTLSTrustCredential id="LDAPtoIdPCredential" xsi:type="sec:X509ResourceBacked">
     792         <sec:Certificate>%
     793           {idp.attribute.resolver.LDAP.trustCertificates}</sec:Certificate>
     794         </dc:StartTLSTrustCredential>
     795       -->
     796       </resolver:DataConnector>
     797       ```
     798
     799       **UTILITY FOR OPENLDAP ADMINISTRATOR:**
     800         *
     801   {{{
     802   ldapsearch -H ldap:// -x -b "dc=example,dc=it" -LLL dn```
     803           * the baseDN ==> ```ou=people, dc=example,dc=org``` (branch containing the registered users)
     804           * the bindDN ==> ```cn=admin,dc=example,dc=org``` (distinguished name for the user that can made queries on the LDAP)
     805
     806
     80729. Enrich IDP logs with the authentication error occurred on LDAP:
     808 *
     809   {{{
     810   vim /opt/shibboleth-idp/conf/logback.xml```
     811
     812     ```xml
     813     <!-- Logs LDAP related messages -->
     814     <logger name="org.ldaptive" level="${idp.loglevel.ldap:-WARN}"/>
     815
     816     <!-- Logs on LDAP user authentication -->
     817     <logger name="org.ldaptive.auth.Authenticator" level="INFO" />
     818     ```
     819
     82030. Build the **attribute-resolver.xml** to define which attributes your IdP can manage. Here you can find the **attribute-resolver-v1-LEARN.xml** provided by LEARN:
     821    * Download the attribute resolver provided by LEARN:
     822      ```wget https://fr-training.ac.lk/attribute-resolver-v1-LEARN.xml -O /opt/shibboleth-idp/conf/attribute-resolver-v1-LEARN.xml```
     823
     824    * Modify ```services.xml``` file:
     825      ```vim /opt/shibboleth-idp/conf/services.xml```
     826
     827      ```xml
     828      <value>%{idp.home}/conf/attribute-resolver.xml</value>
     829      ```
     830
     831      must become:
     832
     833      ```xml
     834      <value>%{idp.home}/conf/attribute-resolver-v1-LEARN.xml</value>
     835      ```
     836
     837    * Configure the LDAP Data Connector to be compliant to the values put on ```ldap.properties```. (See above suggestions)
     838
     839    * Restart Tomcat8:
     840      ```service tomcat8 restart```
     841
     84231. Enable the SAML2 support by changing the ```idp-metadata.xml``` and disabling the SAML v1.x deprecated support:
     843  *
     844   {{{
     845   vim /opt/shibboleth-idp/metadata/metadata.xml```
     846      ```bash
     847      <IDPSSODescriptor> SECTION:
     848        – From the list of "protocolSupportEnumeration" remove:
     849          - urn:oasis:names:tc:SAML:1.1:protocol
     850          - urn:mace:shibboleth:1.0
     851
     852        – Remove the endpoint:
     853          <ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://idp.YOUR-DOMAIN:8443/idp/profile/SAML1/SOAP/ArtifactResolution" index="1"/>
     854          (and modify the index value of the next one to “1”)
     855
     856        – Remove the endpoint:
     857          <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
     858
     859        – Replace the endpoint:
     860          <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
     861          with:
     862          <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
     863          (because the IdP installed with this guide releases persistent SAML NameIDs)
     864
     865        - Remove the endpoint:
     866          <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://idp.YOUR-DOMAIN/idp/profile/Shibboleth/SSO"/>       
     867        - Remove all ":8443" from the existing URL (such port is not used anymore)
     868       
     869        - Uncomment SingleLogoutService:
     870       
     871          <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://identity.thilinapathirana.xyz/idp/profile/SAML2/Redirect/SLO"/>
     872          <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://identity.thilinapathirana.xyz/idp/profile/SAML2/POST/SLO"/>
     873          <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://identity.thilinapathirana.xyz/idp/profile/SAML2/POST-SimpleSign/SLO"/>
     874          <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://identity.thilinapathirana.xyz/idp/profile/SAML2/SOAP/SLO"/>
     875
     876
     877      <AttributeAuthorityDescriptor> Section:
     878        – From the list "protocolSupportEnumeration" replace the value of:
     879          - urn:oasis:names:tc:SAML:1.1:protocol
     880          with
     881          - urn:oasis:names:tc:SAML:2.0:protocol
     882
     883        - Remove the comment from:
     884          <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.YOUR-DOMAIN/idp/profile/SAML2/SOAP/AttributeQuery"/>
     885        - Remove the endpoint:
     886          <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://idp.YOUR-DOMAIN:8443/idp/profile/SAML1/SOAP/AttributeQuery"/>
     887
     888        - Remove all ":8443" from the existing URL (such port is not used anymore)
     889      ```
     890
     89132. Obtain your IdP metadata here:
     892    *  ```https://idp.YOUR-DOMAIN/idp/shibboleth```
     893
     89433. Register you IdP on the test Federation:
     895  *
     896   {{{
     897   https://fr-training.ac.lk/```
     898    > For production enviornments please use `https://fr.ac.lk`, Also make sure to remove `-training` from all urls.
     899
     90034. Configure the IdP to retrieve the Federation Metadata:
     901  *
     902   {{{
     903   cd /opt/shibboleth-idp/conf```
     904  *
     905   {{{
     906   vim metadata-providers.xml```
     907
     908      ```xml
     909      <MetadataProvider
     910            id="HTTPMD-LEARN-Federation"
     911            xsi:type="FileBackedHTTPMetadataProvider"
     912            backingFile="%{idp.home}/metadata/test-metadata.xml"
     913            metadataURL="http://fr-training.ac.lk/rr3/metadata/federation/FR-training/metadata.xml">
     914            <!--
     915                Verify the signature on the root element of the metadata aggregate
     916                using a trusted metadata signing certificate.
     917            -->
     918            <MetadataFilter xsi:type="SignatureValidation" requireSignedRoot="true" certificateFile="${idp.home}/metadata/federation-cert.pem"/>
     919
     920            <!--
     921                Require a validUntil XML attribute on the root element and
     922                make sure its value is no more than 10 days into the future.
     923            -->
     924            <MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P10D"/>
     925
     926            <!-- Consume all SP metadata in the aggregate -->
     927            <MetadataFilter xsi:type="EntityRoleWhiteList">
     928              <RetainedRole>md:SPSSODescriptor</RetainedRole>
     929            </MetadataFilter>
     930      </MetadataProvider>
     931      ```
     932
     933    * Retrive the Federation Certificate used to verify its signed metadata:
     934    *  ```wget https://fr-training.ac.lk/metadata-signer -O /opt/shibboleth-idp/metadata/federation-cert.pem```
     935
     936   
     937 
     93835. Reload service with id ```shibboleth.MetadataResolverService``` to retrieve the Federation Metadata:
     939    *  ```cd /opt/shibboleth-idp/bin```
     940    *  ```./reload-service.sh -id shibboleth.MetadataResolverService```
     941
     942
     943
     94436. The day after the Federation Operators approval you, check if you can login with your IdP on the following services:
     945    * https://sp-training.ac.lk/secure   (Service Provider provided for testing the LEARN Training Federation)
     946    * https://sp-test.learn.ac.lk/secure (Service Provider provided for testing the LEARN Production Federation)
     947
     948
     949### Configure Attribute Filters to release the mandatory attributes to the default IDEM Resources:
     950
     95137. Make sure that you have the "```tmp/httpClientCache```" used by "```shibboleth.FileCachingHttpClient```":
     952  *
     953   {{{
     954   mkdir -p /opt/shibboleth-idp/tmp/httpClientCache ; chown tomcat8 /opt/shibboleth-idp/tmp/httpClientCache```
     955
     95638. Modify your ```services.xml```:
     957  *
     958   {{{
     959   vim /opt/shibboleth-idp/conf/services.xml```
     960
     961      ```xml
     962      <bean id="Default-Filter" class="net.shibboleth.ext.spring.resource.FileBackedHTTPResource"
     963            c:client-ref="shibboleth.FileCachingHttpClient"
     964            c:url="https://fr-training.ac.lk/attribute-filter-LEARN-Default.xml"
     965            c:backingFile="%{idp.home}/conf/attribute-filter-LEARN-Default.xml"/>
     966      <bean id="Production-Filter" class="net.shibboleth.ext.spring.resource.FileBackedHTTPResource"
     967            c:client-ref="shibboleth.FileCachingHttpClient"
     968            c:url="https://fr-training.ac.lk/attribute-filter-LEARN-Production.xml"
     969            c:backingFile="%{idp.home}/conf/attribute-filter-LEARN-Production.xml"/>
     970      ...
     971
     972      <util:list id ="shibboleth.AttributeFilterResources">
     973         <value>%{idp.home}/conf/attribute-filter.xml</value>
     974         <ref bean="Default-Filter"/>
     975         <ref bean="Production-Filter"/>
     976       </util:list>
     977      ```
     978
     97939. Reload service with id ```shibboleth.AttributeFilterService``` to refresh the Attribute Filter followed by the IdP:
     980    *  ```cd /opt/shibboleth-idp/bin```
     981    *  ```./reload-service.sh -id shibboleth.AttributeFilterService```
     982
     983
     984
     985### Appendix: Useful logs to find problems
     986
     9871. Tomcat 8 Logs:
     988 *
     989   {{{
     990   cd /var/log/tomcat8```
     991 *
     992   {{{
     993   vim catalina.out```
     994
     9952. Shibboleth IdP Logs:
     996 *
     997   {{{
     998   cd /opt/shibboleth-idp/logs```
     999   * **Audit Log:** ```vim idp-audit.log```
     1000   * **Consent Log:** ```vim idp-consent-audit.log```
     1001   * **Warn Log:** ```vim idp-warn.log```
     1002   * **Process Log:** ```vim idp-process.log```