LDAP через Ruby или Rails
Я пытаюсь подключить приложение Rails до ActiveDirectory. Я буду синхронизировать данные о пользователях между AD и базой данных, в настоящее время MySQL (но может превратиться в SQL Server или PostgreSQL).
Я проверил activedirectory-ruby, и он выглядит действительно ошибкой (для версии 1.0!?). Он обертывает Net:: LDAP, поэтому я попытался использовать это вместо этого, но он действительно близок к фактическому синтаксису LDAP, и мне понравилась абстракция ActiveDirectory-Ruby из-за синтаксиса, подобного ActiveRecord.
Есть ли элегантный инструмент ORM-типа для сервера каталогов? Еще лучше, если для LDAP (CRUD для пользователей, групп, организационных подразделений и т.д.) Есть какой-то инструмент для лесов. Затем я мог бы быстро интегрировать это с моим существующим кодом аутентификации, хотя Authlogic, и сохранить все данные синхронизированными.
Ответы
Ответ 1
Вот пример кода, который я использую с net-ldap, чтобы проверить учетные записи пользователей на сервере ActiveDirectory при работе:
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 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
Код first.displayName.first
в конце выглядит немного тупой, и поэтому может получиться некоторое объяснение:
-
Net::LDAP#search
всегда возвращает массив результатов, даже если вы закончите сопоставление только одной записи. Первый вызов first
находит первую (и предположительно только) запись, которая соответствует адресу электронной почты.
-
Net::LDAP::Entry
, возвращаемый поиском, позволяет вам обращаться к атрибутам через имя метода, поэтому some_entry.displayName
совпадает с some_entry['displayName']
.
-
Каждый атрибут в Net::LDAP::Entry
всегда представляет собой массив значений, даже если присутствует только одно значение. Хотя было бы глупо иметь пользователя с несколькими значениями "displayName", общий характер LDAP означает, что это возможно. Окончательный вызов first
превращает массив из одной строки в строку только для полного имени пользователя.
Ответ 2
Вы пробовали посмотреть на них:
http://saush.wordpress.com/2006/07/18/rubyrails-user-authentication-with-microsoft-active-directory/
http://xaop.com/blog/2008/06/17/simple-windows-active-directory-ldap-authentication-with-rails/
Ответ 3
Это более анекдотично, чем реальный ответ...
У меня был аналогичный опыт с использованием Samba и OpenLDAP-сервера. Я не мог найти библиотеку, чтобы действительно делать то, что хотел, поэтому я перевернул свои собственные классы-помощники.
Я использовал ldapbrowser, чтобы увидеть, какие поля заполняли Samba, когда я создал пользователя "официальный" способ и в основном дублировал это.
Единственной сложной/нестандартной версией LDAP было сумасшедшее шифрование паролей:
UserPass:
"{MD5}" + Base64.encode64(Digest::MD5.digest(pass))
sambaNTPassword:
OpenSSL::Digest::MD4.hexdigest(Iconv.iconv("UCS-2", "UTF-8", pass).join).upcase
Для функции def authenticate(user, pass)
я пытаюсь заставить LDAP связываться с доменом, используя свои учетные данные, если я поймаю исключение, тогда логин завершился неудачно, в противном случае разрешите их.
Ответ 4
Я начал использовать ruby-activedirectory и даже расширил его/исправил несколько вещей, разместив Judy-activedirectory в Github.
Выполняя следующую итерацию, я обнаружил, что ActiveLdap имеет гораздо лучшую базу кода, и я серьезно задумываюсь о ее переключении. Кто-нибудь имеет личный опыт в этом?
Ответ 5
Извините, не могу комментировать... возможно, кто-то может переместить это соответствующим образом.
Решение @Phrogz работает хорошо, но bind_simple (внутри bind) вызывает исключение Net:: LDAP:: LdapError из-за того, что auth [: username] не устанавливается, как показано здесь:
https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb
Исправлено:
auth: { method: :simple, email: email, password:password }
с:
auth: { method: :simple, username: email, password:password }
Ответ 6
Вы проверили ldap-activerecord-gateway? Это может быть что-то для вас...
http://github.com/thoughtbot/ldap-activerecord-gateway/tree/master