Jak skonfigurować uwierzytelnienie w Drupalu przy użyciu OAuth2 i OpenID Connect

Jak skonfigurować uwierzytelnienie w Drupalu przy użyciu OAuth2 i OpenID Connect

W dobie coraz bardziej rozproszonej architektury aplikacji i portali internetowych zachodzi potrzeba zapewnienia elastycznych metod uwierzytelniania przy jednoczesnym zachowaniu wygody dla użytkownika. W artykule tym dowiesz się, jak łatwo stworzyć serwer uwierzytelniający i aplikację kliencką w Drupalu przy wykorzystaniu OAuth2 i OpenID Connect.

Rozproszone systemy, ich skalowanie i utrzymanie to problem wielu klientów, którzy przychodzą do naszej firmy w celu skorzystania z usług Drupal konsultingu. Bardzo często zachodzi potrzeba zaimplementowania centralnego systemu logowania dla wszystkich platform należących do szerszej federacji stron. Duże firmy i organizacje posiadają osobne portale - wielokrotnie dla nich tworzyliśmy strony wizerunkowe, systemy intranetowe, usługi Drupal Commerce z uwzględnieniem różnych funkcji. Konieczność rejestrowania osobnego konta i logowania się przez użytkowników w każdym miejscu z osobna wydaje się być archaicznym sposobem radzenia sobie z problemem. Kto z nas przecież na co dzień nie ułatwia sobie rejestracji na portalach internetowych chociażby przy wykorzystaniu szybkich metod rejestracji z użyciem konta na portalu społecznościowym czy profilu Google?

Dlaczego nie zrobić tego samego, zwłaszcza, że jak się za chwilę okaże, przy użyciu Drupala jest to banalnie proste.

OAuth2 i OpenID Connect

Aby rzucić nieco światła na cały problem, należy przede wszystkim skupić się na powszechnie stosowanych standardach w aplikacjach internetowych, które są używane w procesie uwierzytelnienia.

Pierwszy z nich to OAuth2, czyli otwarty standard przeznaczony do autoryzacji, który nie wymaga współdzielenia poświadczeń między aplikacjami. Dostęp do zasobów (o ile takich został przyznany) weryfikowany jest na podstawie tokenu wydawanego aplikacjom klienckim poprzez serwer autoryzacyjny.

Jako że OAuth2 został zaprojektowany z myślą o autoryzacji, czyli przyznawaniu określonego dostępu do jakichś zasobów, nie jest on tak naprawdę bezpośrednio przewidziany do ustandaryzowanego procesu uwierzytelniania (logowania) użytkowników. W tym celu zdecydowano się zaproponować dodatkową warstwę (uwierzytelniającą) do protokołu OAuth2, która standaryzuje w nim ten właśnie proces. Technologia ta to OpenID Connect i poza procesem logowania ujednolica ona także sposób wymiany danych o profilu użytkownika pomiędzy aplikacjami. Przyjrzymy się zatem, w jaki sposób obie technologie wykorzystać w praktyce.

Instalacja modułów

Jeśli chcemy skonfigurować zarówno serwer uwierzytelniania oparty o OAuth2 oraz aplikacje klienckie oparte o OpenID Connect, to w zasadzie w Drupalu możemy skorzystać z gotowych rozwiązań. W przypadku serwera mamy kilka możliwych modułów, w tym najpopularniejszy (simple_oauth). W naszym przykładzie użyjemy natomiast modułu OAuth2 Server. Cieszy się on nieco mniejszą popularnością oraz nie doczekał się jeszcze wydania stabilnego dla Drupala 8 i 9, ale za to wspierany jest przez znaczące firmy i organizacje związane z Drupalem.

Dodatkowo, drugi moduł do aplikacji klienckiej, OpenID Connect, to projekt utrzymywany i rozwijany przez dokładnie te same organizacje i zespół deweloperski. Możemy mieć zatem pewność, że oba projekty będą rozwijane symultanicznie i nie powstaną żadne problemy z ich zgodnością w późniejszym czasie.


Instalacja modułów przebiega standardowo. Najpierw należy pobrać i zainstalować moduły na naszym serwerze:

composer require drupal/oauth2_server
drush en oauth2_server -y && drush cr

Następnie analogicznie dla klienta:

composer require drupal/openid_connect
drush en openid_connect -y && drush cr

Główną zależnością potrzebną do instalacji serwera jest biblioteka oauth2-server-php dostarczająca podstawowe mechanizmy do pełnienia roli właśnie tej roli. Jeżeli korzystasz z Composer w PHP, to wszystkie zależności są już rozwiązywane za Ciebie automatycznie.

Konfiguracja serwera

Moduł OAuth2 Server bazuje w większości swojej konfiguracji na encjach. W związku z tym dostarcza on między innymi encję serwera, klienta, tokenu, itd. Naszą konfigurację musimy zacząć od zdefiniowania serwera. Przechodzimy zatem do strony konfiguracyjnej /admin/structure/oauth2-servers.

Lista serwerów

I dodajemy nowy serwer (Add Server). W kolejnym kroku widzimy formularz encji serwera:

Formularz konfiguracji serwera

W najprostszym wariancie konfiguracyjnym zostawiamy wszystkie domyślnie zaznaczone i wypełnione wartości. Ponadto zaznaczamy opcję "Use OpenID Connect" jako domyślnej warstwy wykorzystywanej w procesie logowania.


