Jak utworzyć usługę logowania współdzielonego w wielu domenach?

Interesuje mnie, jak wdrożyć wspólny system logowania między domenami, a także najlepsze praktyki i środki bezpieczeństwa do podjęcia. Jeśli znasz 37Signals, prawdopodobnie jesteś przyzwyczajony do ich używania wspólnego uniwersalnego mechanizmu uwierzytelniania, dzięki któremu nie musisz się logować, jeśli używasz nawigacji najwyższego poziomu do innego produktu. Chciałbym coś wdrożyć w podobny sposób.

Najbliższą rzeczą jaką znalazłem w Internecie jest Wpis w Wikipedii na centralnej usłudze uwierzytelniania i odpowiedzi na Cross Domain Login - Jak automatycznie zalogować się do użytkownika po przeniesieniu z jednej domeny do drugiej, co może być nieco inne w tym przypadku.

Sprawdziłem ich sesyjne pliki cookie, aby zrozumieć, co robią w tym procesie. Początkowo każdy link produktowy ma uristub "goto", czyli:

Https://MY_COMPANY.campfirenow.com/id/users/[int_identifier]/goto

Używając FireCookie i zakładki NET w Firebug, jestem w stanie zobaczyć pliki cookie, które są ustawione i przekierowania, które występują w procesie. Adres URL goto uruchamia przekierowanie 302 na:

Https://MY_COMPANY.basecamphq.com/login/authenticate?sig=[BASE64_ENCODED_AND_ENCRYPTED_DATA]

Identyfikator sesji jest odtwarzany, najprawdopodobniej dla celów CSRF. Niektóre dane w plikach cookie oraz parametrze GET Sig zostały częściowo odszyfrowane za pomocą base64_decode do:

// sig GET param
array(2) {
  [0]=>
���ף�:@marshal_with_utc_coercionT7�z��<k��kW"
  [1]=>
  string(18) "���k�<kn8�f���to��"
}

