ruby on rails - LDAP a través de Ruby o Rails
ruby-on-rails active-directory (6)
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).
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.
¿Has echado un vistazo a ldap-activerecord-gateway de thoughtbot? Puede ser algo para que consideres ...
http://github.com/thoughtbot/ldap-activerecord-gateway/tree/master
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.
Utilicé ldapbrowser para ver qué campos rellenó Samba cuando creé un usuario de la manera "oficial" y básicamente dupliqué eso.
Lo único LDAP complicado / no estándar fue el enloquecido cifrado de contraseñas que tenemos:
contraseña de usuario:
"{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 de def authenticate(user, pass)
, intento que LDAP se vincule al dominio usando sus credenciales, si capturo una excepción, el inicio de sesión falla; de lo contrario, los dejo entrar.
Comencé a usar ruby-activedirectory, e incluso lo extendí / arreglé algunas cosas, alojando el directorio de Judy-activedirectory en Github.
Al hacer 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?
Aquí está el código de muestra que uso con la gema net-ldap para verificar los inicios de sesión del usuario del 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 first.displayName.first
código first.displayName.first
al final parece un poco ridículo, por lo que podría beneficiarse de alguna explicación:
Net::LDAP#search
siempre devuelve una matriz de resultados, incluso si termina haciendo coincidir solo una entrada. La primera llamada alfirst
encuentra la primera (y supuestamente única) entrada que coincide con la dirección de correo electrónico.Net::LDAP::Entry
devuelta por la búsqueda le permite acceder de forma conveniente mediante el nombre del método, por lo quesome_entry.displayName
es igual quesome_entry[''displayName'']
.Cada atributo en una entrada
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. Lafirst
invocación final convierte la matriz de una cadena en la cadena para el nombre completo del usuario.
Lo siento, todavía no puedo comentar ... quizás alguien pueda reubicar esto de manera apropiada.
La solución de @ Phrogz funciona bien, pero bind_simple (enlace interno) genera una excepción Net :: LDAP :: LdapError debido a que auth [: username] no se establece como se muestra aquí:
https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb
El remplazado corregido:
auth: { method: :simple, email: email, password:password }
con:
auth: { method: :simple, username: email, password:password }