2008-12-02 12 views
42

Próbowałem podłączyć aplikację Rails do ActiveDirectory. Będę synchronizować dane o użytkownikach między AD a bazą danych, obecnie MySQL (ale może zmienić się w SQL Server lub PostgreSQL).LDAP przez Ruby lub Railsy

Sprawdziłem activedirectory-ruby i wygląda na bardzo buggy (w wersji 1.0 !?). Łączy Net :: LDAP, więc próbowałem go użyć zamiast tego, ale jest naprawdę bliski rzeczywistej składni LDAP, a ja czerpałem przyjemność z abstrakcji ActiveDirectory-Ruby z powodu jej składni podobnej do ActiveRecord.

Czy istnieje narzędzie typu ORM dla serwera katalogów? Co więcej, gdyby istniało jakieś narzędzie do rusztowania dla LDAP (CRUD dla użytkowników, grup, jednostek organizacyjnych itd.). Wtedy mógłbym szybko zintegrować to z moim istniejącym kodem uwierzytelniającym za pomocą Authlogic i zachować wszystkie dane zsynchronizowane.

Odpowiedz

38

Oto przykładowy kod używam z net-ldap gem do weryfikacji danych logowania użytkownika z serwera ActiveDirectory w mojej pracy:

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 

Kod first.displayName.first na końcu wygląda trochę głupkowaty, a więc może korzystać z niektórych wyjaśnienie:

  • Net::LDAP#search zawsze zwraca tablicę wyników, nawet jeśli kończy się dopasowując tylko jedną pozycję. Pierwsze wywołanie first znajduje pierwszy (i prawdopodobnie tylko) wpis, który pasował do adresu e-mail.

  • Opcja Net::LDAP::Entry zwrócona przez wyszukiwanie wygodnie umożliwia dostęp do atrybutów za pośrednictwem nazwy metody, dzięki czemu some_entry.displayName jest taka sama jak some_entry['displayName'].

  • Każdy atrybut w Net::LDAP::Entry jest zawsze tablicą wartości, nawet jeśli obecna jest tylko jedna wartość. Chociaż może być głupio mieć użytkownika z wieloma wartościami "displayName", ogólny charakter LDAP oznacza, że ​​jest to możliwe. Ostateczne wywołanie przekształca łańcuch-jednego-łańcucha w ciąg znaków dla pełnej nazwy użytkownika.

+0

Dzięki za spóźnioną odpowiedź. Nie potrzebuję już tych informacji, ale ta składnia wygląda niesamowicie, a DUŻO krótsza niż to, w jaki próbowałem to zrobić. Dzięki jeszcze raz! – Judy

+1

Dzięki za wysłanie tego. Uderzyłem w ścianę tylko dlatego, że nie zawierałem @ company.com dla nazwy użytkownika. Twój post kazał mi podążać we właściwym kierunku. –

1

Czy sprawdziłeś ldap-activerecord-gateway thinkbota? To może być coś do rozważenia ...

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

+0

Hmm. Wciąż próbuję zrozumieć, co to może dla nas zrobić. Zasadniczo powinienem uruchomić ten serwer LDAP podczas uruchamiania aplikacji rails. Następnie, jeśli istnieje sposób na replikację danych między tym a rzeczywistym serwerem AD, zrób to. Następnie użyj mojego serwera LDAP dla danych. Czy to ma sens? – Judy

8
+5

mrT - Wiele linków, które prawdopodobnie kiedyś działały w twojej odpowiedzi, jest teraz uszkodzonych. Czy możesz być przekonany, aby je zaktualizować? Z góry dziękuję. –

+1

nowy sposób uwierzytelniania za pomocą łącza ldap: http://wiki.rubyonrails.org/rails/pages/howtoauthenticatewithynynldldap –

4

To więcej niepotwierdzone niż prawdziwą odpowiedź. ..

Miałem podobne doświadczenie przy użyciu Samby i serwera OpenLDAP. Nie mogłem znaleźć biblioteki, która naprawdę zrobiłaby to, co chciałem, więc stworzyłem własne klasy pomocników.

Użyłem ldapbrowser, aby zobaczyć, jakie pola wypełnił Samba, gdy utworzyłem użytkownika w "oficjalnym" stylu i zasadniczo go zduplikowałem.

Jedynym haczykiem/niestandardowa rzecz LDAP był szalony szyfrowanie hasła mamy:

UserPass:

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

sambaNTPassword:

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

dla funkcji def authenticate(user, pass) staram się pobierz LDAP, aby powiązać się z domeną przy użyciu ich poświadczeń, jeśli zgłoszę wyjątek, logowanie się nie powiodło, w przeciwnym razie wpuść je.

+0

+1 Dziękuję, szukałem sposobu na wygenerowanie hasha hasła hash w ruby ​​:) – chmeee

+1

uratowałeś cztery życia dzisiaj. – nurettin

2

Zacząłem używać ruby-activedirectory, a nawet rozszerzyłem/naprawiłem kilka rzeczy, hostując judy-activedirectory w Github.

W następnej iteracji odkryłem, że ActiveLdap ma znacznie lepszą podstawę kodu i poważnie zastanawiam się, jak ją zmienić. Czy ktoś ma osobiste doświadczenia z tym?

+0

+1 dla ruby-activedirectory – chmeee

2

Przepraszamy, nie możemy jeszcze komentować ... może ktoś może odpowiednio to przenieść.

@ rozwiązanie Phrogz za dobrze, ale bind_simple (wewnątrz wiążą) podnosi wyjątek Net :: LDAP :: LdapError powodu auth [: nazwa użytkownika] nie jest ustawiony, jak pokazano tutaj:

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

skorygowane zastępuje:

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

z:

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

Nawiasem mówiąc, możesz edytować posty innych osób - zmiany trafią do kolejki Sugerowane zmiany, w której dwie osoby mogą potwierdzić lub odmówić, że edycja jest dobra. :) – sarnold