Jak widać z ustawień, proces uwierzytelniania i autoryzacji odbywa się bez użycia danych uwierzytelniających przesyłanych przez klienta, lecz na podstawie kodu autoryzacyjnego - wymienianego potem na kod dostępu (access token) i tokenu odświeżania (refresh token), które są wymieniane w toku komunikacji pomiędzy aplikacjami. Szczegóły techniczne protokołu OAuth2 wykraczają dalece poza zakres tego artykułu, dlatego jeśli chcesz wiedzieć więcej na temat tego, jak działają poszczególne opcje i sam protokół, to możesz to zrobić korzystając z oficjalnej dokumentacji.

W kolejnym kroku powinniśmy zdefiniować klientów, którzy mogą podłączać się do naszego serwera. Musimy jednak do tego celu posiadać przynajmniej jedną aplikację kliencką.

Konfiguracja klienta

OpenID Connect to moduł bardzo przyjazny także od strony konfiguracyjnej. Aby skonfigurować klientów, których chcemy używać, należy przejść na stronę /admin/config/services/openid-connect

Konfiguracja OpenID Connect

Jak widać, w formularzu widnieje lista klientów. Moduł pozwala zatem w łatwy sposób logować się przy wykorzystaniu np. znanych portali społecznościowych. Każdy z typów klientów definiowany jest jako osobny plugin (OpenIDConnectClient), co daje łatwość rozszerzania projektu o zupełnie nowych klientów. W naszym przykładzie chodzi jednak o podłączenie się do własnego serwera, dlatego skorzystamy z klienta do ogólnych zastosowań (Generic).

Konfiguracja jest dość prosta, gdyż polega na zdefiniowaniu nazwy klienta oraz klucza tzw. secret oraz podania adresów serwera:

Konfiguracja klienta ogólnego

Przy okazji dodamy sobie jeszcze małe usprawnienie, a mianowicie podmienimy formularz logowanie na przycisk z logowaniem za pomocą naszego serwera autoryzacyjnego. Jest to banalnie proste i dostępne z formularza konfiguracyjnego:

Opcje przycisku

Świetnie! Klient wygląda na gotowy do użycia. Jedyny mankament to brak wygodnej na ten moment możliwości zmiany nazwy "Generic" bez odrobiny kodowania, ale rezultat i tak wygląda świetnie jak na tak szybka konfigurację:

Login form

Konfiguracja serwera część druga

Mamy wstępnie skonfigurowany serwer, a także gotowego klienta. Zdefiniujmy zatem naszego klienta w konfiguracji serwera, tak aby wiedział on, że może ona się do niego podłączać i żądać o dostęp do jego zasobów. Drupal to bardzo bezpieczny CMS na tle konkurencji, ale podstawa bezpieczeństwa leży też w poprawnej jego konfiguracji.

Pamiętaj zawsze, że to od Ciebie zależy weryfikacja i konfiguracja tego, jakie aplikacje klienckie powinny mieć możliwość podłączania się do serwera i korzystania z jego zasobów.

W celu dodania nowych klientów musimy udać się do zakładki Clients, a następnie kliknąć w przycisk dodawania nowego klienta.

Konfiguracja klienta

Naszym oczom powinien ukazać się formularz, którego dane powinny zostać wypełnione analogicznie do tego, co skonfigurowaliśmy w module OpenID Connect w aplikacji klienckiej.

Dodawanie klienta

Zapisujemy formularz i gotowe... prawie. Pozostało jeszcze nadać odpowiednie uprawnienie, tak aby było możliwe w ogóle korzystanie z serwera OAuth2. W tym celu należy udać się do strony /admin/people/permissions i przypisać uprawnienie Use OAuth2 Server dla anonimowego użytkownika.

Konfiguracja uprawnień

Test

Wszystko skonfigurowane. Sprawdźmy zatem realny scenariusz logowania. Na początek zarejestrujemy użytkownika test na naszym serwerze, tak aby mógł on logować się do naszych pozostałych aplikacji.

Stworzenie testowego użytkownika

Przechodzimy do aplikacji klienta (formularz logowania) i klikamy w przycisk Log in with Generic (zrzut formularza).

Następuje przekierowanie na stronę logowania na serwerze wraz z parametrem destination (/user/login?destination=/oauth2/authorize).

Po poprawny podaniu loginu i hasła (test:test) powinniśmy zobaczyć taki dodatkowy krok...

Formularz potwierdzenia autoryzacji

...w którym decydujemy jako logujący się użytkownik o tym, czy faktycznie chcemy uprawnić naszą stronę kliencką do naszych danych użytkownika z serwera, na podstawie których utworzone zostanie lokalne konto użytkownika.

Po zatwierdzeniu zostajemy przekierowani na stronę aplikacji klienckiej jako zalogowany użytkownik:

Strona testowe użytkownika

Sukces! Możemy teraz w pełni cieszyć się naszym centralnym systemem logowania.

Podsumowanie

Możliwość tworzenia centralnego systemu logowania to coraz częstsza potrzeba klientów, którzy posiadają różnego rodzaju rozproszone usługi, serwisy i aplikacje. Stawiając na Drupala, możemy skupić się na implementacji konkretnych reguł biznesowych, zamiast wymyślać koło na nowo. Użycie gotowych rozwiązań tj. OAuth2 Server czy OpenIDConnect, wspieranych przez znane organizacje, daje nam pewność, że w łatwy sposób zaimplementujemy potrzebny nam mechanizm, chociażby bez konieczności szczegółowej wiedzy na temat wykorzystywanych w nich protokołach.

W naszej agencji drupalowej zawsze korzystamy pełnymi garściami z już dostępnych rozwiązań, które często także rozszerzamy, a moduły Drupala dopasowujemy do konkretnego modelu biznesowego. Mam nadzieję, że powyższy artykuł i wykorzystane moduły sprawdzą się także w Twoim projekcie.

3. Najlepsze praktyki zespołów programistycznych