// _basecamp_session cookie session param
string(247) {
:_csrf_token"1Sj5D6jCwJKIxkZ6oroy7o/mYUqr4R5Ca34cOPNigqkw=:session_id"%060c0804a5d06dafd1c5b3349815d863"
flashIC:'ActionController::Flash::FlashHash{:
@used{: auth{"
              MY_COMPANY{:
                       user_idi�3
:identity_idi�W����������s�]��:�N[��:

�����"

Kodowanie łamie blok kodu. Dzięki za pomoc!

Author: Community, 2010-11-29

7 answers

Myślę, że kluczem w Twoim Q Jest to, że piszesz "dzięki czemu nie musisz się logować, jeśli używasz nawigacji najwyższego poziomu do innego produktu".

Wyjaśnię: Chcesz być w stanie przenieść się z site1.com na site2.com i niech site2.com wiedz, że jesteś jakimś użytkownikiem, który zalogował się za pośrednictwem site1.com.

Ponieważ pliki cookie nie są udostępniane pomiędzy różnymi domenami (innymi niż subdomeny, ale chyba nie mówisz o subdomenach), musisz przekazać pewne informacje na link do site2.com to pozwoli mu rozmawiać z zapleczem i wiedzieć, jakim użytkownikiem jesteś.

Zacznijmy od naiwnego rozwiązania, a następnie pracujemy na swój sposób, aby rozwiązać niektóre problemy, które stwarza: Załóżmy, że masz tabelę użytkowników na jakimś zapleczu DB i twój użytkownik ma jakiś identyfikator. teraz Załóżmy, że użytkownik uwierzytelniony na site1.com i jest użytkownikiem 123 z twojego DB. Najbardziej naiwnym rozwiązaniem byłoby wywołanie site2.com/url/whatever?myRealID=123 i niech site2 sprawdzi ten identyfikator i " belive" użytkownik, że to rzeczywiście on.

Problem: każdy (nawet prawidłowy użytkownik Twojej witryny), który zobaczy twój link, może utworzyć link z myRealID=123 lub spróbować innych wartości dla niego. oraz site2.com zaakceptuje go jako tego użytkownika.

Rozwiązanie: nie pozwala używać domyślnego identyfikatora Załóżmy, że dodasz do swojej tabeli użytkowników unikalny identyfikator GUID i jeśli użytkownik 123 ma identyfikator guid 8dc70780-15e5-11e0-ac64-0800200c9a66 to wywołaj site2.com/url/whatever?myGuid=8dc70780-15e5-11e0-ac64-0800200c9a66.

Nowy Problem: cóż nawet jeśli byłoby bardzo mało prawdopodobne, że ktoś zgadnie GUID Użytkownika jego GUID może nadal być porwany przez jakiegoś pośrednika, który widzi ten link i to ktoś dostanie guid może go używać na zawsze.

Rozwiązanie: użyj klucza prywatnego zapisanego na serwerze, aby podpisać łańcuch zawierający następujące pozycje danych, bieżący znacznik czasu, witrynę docelową (np. site2.com") wspomniany GUID, ten podpis można przetłumaczyć na powiedzenie " jest to dowód, że ten link został stworzony przez stronę w wspomniany czas dla użytkownika, który ma ten GUID do uwierzytelnienia przez tę domenę " i wysłać go do site2.com wraz ze znacznikiem czasu i GUID. Teraz kiedy site2.com dostaje link może upewnić się, że jest poprawnie podpisany i jeśli jakiś pośrednik lub pierwotnie użytkownik będzie próbował go zmienić w jakikolwiek sposób (albo moja modyfikacja czasu lub GUID) to podpis nie pasuje i site2.com odmówi uwierzytelnienia użytkownika.

Ostatni problem: jeśli link zostanie przechwycony przez pośrednika, może nadal używaj, jeśli z innej maszyny.

Rozwiązanie: dodaj nonce do podanych parametrów. Nonce jest tylko przypadkową liczbą, którą Twój system uwierzytelniania powinien upewnić się, że nie pozwala na uwierzytelnienie tym numerem więcej niż jeden raz (stąd nazwa N(umber)-ONCE). Zauważ, że oznacza to, że każdy link, który tworzysz na site1.com to prowadzi do site2.com powinien mieć odrębną nonce, która musi być zapisana w back-endzie do późniejszej walidacji.

Bo nie chcesz aby w nieskończoność dodawać rekordy do tej tabeli nonce, zwyczajem jest decydowanie, że takie łącze jest ważne tylko przez określony czas po jego utworzeniu. możesz więc tworzyć rekordy inne niż starsze niż ten limit czasu.

Mam nadzieję, że to jest zarys, którego szukasz. Możliwe, że coś przeoczyłem, ale to są podstawowe wytyczne, użyj podpisu, aby udowodnić autentyczność danych w linku i użyj nonce, aby zapobiec atakom pośredników. Polecam również korzystanie z HTTPS dla tych linków, jeśli to możliwe.

Eyal

 53
Author: epeleg,
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-01-01 20:52:23

Możesz spróbować zaimplementować Globalne Auto-Login rozwiązanie à la przepełnienie stosu.
Jest wnikliwy post dotyczący jego genialnej realizacji przez Kevina Montrose tutaj .

Wymagałoby to Plików cookie, HTML5 localStorage , Javascript, Iframe i wielu kontroli bezpieczeństwa, ale myślę, że warto.

 5
Author: systempuntoout,
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
2017-03-20 10:29:31

Facebook/OpenID/yahoo/Gmail / openID to dobry początek, ale to nie rozwiązuje problemu implementacji lub użycia własnego rozwiązania.

Po opracowaniu i zarządzaniu implementacją w przeszłości (ostatecznie poszliśmy w kierunku SiteMinder, ale zgaduję, że nie chcesz kosztować prawdziwego produktu), myślę, że Eyal ma bardzo dobry pomysł, ale dodałbym do niego trochę poprawek.

W momencie uwierzytelniania Wygeneruj losowy Kod (może to być wartość GUID, ale nie jest statyczna dla każdego użytkownika), która jest przechowywana w tabeli transakcyjnej wraz z identyfikatorem użytkownika. Ten kod ma maksymalną żywotność (musisz ocenić wartość bezpieczeństwa dla tego okresu). Kod ten byłby najlepiej zaszyfrowany nazwą użytkownika lub zaszyfrowany i wysyłany jako część adresu URL.

 1
Author: E Oslick,
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-01-04 23:09:08

Czy próbowałeś czegoś takiego jak Charles aby powąchać, co jest wysyłane tam iz powrotem? To może być w stanie zepsuć rzeczy jeszcze bardziej dla Ciebie.

Jak wspomniano przez FlipScript, może użycie OAuth / OpenID może być dla Ciebie drogą do przodu?

 0
Author: Chris Kimpton,
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
2017-05-23 12:26:17

Spójrz na Jasig CAS http://www.jasig.org/cas . Myślę, że zrobi to, co chcesz. To jest open source, i ma wiele wtyczek, które pozwalają na uwierzytelnianie używać wielu źródeł uwierzytelniania i z wielu domen / języków.

 0
Author: ehudokai,
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-01-04 19:08:12

Użyj czegoś takiego jak. Net Passport (tj. Windows Live Id) lub sposób, w jaki Facebook zrobił to za pomocą swojego API, które można otwarcie oglądać.

 0
Author: Joy To The World,
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-01-19 11:27:29

Dlaczego nie używać Open ID do tego celu.

OperID będzie optymalnym rozwiązaniem tego problemu.

 -1
Author: ,
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-01-05 12:56:56