Single Sign On (SSO) con KMKey

Es frecuente plantearse integrar KMKey con algun sistema de autentificación de usuarios tipo LDAP o Active Directory. En el presente artículo vamos a explicar cómo puede conseguirse que una instalación de KMKey detecte nuestro usuario de trabajo en el dominio (a través del navegador) y ni tan sólo nos pida password si ya nos hemos validado contra el dominio

1) Para ello lo primero que vamos a necesitar es instalar algunas librerías, y el producto SSOAuth, que podemos descargar usando subversion:

# Comprobar que disponemos de la rama non-free activada en nuestro /etc/apt/sources.list
su
apt-get install libldap-2.4-2 libldap2-dev libnss-ldap python-ldap
apt-get install krb5-clients krb5-config krb5-user libkrb5-dev libkrb53
libpam-krb5 libapache2-mod-auth-kerb libkadm55 libapache2-mod-fastcgi
libsasl2-gssapi-mit libsasl2-modules-gssapi-mit libsasl2-modules-ldap

su zope
cd /usr/local/kmkey/zope/Products/
svn co https://svn.forge.osor.eu/svn/kmkey/products/SSOAuth/trunk SSOAuth
/usr/local/kmkey/zope/bin/zopectl restart


2) Crear un usuario en al Active Directory / LDAP, con password que NO CADUQUE. No hace falta que sea administrador, pero si que tenga lectura sobre todas las ramas que necesiten autentificarse en KMKey


3) Entrar en el Zope Management Interfac (ZMI), ir a portal_directories, y añadir un "CPS LDAP Backing Directory" que se llame "members_ldap", con estas propiedades:

Schemas (old style - for backward compatibility) -> members_ldap
Additional schemas (new style - merged with the previous) -> members_readonly_entry_flag_true
Is the directory read-only? -> Marcado
ACL: entry create roles -> Manager
ACL: entry delete roles -> Manager
ACL: entry view roles -> Manager
ACL: entry edit roles -> Manager
Field for entry title -> cn
Fields with substring search -> cn givenName sn mail
Field for password (if authentication) -> userPassword
LDAP server -> IP del servidor LDAP
LDAP port -> 389
LDAP base -> CN=Users,DC=dominio,DC=win (este es el defecto, pero puede cambiar para cada LDAP)
LDAP scope -> SUBTREE
LDAP object classes (search) -> top, person
LDAP bind dn -> usuariocreado@DOMINI.WIN (corresponde al usuario creado en el punto 2)
LDAP bind password -> clave correspondiente al usuario creado en el punto 2
LDAP rdn attribute (create) -> sAMAccountName
LDAP object classes (create) -> top, person
Field that contains a list of sub entries id for hierarchical directory -> None
attr used as id for children_attr default is ldap_rdn_attr. -> cn
LDAP auto reconnect feature: maximum retry -> 1
LDAP auto reconnect feature: delay in seconds before retrying -> 60.0
LDAP network timeout in seconds for any request (0 means no limit) -> 0.0

Una vez hecho esto, se puede comprobar que funciona la conexión con el LDAP usando la pestaña "Search" del propio directory


4) Entrar de nuevo via ZMI, borrar el objeto "cookie_authentication" y crear en su lugar un objeto "Secure Auth" con nombre "secure_auth"

5) Crear usuarios KMKey a partir de usuarios LDAP. Los usuarios de KMKey, además de tener un registro en portal_directories, necesitan tener un contacto asociado, con toda una serie de propiedades que no estan disponibles en un LDAP. Es por ello que la mejor opción es programar un script de traspaso periódico de usuarios del LDAP hacia KMKey. Este script puede ponerse en el cron y ejecutarse mediante zope/bin/zopectl run script.py diariamente, y lo que va a hacer es crear una entrada de usuario KMKey para cada usuario LDAP, SIN traspasar nunca el password, que siempre va a validarse contra el controlador de dominio. El contenido del script variará en función de la estructura del LDAP origen. Se incluye aquí un ejemplo de script:

