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.

Moje pytanie dotyczy Uwierzytelnianie NTLM lub Kerberos, gdy nie jestem za Apache, używając tylko Thin i Sinatra. Widziałem rack-NTLM , ale szczegóły użytkowania są niezwykle rzadkie.

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ć.

Author: Phrogz, 2011-04-16

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.

Oto kod.

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.

 9
Author: rekado,
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.

 7
Author: lusis,
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ą.

 2
Author: TomWardrop,
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.

 1
Author: Rob Di Marco,
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.

 1
Author: Roman,
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
 0
Author: peter,
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