Instalación del Identity Provider (IdP)

Para la instalación tanto del SP como del IdP, me base principalmente en la documentación de [1].

Paquetes necesarios

Para descomprimir e instalar el Idp, primero necesitamos tener unzip:

sudo apt-get update
apt-get install unzip

Se instala la ultima version de la jdk:

apt-get install default-jre-headless

Instalación de tomcat:

apt-get install tomcat6

Se configuran las opciones de memoria de la Java Virtual Machine para que funcioné con el IdP. Se setea la memoria máximo del proceso en 512 MB: "Set Xmx (maximum amount of heap space available to the JVM) to at least 512 MB and XX:MaxPermSize to 128 MB".

Hay que setear la variable JAVA_OPTS en /etc/default/tomcat6:

JAVA_OPTS="-Djava.awt.headless=true -Xmx512M -XX:MaxPermSize=128M -Dcom.sun.security.enableCRLDP=true" 

El valor por defecto de autoDeploy en la config de tomcat6 es true. Esto significa que periodicamente está chequeando si una app web ha sido actualizada, para redeployarla. Esto no es el comportamiento preferido por lo que hay que desactivarlo, poniéndolo en false en el archivo /etc/tomcat6/server.xml:

<Host name="localhost"  appBase="webapps" 
            unpackWARs="true" autoDeploy="false" 
            xmlValidation="false" xmlNamespaceAware="false">

Se reinicia tomcat6

service tomcat6 restart

Para verificar que el tomcat haya quedado correctamente instalado, acceder a la url http://ip:8080/

Instalación de Shibboleth

Se baja la ultima versión de shibbolleth IdP

cd /usr/local/src
curl -O https://shibboleth.net/downloads/identity-provider/2.4.3/shibboleth-identityprovider-2.4.3-bin.zip
unzip shibboleth-identityprovider-2.4.3-bin.zip
cd shibboleth-identityprovider-2.4.3
chmod u+x install.sh

Ejecutamos el instalador del IdP Shibboleth. Hay que asegurarse de setear la variable de ambiente IdPCertLifeTime para el certificado IdP a 3 (años):

cd /usr/local/src/shibboleth-identityprovider-2.4.3/
sudo env IdPCertLifetime=3 JAVA_HOME=/usr/lib/jvm/default-java ./install.sh

Durante la instalación hay que responder a una serie de preguntas:

Where should the Shibboleth Identity Provider software be installed?
[/opt/shibboleth-idp]
/opt/shibboleth-idp
What is the fully qualified hostname of the Shibboleth Identity Prov
ider server? [default: idp.example.org]
idp.identidad.interior.udelar.edu.uy
A keystore is about to be generated for you. Please enter a password
that will be used to protect it.
<Password compartida ingles>

Se debe recordar esta password ingresada para el IdP porque se va a usar mas adelante en la configuración.

Luego, se deben configurar los SOAP endpoints para las veces en que se requiera conectar IdP y SP directamente:
  • Hay que bajar tomcat6-dta-ssl-1.0.0.jar en el directorio /usr/share/tomcat6/lib
  • Después hay que editar el archivo /var/lib/tomcat6/conf/server.xml , agregando lo siguiente y reemplazando la PASSWORD por la ingresada durante la instalación anterior:
    <Connector port="8443" 
               protocol="org.apache.coyote.http11.Http11Protocol" 
               SSLImplementation="edu.internet2.middleware.security.tomcat6.DelegateToApplicationJSSEImplementation" 
               scheme="https" 
               maxPostSize="100000" 
               SSLEnabled="true" 
               clientAuth="want" 
               keystoreFile="/opt/shibboleth-idp/credentials/idp.jks" 
               keystorePass="<Password compartida ingles>" />
    

A continuación, se debe crear un context deployment fragment.
Se debe agregar este nuevo fragmento de XML para que tomcat6 sepa donde encontrar el war del shibbolleth y como cargarlo (extiende sus webapps).
Esto se hace así, en lugar de copiar manualmente el war dentro de webapps, para evitar que tomcat6 utilice una versión antigua del war.

cd /var/lib/tomcat6/conf/Catalina/localhost
nano idp.xml

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

Fixeo de permisos

Para evitar cualquier problema de permisos en los logs:

cd /opt/shibboleth-idp
chown -R tomcat6 logs metadata  
chgrp -R tomcat6 conf credentials logs metadata war lib
chown tomcat6 conf/attribute-filter.xml
chmod 664 conf/attribute-filter.xml
chmod 750 lib war
chmod 750 conf credentials
chmod 775 logs metadata