from AccessControl.SecurityManagement import newSecurityManager
from Testing.makerequest import makerequest
from Products.KMKeyCore.pattern import KMObjectCreationAdapter
user = app.kmkey.acl_users.getUser('manager').__of__(app.kmkey.acl_users)
newSecurityManager({}, user)
app = makerequest(app)
km = app.kmkey
ldap = km.portal_directories.members_ldap
entries = ldap._searchEntries(return_fields=['*'])
user_entries = [entry for (id, entry) in entries if entry['sAMAccountName'] and entry['sn']]
container = km.workspaces.kmkey
portal_type = 'KMKey Contact'
adapter = KMObjectCreationAdapter(container)
ti = km.portal_types.getTypeInfo(portal_type)
cat = km.portal_catalog
for entry in user_entries:
brains = cat(meta_type='KM Contact', username=entry['sAMAccountName'])
if len(brains) == 1:
print "Ya existe " + brains[0].username
else:
dm = ti.getDataModel(ob=None, proxy=None, context=container)
dm['language'] = 'es'
dm['email'] = entry['mail']
dm['phone'] = entry['telephoneNumber']
dm['sn'] = entry['sn']
dm['username'] = entry['sAMAccountName']
dm['givenName'] = entry['givenName']
adapter.createObject(portal_type, dm)

get_transaction().commit()


6) Compilar el modulo mod_ntlm para apache2

Se puede descargar libremente de internet. Cuesta un poco compilarlo, porque el Makefile apunta a apxs en lugar de apxs2. También deja cosas dentro de .libs/ que luego no encuentra. Se debe ir haciendolo manualmente, pasito a pasito, hasta que funcione y tengamos el módulo válido


7) Configurar Zope para que escuche también por fascgi


sudo mkdir /var/run/zope
sudo chown -R zope.zope /var/run/zope

vi /usr/local/kmkey/zope/etc/zope.conf
<fast-cgi>
address /var/run/zope/fcgi
</fast-cgi>


8) Configurar Apache.

Es importante el tema del /htdocs o el módulo de FastCGI no funciona

sudo mkdir /htdocs
sudo touch /htdocs/zope
sudo cp /home/earcon/nommaquina.keytab /etc/apache2/
cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/fastcgi.* .

Antes del VirtualHost:
FastCgiExternalServer /htdocs/zope -socket /var/run/zope/fcgi -pass-header Authorization -pass-header Cookie

Dentro del VirtualHost:

<Location /zope >
Allow from all
Order allow,deny
SetHandler fastcgi-script
</Location>

<Location /zope/kmkey/ >
AuthType NTLM
NTLMAuth on
NTLMAuthoritative on
NTLMDomain DOMINIO.WIN
NTLMServer cpd-dc1
Require valid-user
</Location>

# Para acceder SIN SSO

RewriteCond %{REQUEST_URI} !^/zope.*
RewriteRule ^/(.*) balancer://lb/VirtualHostBase/http//%{HTTP_HOST}:80/kmkey/VirtualHostRoot/$1 [L,P]



9) Verificar, en las estaciones clientes, que el Internet Explorer tiene activada la casilla de "Autentificacion Integrada en Windows" en las opciones avanzadas. También que el dominio de KMKey se encuentra dentro de la zona "Intranet Local", en la configuración de sitios de confianza

Si se usa Firefox, se puede activar poniendo en la barra de direcciones: about:config y en la nueva barra network.automatic-ntlm-auth.trusted-uris


10) Ya se puede entrar con SSO desde http://nombredominio/zope/kmkey

NOTA IMPORTANTE: Si se prueba desde fuera del dominio, al entrar el usuario y la clave manualmente, debe hacerse en el formato DOMINIO\usuario para que lo acepte

Etiquetas: