2008-12-02 20 views
42

He intentado conectar una aplicación de Rails a ActiveDirectory. Estaré sincronizando datos sobre usuarios entre AD y una base de datos, actualmente MySQL (pero puede convertirse en SQL Server o PostgreSQL).LDAP a través de Ruby o Rails

He comprobado activedirectory-ruby, y parece realmente defectuoso (para una versión 1.0 !?). Cubre Net :: LDAP, así que traté de usarlo, pero está muy cerca de la sintaxis real de LDAP, y disfruté de la abstracción de ActiveDirectory-Ruby debido a su sintaxis similar a ActiveRecord.

¿Hay una herramienta elegante de tipo ORM para un servidor de directorio? Mejor aún, si existiera algún tipo de herramienta de andamiaje para LDAP (CRUD para usuarios, grupos, unidades organizativas, etc.). Luego podría integrarlo rápidamente con mi código de autenticación existente a través de Authlogic, y mantener todos los datos sincronizados.

Respuesta

38

Aquí es código de ejemplo que utilizo con la net-ldap joya para verificar los inicios de sesión de usuario desde el servidor ActiveDirectory en mi trabajo:

require 'net/ldap' # gem install net-ldap 

def name_for_login(email, password) 
    email = email[/\A\w+/].downcase # Throw out the domain, if it was there 
    email << "@mycompany.com"  # I only check people in my company 
    ldap = Net::LDAP.new(
    host: 'ldap.mycompany.com', # Thankfully this is a standard name 
    auth: { method: :simple, email: email, password:password } 
) 
    if ldap.bind 
    # Yay, the login credentials were valid! 
    # Get the user's full name and return it 
    ldap.search(
     base:   "OU=Users,OU=Accounts,DC=mycompany,DC=com", 
     filter:  Net::LDAP::Filter.eq("mail", email), 
     attributes: %w[ displayName ], 
     return_result:true 
    ).first.displayName.first 
    end 
end 

El código first.displayName.first al final parece un poco tonto, y así podría beneficiarse de algunas explicación:

  • Net::LDAP#search siempre devuelve un conjunto de resultados, incluso si al final de juego sólo una entrada. La primera llamada al first encuentra la primera (y presumiblemente única) entrada que coincide con la dirección de correo electrónico.

  • El Net::LDAP::Entry devuelto por la búsqueda convenientemente le permite acceder a través de atributos nombre del método, por lo some_entry.displayName es lo mismo que some_entry['displayName'].

  • Cada atributo en un Net::LDAP::Entry es siempre una matriz de valores, incluso cuando solo hay un valor presente. Aunque podría ser una tontería tener un usuario con múltiples valores "displayName", la naturaleza genérica de LDAP significa que es posible. La invocación final first convierte la matriz de una cadena en la cadena para el nombre completo del usuario.

+0

Gracias por la respuesta tardía. Ya casi no necesito esta información, pero esta sintaxis se ve estelar, y MUCHO más corta que la forma en que estaba tratando de hacerlo. ¡Gracias de nuevo! – Judy

+1

Gracias por publicar esto. Había estado golpeando una pared simplemente porque no estaba incluyendo @company.com para el nombre de usuario. Tu publicación me ayudó a ir en la dirección correcta. –

1

¿Has comprobado el ldap-activerecord-gateway de thoughtbot? Puede ser que sea algo para que usted considere ...

http://github.com/thoughtbot/ldap-activerecord-gateway/tree/master

+0

Hmm. Todavía estoy tratando de entender qué podría hacer esto por nosotros. Esencialmente, comenzaría este servidor ldap al iniciar la aplicación de rieles. Entonces, si hay una forma de replicar datos entre este y el servidor AD real, haz eso. Luego usa mi servidor ldap para datos. ¿Eso tiene sentido? – Judy

8
+5

mrT - Muchos de los enlaces que presuntamente alguna vez funcionaron en su respuesta ahora están rotos. ¿Podría persuadirse para actualizarlos? Gracias por adelantado. –

+1

nuevo cómo autenticarse con el enlace ldap: http://wiki.rubyonrails.org/rails/pages/howtoauthenticatewithrubynetldap –

4

esto es más anecdótico que una respuesta real. ..

Tuve una experiencia similar al usar Samba y el servidor OpenLDAP. No pude encontrar una biblioteca que realmente hiciera lo que quería, así que rodé mis propias clases de ayuda.

Usé ldapbrowser para ver qué campos llenó Samba cuando creé un usuario de la manera "oficial" y básicamente dupliqué eso.

Lo único LDAP complicado/no estándar era el cifrado de la contraseña loca tenemos:

userpass:

"{MD5}" + Base64.encode64(Digest::MD5.digest(pass)) 

sambaNTPassword:

OpenSSL::Digest::MD4.hexdigest(Iconv.iconv("UCS-2", "UTF-8", pass).join).upcase 

para la función def authenticate(user, pass) intento hacer que LDAP se vincule al dominio usando sus credenciales, si capturo una excepción, entonces el inicio de sesión falló; de lo contrario, déjalos entrar.

+0

+1 Gracias, estaba buscando una forma de generar un hash de contraseña nt en ruby ​​:) – chmeee

+1

has salvado cuatro vidas hoy. – nurettin

2

Empecé a usar ruby-activedirectory, e incluso lo extendí/arreglé algunas cosas, alojando el directorio de acty-judy en Github.

Haciendo la siguiente iteración, descubrí que ActiveLdap tiene una base de código mucho mejor, y estoy considerando seriamente cambiar a ella. ¿Alguien tiene experiencia personal con esto?

+0

+1 para ruby-activedirectory – chmeee

2

Lo siento, todavía no puedo comentar ... quizás alguien pueda reubicar esto apropiadamente.

@ solución de Phrogz funciona bien, pero bind_simple (dentro bind) genera una excepción Net :: LDAP :: LdapError debido a la autenticación [: nombre de usuario] no está ajustado como se muestra aquí:

https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb

El sustituye corregidos:

auth: { method: :simple, email: email, password:password } 

con:

auth: { method: :simple, username: email, password:password } 
+0

Por cierto, puede editar las publicaciones de otras personas: las ediciones entrarán en la lista de ediciones sugeridas, donde dos personas pueden confirmar o rechazar la edición. :) – sarnold

Cuestiones relacionadas