Objectiu
-
Donar una resposta a l’autenticació d’aplicacions a Cloud Públic, que s’integri amb l’Active Directori Corporatiu
-
Tecnològicament s’opta per containeritzar la solució, per facilitat de la configuració, proves i portabilitat de la solució
Imatges utilitzades:
- Docker Identity Provider - IdP (servidor): https://github.com/jtgasper3/docker-shibboleth-idp
- Docker Service Provider - SP (client): https://hub.docker.com/r/jtgasper3/centos-shibboleth-sp/
IdP - Identity Provider (servidor)
-
Construcció de la imatge a partir del projecte anterior:
$ docker build -t shibboleth-idp .
NOTA: abans de crear la imatge, tenir present el “host” que resoldrà el contenidor que arrenqui l’IDP. Paràmetre: -Didp.host.name=localhost
-
Per a personalitzar l’entorn IDP, és necessari arrencar el contenidor a partir de la imatge anterior amb un volum compartit amb el host per a poder recuperar els directoris de configuració que ens interessen.
$ docker run -d -p 443:443 -p 8443:8443 --name shibboleth-idp -v /home/shibboleth/idp/conf:/external-mount shibboleth-idp
Mentre no es disposi de contenidors i balancejadors amb IP i DNS assignats, pot ser necessari afegir els hosts a resoldre amb el flag –add-host de Docker.
-
Copiar els directoris que ens interessen del contenidor i que es troben a /opt/shibboleth-idp (conf, credentials, messages, metadata, views, webapp). Amb aquests directoris podrem personalitzar la nostra aplicació IDP
$ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/conf/ /external-mount $ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/credentials/ /external-mount $ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/messages/ /external-mount $ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/metadata/ /external-mount $ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/views/ /external-mount $ docker exec shibboleth-idp cp -R /opt/shibboleth-idp/webapp/ /external-mount
-
S’ha de modificar el fitxer /container_scripts/import.sh dins el projecte “Docker Identity Provider - IdP” per a que importi la webapp i messages, que no estan inclosos.
-
Fitxers de configuració i dades de configuració clau:
-
/conf/idp.properties
- idp.entityID= https://[host]/idp/shibboleth
-
/conf/metadata-providers.xml, amb el mecanisme que es vulgui per a recuperar les dades dels SP. Per exemple, per http amb filesystem backup:
<MetadataProvider id="gencatMetadata" xsi:type="FileBackedHTTPMetadataProvider" metadataURL="http://[host]/sp-metadata.xml" backingFile="%{idp.home}/metadata/sp-metadata.xml"> </MetadataProvider>
Si l’entorn on es posen els contenidors no té visibilitat directe a internet, es pot configurar un proxyhost i proxyport per a recuperar el fitxer de metadades. Exemple:
<MetadataProvider id="gencatMetadata" xsi:type="FileBackedHTTPMetadataProvider" metadataURL="http://[host]/sp-metadata.xml" backingFile="%{idp.home}/metadata/sp-metadata.xml" proxyHost="100.64.227.11" proxyPort="3128" > </MetadataProvider>
-
/conf/attribute-resolver.xml
<resolver:AttributeDefinition id="employeeId" xsi:type="ad:PrincipalName"> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeId" encodeType="false" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="employeeId" encodeType="false" /> </resolver:AttributeDefinition> <resolver:AttributeDefinition id="mail" xsi:type="ad:Simple" sourceAttributeID="mail"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mail" encodeType="false" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" encodeType="false" /> </resolver:AttributeDefinition> <resolver:AttributeDefinition id="CODIINTERN" xsi:type="ad:Simple" sourceAttributeID="sAMAccountName"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:sAMAccountName" encodeType="false" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.99" friendlyName="CODIINTERN" encodeType="false" /> </resolver:AttributeDefinition> <resolver:AttributeDefinition id="UNITAT_MAJOR" xsi:type="ad:Simple" sourceAttributeID="department"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:department" encodeType="false" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.2" friendlyName="UNITAT_MAJOR" encodeType="false" /> </resolver:AttributeDefinition> <resolver:AttributeDefinition id="UNITAT_MENOR" xsi:type="ad:Simple" sourceAttributeID="company"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:company" encodeType="false" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.98" friendlyName="UNITAT_MENOR" encodeType="false" /> </resolver:AttributeDefinition> <resolver:AttributeDefinition id="GICAR" xsi:type="ad:Template"> <resolver:Dependency ref="employeeId" /> <resolver:Dependency ref="mail" /> <resolver:Dependency ref="CODIINTERN" /> <resolver:Dependency ref="UNITAT_MAJOR" /> <resolver:Dependency ref="UNITAT_MENOR" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="https://gencat.cat/GICAR" friendlyName="GICAR" /> <ad:Template> <![CDATA[ CODIINTERN=${CODIINTERN};NIF=${employeeId};EMAIL=${mail};UNITAT_MAJOR=${UNITAT_MAJOR};UNITAT_MENOR=${UNITAT_MENOR} ]]> </ad:Template> <ad:SourceAttribute>employeeId</ad:SourceAttribute> <ad:SourceAttribute>mail</ad:SourceAttribute> <ad:SourceAttribute>CODIINTERN</ad:SourceAttribute> <ad:SourceAttribute>UNITAT_MAJOR</ad:SourceAttribute> <ad:SourceAttribute>UNITAT_MENOR</ad:SourceAttribute> </resolver:AttributeDefinition> <!-- ========================================== --> <!-- Data Connectors --> <!-- ========================================== --> <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory" ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}" baseDN="%{idp.attribute.resolver.LDAP.baseDN}" principal="%{idp.attribute.resolver.LDAP.bindDN}" principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}" useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:false}"> <dc:FilterTemplate> <![CDATA[ %{idp.attribute.resolver.LDAP.searchFilter} ]]> </dc:FilterTemplate> </resolver:DataConnector>
-
/conf/ldap.properties
idp.authn.LDAP.authenticator = bindSearchAuthenticator -------- idp.authn.LDAP.ldapURL = ldap://192.168.119.14:389 idp.authn.LDAP.useStartTLS = false idp.authn.LDAP.useSSL = false -------- ó -------- idp.authn.LDAP.ldapURL = ldaps://wndca08.prepdc.gencat.intranet:636 --> idp.authn.LDAP.useStartTLS = false idp.authn.LDAP.useSSL = true -------- #idp.authn.LDAP.connectTimeout = 3000 idp.authn.LDAP.sslConfig = certificateTrust idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt --> s'hauria de posar la ruta del certificat del ldap si estem anant per SSL --> el certificat s'ha d'importar des del directoris de configuració o bé injectar en la creació de la imatge idp.authn.LDAP.trustStore = %{idp.home}/credentials/ldap-server.truststore idp.authn.LDAP.returnAttributes = employeeId idp.authn.LDAP.baseDN = ou=Persones,ou=DIRECTORI,dc=prepdc,dc=gencat,dc=intranet idp.authn.LDAP.userFilter = (employeeId={user}) idp.authn.LDAP.bindDN = SMAdmin@prepdc.gencat.intranet idp.authn.LDAP.bindDNCredential = ******************************************** idp.authn.LDAP.dnFormat = %s@prepdc.gencat.intranet idp.attribute.resolver.LDAP.ldapURL = %{idp.authn.LDAP.ldapURL} idp.attribute.resolver.LDAP.baseDN = %{idp.authn.LDAP.baseDN} idp.attribute.resolver.LDAP.bindDN = %{idp.authn.LDAP.bindDN} idp.attribute.resolver.LDAP.bindDNCredential = %{idp.authn.LDAP.bindDNCredential} #idp.attribute.resolver.LDAP.useStartTLS = %{idp.authn.LDAP.useStartTLS:true} #idp.attribute.resolver.LDAP.trustCertificates = %{idp.authn.LDAP.trustCertificates} idp.attribute.resolver.LDAP.searchFilter = (employeeId=$requestContext.principalName) #idp.pool.LDAP.minSize = 3 #idp.pool.LDAP.maxSize = 10 #idp.pool.LDAP.validateOnCheckout = false #idp.pool.LDAP.validatePeriodically = true #idp.pool.LDAP.validatePeriod = 300 #idp.pool.LDAP.prunePeriod = 300 #idp.pool.LDAP.idleTime = 600 #idp.pool.LDAP.blockWaitTime = 3000 #idp.pool.LDAP.failFastInitialize = false
-
/conf/attribute-filter.xml
Utilitzarem el camp employeeId com a identificador de l’Active Directory.
<afp:AttributeFilterPolicy id="gencat_attrib_policy"> <afp:PolicyRequirementRule xsi:type="basic:ANY" /> <afp:AttributeRule attributeID="employeeId"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> <afp:AttributeRule attributeID="mail"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> <afp:AttributeRule attributeID="CODIINTERN"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> <afp:AttributeRule attributeID="UNITAT_MAJOR"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> <afp:AttributeRule attributeID="UNITAT_MENOR"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> <afp:AttributeRule attributeID="GICAR"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> </afp:AttributeFilterPolicy>
-
/conf/logback.xml si es volen canviar els nivell de log
-
/messages/* per a configurar els textos de l’aplicació
-
/metadata/idp-metadata.xml
- revisar que s’ha configurat correctament el host domain
- aquest fitxer s’ha de copiar als service providers
-
/views per a personalitzar les vistes de les diferents pantalles de l’aplicació
-
/webapp per a personalitzar la presentació de l’aplicació (css, imatges, …)
-
Un cop configurats aquests fitxers, cal fer
$ docker exec shibboleth-idp import.sh
per a reconstruir el idp.war i carregar la nova configuració. Caldrà reiniciar el contenidor.
$ docker restart shibboleth-idp
-
SP - Service Provider (client Apache)
-
Construcció de la imatge a partir del projecte:
$ docker build -t shibboleth-sp .
-
Arrencar el contenidor
$ docker run -d -p 81:80 -v /home/shibboleth/sp/conf:/tmp --name shibboleth-sp shibboleth-sp
-
Copiar fitxers de configuració per a poder adaptar-los
$ docker exec shibboleth-sp cp /etc/shibboleth/shibboleth2.xml /tmp $ docker exec shibboleth-sp cp /etc/shibboleth/attribute-map.xml /tmp
-
Copiar el fitxer idp-metadata.xml de l’IDP a la ruta que estigui configurada al fitxer shibboleth2.xml
-
shibboleth2.xml
-
modificar les uris i entityId que apuntin a l’IDP: https://[idp host]/idp/shibboleth
-
adaptar el metadata provider segons les necessitats (en aquest exemple s’han deshabilitat les propietats de signatura):
<MetadataProvider type="XML" validate="true" uri="https://[idp-host]/idp/shibboleth" backingFilePath="/tmp/idp-metadata.xml" reloadInterval="7200"> <!--MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/--> <!--MetadataFilter type="Signature" certificate="idp-cert.pem"/--> <!--DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" attributeName="http://macedir.org/entity-category" attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" attributeValue="http://refeds.org/category/hide-from-discovery" /--> </MetadataProvider>
-
Modificar el REMOTE_USER amb el valor GICAR_ID:
<ApplicationDefaults entityID="https://sp1.locahost/shibboleth" REMOTE_USER="GICAR_ID">
-
-
attribute-map.xml
-
Com que estem optant pel employeeId com a camp de l’AD a utilitzar, necessitem afegir les següents línies (posem com a id “GICAR_ID”, que és la capçalera actual de GICAR):
<Attribute name="urn:mace:dir:attribute-def:employeeId" id="GICAR_ID" /> <Attribute name="urn:oid:0.9.2342.19200300.100.1.1" id="GICAR_ID" /> <Attribute name="urn:mace:dir:attribute-def:mail" id="mail" /> <Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail" /> <Attribute name="urn:mace:dir:attribute-def:sAMAccountName" id="CODIINTERN" /> <Attribute name="urn:oid:0.9.2342.19200300.100.1.99" id="CODIINTERN" /> <Attribute name="urn:mace:dir:attribute-def:department" id="UNITAT_MAJOR" /> <Attribute name="urn:oid:0.9.2342.19200300.100.1.2" id="UNITAT_MAJOR" /> <Attribute name="urn:mace:dir:attribute-def:company" id="UNITAT_MENOR" /> <Attribute name="urn:oid:0.9.2342.19200300.100.1.98" id="UNITAT_MENOR" /> <Attribute name="https://gencat.cat/GICAR" id="GICAR" />
Tenint present que estem agafant la referència de l’uid, aquest camp no hauria d’estar activat.
-
-
Obtenir el fitxer de metadata per a informar al IDP (no utilitzar localhost!!!)
http(s)://[service provider host]/Shibboleth.sso/Metadata
-
El fitxer recuperat, s’hauria d’afegir al fitxer complet de metadata que recupera l’IDP.
Tips and tricks
-
Configurar els contenidors amb un DNS. En arrencar contenidors de prova
$ docker run -d -p 80:80 --name shibboleth-sp --add-host idp.extranet.gencat.cat:172.17.0.2 -v $BASE_PATH/Dockers/docker-images/centos-shib-sp/conf/:/tmp/ jtgasper3/centos-shibboleth-sp
-
En recuperar la metadata del SP, fer-ho amb el DNS assignat.
-
Exemple de fitxer de metadata complet, amb el idp-metadata i dos sp-metadata: https://dl.dropboxusercontent.com/u/17397489/idp/metadata.xml
TODO
-
Modificar l’interval de refresc del fitxer configurat a IDP/conf/metadata-providers.xml
-
Possibilitats de clúster
-
Traduïr els fitxers de configuració a català
-
Evitar que surti el missatge de redirecció a l’aplicació SP