Primer testeo de nuestro IdP

Se puede configurar en /etc/hosts el o los nombres de servidores SP e IdP para resolverlos mejor.

Después se reinicia Tomcat

service tomcat6 restart

El Idp se puede testart para ver si quedó instalando y corriendo correctamente, accediendo a la url: https://identidad.interior.udelar.edu.uy/idp/profile/Status.
Entramos y si dice 'ok' en texto plano de que está todo bien!
(La url en local sería algo así: http://localhost:8080/idp/profile/Status).

Configuración de un mecanismo de autenticación

Un IdP Shibboleth soporta diferentes mecanismos de autenticación en un mismo momento. Un SP requiere usar uno de una lista de posibles métodos de auntenticación. Si el SP está configurado para un metodo provisto por el IdP, entonces se va a usar ese. Si no requiere ninguno en especial, entonces se va a usar el que está por defecto, identificado en la configuración relying party. Si el IdP no tiene configurado uno por defecto, se va a elegir el método de forma randómica. Por esto, es muy importante, tener cuidado en los siguientes cambios.

Configuramos la autenticación a través de usuario y password, utilizando el método Java Authentication and Authorization Service (JAAS).
Básicamente el usuario ingresará sus credenciales y las mismas serán autentificado contra el LDAP. Para esto, editar el archivo /opt/shibboleth-idp/conf/handler.xml:

Hay que desactivar el LoginHandler RemoteUser comentándolo:

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

Hay que activar el manejador UsernamePassword descomentandolo

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

Par terminar la configuración del JAAS del Shibboleth idp hay que agregar una directiva ShibUserPassAuth en la configuración. Ahora si hay que configurar la conexión con el servidor LDAP. Se puede definir una conexión ldaps (ldapUrl="ldaps://identidad.interior.udelar.edu.uy:636/") para mayor seguridad, pero para asegurarnos que funciona primero podemos arrancar con ldap común.

nano /opt/shibboleth-idp/conf/login.config
ShibUserPassAuth {
    edu.vt.middleware.ldap.jaas.LdapLoginModule required
    ldapUrl="ldap://identidad.interior.udelar.edu.uy:389/" 
    baseDn="ou=gente,dc=interior,dc=udelar,dc=edu,dc=uy" 
    bindDn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" 
    ssl="true" 
    bindCredential="<Password compartida español>";
};

Configuración avanzada de Shibboleth IdP:

En el Identity Provider la mayor parte de las funcionalidades son dirigidos por la información de los metadatos SAML. Ambos Sp e IdP deben conocer la metadata (configuración de datos usada) de la otra parte para poder comunicarse entre sí.

Shibboleth no almacena ningún atributo de usuarios por su cuenta, este los obtiene de almacenes de datos externos para suministrar la información de usuarios ha ser entregada. Estos atributos son traídos desde data sources usando Data Connectors, los cuales son configurables mediante el archivo /opt/shibboleth-idp/conf/attribute-resolver.xml

Hay que descomentar el DataConnector para el LDAP al final del archivo, utilizando los datos para conectarnos con nuestro servidor LDAP:

    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory" 
        ldapURL="ldap://identidad.interior.udelar.edu.uy:389/" 
        baseDN="ou=gente,dc=interior,dc=udelar,dc=edu,dc=uy" 
        principal="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" 
        principalCredential="<Password compartida español>">
        <dc:FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </dc:FilterTemplate>
    </resolver:DataConnector>

Hay que buscar en el archivo, los atributos que queremos hacer disponible para entregarselos al SP. Nosotros liberaremos los atributos Common Name (cn) and Surname (sn) descomentándolos:

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

    <resolver:AttributeDefinition xsi:type="ad:Simple" id="surname" sourceAttributeID="sn">
        <resolver:Dependency ref="myLDAP" />
        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:sn" />
        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.4" friendlyName="sn" />
    </resolver:AttributeDefinition>

Hay que configurar cuales atributos son enviadas al SP. Los cambios hechos en el attribute-resolver.xml tienen que ser reflejados en attribute-filter.xml.
Entonces se agrega esto en el último archivo, abajo de <AttributeFilterPolicy>:

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

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

Archivo de Log

FIXME: Para darle más LOG, hay que activar DEBUG en la conf
Para ver los errores registrados hay que hacer tail /opt/shibboleth/logs/idp-process.log

Referencias

[1] http://csrdu.org/blog/2011/07/04/shibboleth-idp-sp-installation-configuration/