Uwierzytelnianie serwera jednokrotnego logowania w Ruby/Rack
Piszę i hostuję aplikacje internetowe na serwerach Windows do użytku w intranecie. Mój stos serwerów używa Sinatry (która używa Racka), Thin i (w niektórych przypadkach) Apache tylko do odwrotnego proxy.
Chcę obsługiwać jednokrotne logowanie (za pomocą NTLM lub Kerberos) w naszej domenie wspieranej przez ActiveDirectory. Widziałem, że mogę użyć mod_ntlm
lub mod_auth_kerb
Kiedy jestem za Apache, aby wykonać moje uwierzytelnianie NTLM. Jeszcze tego nie próbowałem, ale zakładam, że zadziała.
Proszę podać znany-działający kod Pod Sinatrą lub Rackiem, który pokazuje jak używać NTLM lub Kerberos po stronie serwera , uwierzytelniając się za pomocą ActiveDirectory (prawdopodobnie przez net-ldap
).
Edit : wyraźna pomoc, o którą prosi to pytanie. Użytkownicy powinni być w stanie znaleźć tę odpowiedź i mieć działające rozwiązanie, a nie wskaźniki do zewnętrznych bibliotek, z których muszą dowiedzieć się, jak korzystać.
6 answers
Napisałem Rack::Auth
moduł implementujący NTLM SSO. Może to trochę trudne, ale działa na mnie. Robi wszystkie te wyzwania / odpowiedzi, które są wymagane dla NTLM i ustawia REMOTE_USER
na to, co przesłała przeglądarka.
Aby to działało, przeglądarka musi być skonfigurowana do wysyłania rzeczy NTLM na serwer. W moim środowisku stało się to tylko wtedy, gdy adres serwera znajdował się na liście zaufanych domen. W przypadku Firefoksa domena musi zostać dodana do listy przypisany do klucza network.automatic-ntlm-auth.trusted-uris
, do którego można uzyskać dostęp poprzez about:config
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-09 05:19:51
Chociaż nie mam żadnego kodu do udostępnienia i nie mam serwera reklamowego do testowania, opublikuję kilka ogólnych informacji, które inni mogą znaleźć pomocne podczas korzystania z rack-ntlm (co byłoby najlepszą trasą w tym momencie).
Pierwszą rzeczą do zrozumienia jest to, że NTLM nigdy nie podaje hasła użytkownika. Nie musisz uwierzytelniać użytkownika wewnątrz aplikacji. NTLM już to zrobił. Co rack-ntlm da ci to domena + użytkownik, który możesz wtedy pracować z.
Rack-ntlm wykonuje dodatkową pracę z tymi informacjami, które mogą lub nie mogą być dla Ciebie cenne. Dostarczasz mu serwer reklamowy, port i zestaw poświadczeń. Weźmie ten obiekt użytkownika (z braku lepszego słowa) i odszukać je w AD poprzez wywołanie LDAP.
Poświadczenia, o które prosi rack-ntlm w Ustawieniach, będą twoimi poświadczeniami (lub optymalnie poświadczeniami specyficznymi dla aplikacji w domenie, które mają ograniczony dostęp do zapytań). Z tym zapytaniem, można by Odzyskaj dane tego użytkownika z reklamy(członkostwo w grupie, adresy e-mail, cokolwiek). Możesz użyć tego do dalszego wypełniania bazy danych danymi użytkownika.
Należy pamiętać, że jeśli używasz innej przeglądarki niż IE (a w niektórych przypadkach nawet z IE), użytkownicy otrzymają okno uwierzytelniania HTTP. W zależności od tego, czy Twoja witryna jest w "intranecie", czy nie, IE przejdzie automatycznie przez poświadczenia NTLM. Jest to kontrolowane na podstawie przeglądarki, więc może nie mieć żadnych Kontrola. W Firefoksie jest ustawienie "about: config", które pozwoli Ci zapełniać Zaufane witryny.
Więc jeśli wracamy do rack-ntlm, przepływ będzie wyglądał mniej więcej tak:
- browser - > sinatra app
- (wyzwanie ręczne / praca odpowiedzi
tutaj) - rack-ntlm wyszukuje teraz użytkownika w reklamie poprzez LDAP
- sinatra aplikacja ma teraz dane użytkownika z LDAP w jakimś hashu
- sinatra aplikacja tworzy użytkownika bazowego
- nazwa użytkownika sklepu (nie hasło
bo go nie masz) z jakimiś podstawowy zestaw umiejętności w lokalnym magazynie danych - sinatra ustawia cookie na "zalogowany" lub whatever
Jeśli chcesz, możesz mapować grupy reklam do ról aplikacji w pewnym zakresie, aby, powiedzmy, administratorzy domen automatycznie zostali dodani do twojej roli administratora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-26 20:44:19
Są ludzie, którzy odpowiadają na to pytanie dotyczące uwierzytelniania/bezpieczeństwa, którzy podają całkowicie fałszywe i wprowadzające w błąd informacje, które są potencjalnie bardzo niebezpieczne. NTLM jest procesem dwufazowym. Masz negocjację klient-serwer, która pobiera szczegóły od klienta, takie jak rzekomo nazwa użytkownika i token, który jest zaszyfrowany hash hasła użytkownika. Wiele osób uważa, że tak długo, jak można rozmawiać NTLM z klientem, jakoś uwierzytelnianie się stało. Mam nie mam pojęcia, dlaczego ludzie tworzą takie założenie, może dlatego, że proces ręcznego wstrząsania NTLM jest stosunkowo zawiły.
Jeśli zatrzymasz się po pierwszej fazie i nie wykonasz rzeczywistego uwierzytelniania, ufasz klientowi / użytkownikowi, w takim przypadku możesz równie dobrze nie wykonywać żadnego uwierzytelniania i po prostu umieścić komunikat "Proszę nie używać tej aplikacji internetowej, jeśli nie możesz".
Druga faza to rzeczywiste uwierzytelnianie. Serwer WWW przesyła dane podane przez Klienta (zaszyfrowany token) do kontrolera domeny. Kontroler domeny zna hash hasła użytkownika używanego do zaszyfrowania tokenu, a więc wykonuje to samo szyfrowanie hash hasła. Jeśli odpowiada wartości klienta, wtedy wiemy, że klient użył poprawnego hasha hasła. Serwer WWW nigdy nie widzi zaszyfrowanego hasła, widzi tylko token, który został zaszyfrowany za pomocą zaszyfrowanego hasła jako klucza szyfrowania.
Niestety, nie ma wielu bibliotek LDAP, które obsługują Możliwości NETLOGONA wymagane do autentykacji tokena NTLM, prawdopodobnie dlatego, że jest to nietrywialne gówno własnościowe. Samba (właściwie winbind) jest jedną z niewielu bibliotek, które mogą to zrobić. Obecnie nie ma biblioteki Ruby zdolnej do uwierzytelniania NTLM, chociaż istnieje wiele bibliotek, które dostarczą Ci nazwę użytkownika zgłoszoną przez klienta, chociaż klient może zgłosić dowolną nazwę użytkownika, którą lubi.
Zgodnie z zasadą, jeśli Biblioteka NTLM nie prosi o szczegóły kontrolera domeny, to nie ma mowy, aby robił jakikolwiek rodzaj uwierzytelniania. Wielu twórców tych prostych bibliotek nie ma pojęcia, co robią.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-18 05:52:51
Używam OmniAuth do uwierzytelniania z interfejsu LDAP ActiveDirectory. Dokumentacja jest całkiem dobra i łatwo zaczepia się w stojaku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-16 17:31:03
Z powodzeniem użyłem modułu Apache Kerberos, o którym wspomniałeś (http://modauthkerb.sourceforge.net/) Następnie prezentuje ten sam API, co basic auth, zapewniając jednocześnie wszystkie zalety Kerberos. Wystarczy użyć zwykłego stojaka:: Auth:: Basic i tyle.
Na zwykły Rack auth, możesz prawdopodobnie użyć https://github.com/djberg96/rack-auth-kerberos , ale osobiście nie próbowałem. Kod wygląda jednak prosto do przodu.
Oczywiście w obu przypadkach będziesz musiał wprowadzić swój serwer do reklamy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-22 22:43:01
Mam to działające bez rozwiązań rack i NTLM.
Dla uwierzytelniania zobacz moją odpowiedź tutaj: czy istnieje sposób, aby odczytać nazwę logowania klienta windows używając ruby on rails
Autoryzacja może być dokonana przez gem net-ldap poprzez sprawdzenie przynależności do grup bezpieczeństwa.
To działa tylko raz, gdy serwer / Usługa się uruchamia, tylko minusem jest to, że musisz ponownie uruchomić usługę, gdy członkowie grupy się zmienią. Można oczywiście zachować autoryzowanych użytkowników w tabeli bazy danych.
Oto Mój kod.W aplikacji Sinatra
require 'net-ldap'
HOST = "XXXXXX"
PORT = 389
LDAP = Net::LDAP.new(:host => HOST, :port => PORT)
# get account info somewhere safe
LDAP.auth(CONFIG.admin_user, CONFIG.admin_password)
if LDAP.bind
log "ldap logged in"
else
log "ldap login failed"
abort
end
# CONFIG.permitted_users is the name of the apps security group
$members = get_members CONFIG.permitted_users
Oraz w pliku pomocniczym
def get_ldap_username cn
treebase = "ou=xxxxxx,ou=xxxxxx,ou=xxxxxxx,ou=xxxxxx,dc=xxx,dc=xx"
filter = Net::LDAP::Filter.eq("cn", cn)
LDAP.search(:filter => filter, :base => treebase) do |item|
return item.sAMAccountName.first
end
end
def get_members name, members = []
treebase = "ou=xxxxxxx,ou=xxxxxxx,ou=xxxxxxx,ou=xxxxxx,dc=xxx,dc=xx"
filter = Net::LDAP::Filter.eq("cn", name)
LDAP.search(:filter => filter, :base => treebase) do |item|
item.each do |attribute, values|
if attribute == :member
values.each do |value|
cn = value[/CN=([^,]+),/,1]
# my groups all begin with a letter/number sequence
# recurse this method if member is a group itself
if cn[0..2].downcase == "xxx" # xxx something else of course
get_members cn, members
else
members << get_ldap_username(cn)
end
end
end
end
end
members # an array of permitted usernames
end
before do
# authentication code
# see https://stackoverflow.com/questions/5506932/is-there-a-way-to-read-a-clients-windows-login-name-using-ruby-on-rails/48407500#48407500
# authorisation
unless $members.include? @username
halt "No access"
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 17:55:32