Wdrożenie Keycloak na Kubernetes z przykładową aplikacją na NSIS
Keycloak to duży pakiet do zarządzania tożsamością o otwartym kodzie źródłowym, zdolny do obsługi szerokiego zakresu przypadków użycia związanych z tożsamością.
Korzystając z Keycloak, można łatwo wdrożyć solidne rozwiązanie uwierzytelniania/autoryzacji dla swoich aplikacji. Po początkowym wdrożeniu można je łatwo skonfigurować, aby spełniało nowe wymagania związane z tożsamością, np. uwierzytelnianie wieloskładnikowe, federacja z dostawcami usług społecznościowych, niestandardowe zasady dotyczące haseł i wiele innych.
Co zamierzamy zrobić
Wdrożenie Keycloak na klastrze Kubernetes
Konfiguracja Keycloak: utworzenie domeny, klienta i użytkownika
Wdrożenie przykładowej aplikacji internetowej w języku Python przy użyciu Keycloak do uwierzytelniania
Wymagania wstępne
Nr 1 Hosting
Potrzebne jest konto hostingowe NSIS z interfejsem Horizon https://horizon.cloudferro.com.
Nr 2 Uruchomiony klaster Kubernetes i aktywowany kubectl.
Klaster Kubernetes, aby go utworzyć, patrz: Jak utworzyć klaster Kubernetes przy użyciu NSIS OpenStack Magnum. Aby aktywować kubectl, zobacz Jak uzyskać dostęp do klastra Kubernetes po wdrożeniu przy użyciu Kubectl na NSIS OpenStack Magnum?.
Nr 3 Podstawowa znajomość Pythona i zarządzania pakietami pip
Oczekuje się podstawowej znajomości Pythona i zarządzania pakietami pip. Python 3 i pip powinny być już zainstalowane i dostępne na lokalnym komputerze.
Nr 4 Znajomość terminologii OpenID Connect (OIDC)
Wymagana jest pewna znajomość terminologii OpenID Connect (OIDC). Niektóre kluczowe terminy zostaną pokrótce wyjaśnione w tym artykule.
Krok 1 Wdrożenie Keycloak na platformie Kubernetes
Najpierw utwórzmy dedykowaną przestrzeń nazw Kubernetes dla Keycloak. Jest to opcjonalne, ale stanowi dobrą praktykę:
kubectl create namespace keycloak
Następnie należy wdrożyć Keycloak w tej przestrzeni nazw:
kubectl create -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes-examples/keycloak.yaml -n keycloak
Keycloak domyślnie jest udostępniany jako usługa Kubernetes typu LoadBalancer na porcie 8080. Musisz znaleźć publiczny adres IP usługi za pomocą następującego polecenia (pamiętaj, że wypełnienie może zająć kilka minut):
kubectl get services -n keycloak
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
keycloak LoadBalancer 10.254.8.94 64.225.128.216 8080:31228/TCP 23h
Informacja
W naszym przypadku zewnętrzny adres IP to 64.225.128.216, więc właśnie tego będziemy używać w tym artykule. Pamiętaj, aby zastąpić go własnym adresem IP.
Tak więc, wpisz http://64.225.128.216:8080/ do przeglądarki, aby uzyskać dostęp do Keycloak:
Następnie kliknij Konsola administracyjna, a zostaniesz przekierowany do ekranu logowania, gdzie możesz zalogować się jako administrator (login/hasło admin/admin).
Jest to widok pełnoekranowy okna Keycloak:
Krok 2 Utwórz obszar Keycloak
W terminologii Keycloak, realm jest dedykowaną przestrzenią do zarządzania izolowanym podzbiorem użytkowników, ról i innych powiązanych podmiotów. Keycloak ma początkowo główną sferę używaną do administrowania samym Keycloak.
Naszym następnym krokiem jest stworzenie własnego królestwa i rozpoczęcie działania w jego kontekście. Aby go utworzyć, kliknij najpierw na pole master w lewym górnym rogu, a następnie na Create Realm.
Wprowadzimy tylko nazwę królestwa myrealm, pozostawiając resztę bez zmian:
Kiedy sfera zostaje stworzona (i wybrana), działamy w tej sferze:
W lewym górnym rogu zamiast master znajduje się teraz nazwa wybranego królestwa, myrealm.
Krok 3 Utwórz i skonfiguruj klienta Keycloak
Klienci są podmiotami w Keycloak, które mogą zażądać od Keycloak uwierzytelnienia użytkowników. W praktyce można je traktować jako reprezentację poszczególnych aplikacji, które chcą korzystać z uwierzytelniania / autoryzacji zarządzanej przez Keycloak.
W obszarze myrealm utworzymy teraz klienta myapp, który będzie reprezentował aplikację internetową, którą utworzymy w jednym z dalszych kroków. Aby utworzyć takiego klienta, kliknij panel Clients w lewym menu, a następnie przycisk Create Client.
Pojawi się kreator składający się z 3 kroków. W pierwszym kroku wprowadzamy jedynie ID klienta (w naszym przypadku jest to myapp), pozostawiając pozostałe ustawienia bez zmian:
Następny ekran obejmuje wybór niektórych kluczowych ustawień związanych z wymaganiami uwierzytelniania / autoryzacji określonej aplikacji.
Wybór opcji zależy od konkretnego scenariusza:
- Scenariusz 1 Tradycyjne aplikacje serwerowe
Na potrzeby tego artykułu i naszej aplikacji demonstracyjnej używamy tradycyjnej aplikacji klient-serwer. Następnie musimy włączyć przełącznik „Client Authentication”.
- Scenariusz 2 SPA
W przypadku aplikacji jednostronicowych można pozostać przy ustawieniach domyślnych, w których przełącznik „Client Authentication” jest wyłączony.
W naszej aplikacji demonstracyjnej będziemy wymagać uwierzytelnienia za pomocą sekretu, więc pamiętaj, aby aktywować opcję Uwierzytelnianie klienta. Po jej włączeniu będziemy mogli uzyskać wartość secret później, w kroku 5.
Ostatnim krokiem kreatora jest ustawienie kilku kluczowych współrzędnych naszej aplikacji klienckiej. Te, które modyfikujemy, obejmują:
- główny adres URL
W naszym przypadku chcemy wdrożyć aplikację lokalnie, więc ustawiliśmy katalog główny jako http://localhost . Będziesz musiał to zmienić, jeśli Twoja aplikacja będzie dostępna jako usługa publiczna.
- Prawidłowe identyfikatory URI przekierowania
To ustawienie reprezentuje trasę w naszej aplikacji, do której użytkownik zostanie przekierowany po pomyślnym zalogowaniu z Keycloak. W naszym przypadku pozostawiamy to ustawienie bardzo liberalne z „*”, umożliwiając przekierowanie do dowolnej ścieżki w naszej aplikacji. W przypadku produkcji należy to zrobić bardziej wyraźnie, używając do tego celu dedykowanej trasy, powiedzmy /callback.
- Pochodzenie sieci
To ustawienie określa hosty, które mogą wysyłać żądania do Keycloak. Żądania z innych hostów nie przejdą kontroli pochodzenia i zostaną odrzucone. Również tutaj jesteśmy bardzo liberalni, ustawiając „*”. Podobnie jak powyżej, zdecydowanie rozważ zmianę tego ustawienia dla produkcji i ograniczenie tylko do zaufanych źródeł.
Po naciśnięciu przycisku Zapisz klient zostanie utworzony. Następnie można zmodyfikować wcześniej wybrane ustawienia utworzonego klienta i dodać nowe, bardziej szczegółowe. Istnieją ogromne możliwości dalszego dostosowywania w zależności od specyfiki aplikacji, jednak wykracza to poza zakres tego artykułu.
Krok 4 Utwórz użytkownika w Keycloak
Po utworzeniu klienta przejdziemy do utworzenia naszego pierwszego użytkownika w Keycloak. Aby to zrobić, kliknij zakładkę Users po lewej stronie, a następnie Create New User:
Ponownie będziemy bardzo selektywni i wybierzemy tylko test jako nazwę użytkownika, pozostawiając inne opcje nienaruszone:
Następnie ustawimy poświadczenia hasła dla nowo utworzonego użytkownika. Wybierz zakładkę Poświadczenia, a następnie Ustaw hasło, wpisz hasło z potwierdzeniem w formularzu i naciśnij Zapisz:
Krok 5 Pobierz klucz tajny klienta z Keycloak
Po skonfigurowaniu Keycloak będziemy musieli wyodrębnić secret klienta, aby Keycloak ustanowił zaufanie do naszej aplikacji.
Sekret client_secret można wyodrębnić, przechodząc do myrealm realm, wybierając myapp jako klienta, a następnie pobierając sekret klienta za pomocą następującego łańcucha poleceń:
Klienci –> Szczegóły klienta –> Poświadczenia
Po przejściu do zakładki Poświadczenia, sekret będzie dostępny w polu Sekret klienta:
Ze względu na prywatność, na powyższym zrzucie jest on pomalowany na żółto. W twoim przypadku zanotuj jego wartość, ponieważ w następnym kroku będziesz musiał wkleić ją do kodu aplikacji.
Krok 6 Utworzenie aplikacji Flask wykorzystującej uwierzytelnianie Keycloak
Do zbudowania aplikacji użyjemy Flask, który jest lekkim frameworkiem webowym opartym na Pythonie. Keycloak obsługuje również wiele innych technologii. Użyjemy biblioteki Flask-OIDC, która rozszerza Flask o możliwość uruchamiania scenariuszy uwierzytelniania / autoryzacji OpenID Connect.
Jako warunek wstępny należy zainstalować następujące pakiety pip, aby pokryć łańcuch zależności. Najlepiej uruchamiać polecenia z już zainstalowanego wirtualnego środowiska Python:
pip install Werkzeug==2.3.8
pip install Flask==2.0.1
pip install wheel==0.40.0
pip install flask-oidc==1.4.0
pip install itsdangerous==2.0.1
Następnie należy utworzyć 2 pliki: app.py i keycloak.json. Będziesz potrzebował następujących zmian w tych plikach:
- Zastąp adres IP
W pliku keycloak.json zastąp 64.225.128.216 własnym zewnętrznym adresem IP z kroku 1.
- Zastąp client_secret
Ponownie w pliku keycloak.json zastąp wartość zmiennej client_secret sekretem z Kroku 5.
- Zastąp client_secret
W pliku app.py zastąp wartość SECRET_KEY tym samym sekretem z Kroku 5.
Utwórz nowy plik o nazwie app.py i wklej do niego poniższą zawartość:
from flask import Flask, g
from flask_oidc import OpenIDConnect
import json
app = Flask(__name__)
app.config.update(
SECRET_KEY='XXXXXX',
OIDC_CLIENT_SECRETS='keycloak.json',
OIDC_INTROSPECTION_AUTH_METHOD='client_secret_post',
OIDC_TOKEN_TYPE_HINT='access_token',
OIDC_SCOPES=['openid','email','profile'],
OIDC_OPENID_REALM='myrealm'
)
oidc = OpenIDConnect(app)
@app.route('/')
def index():
if oidc.user_loggedin:
info = oidc.user_getinfo(["preferred_username", "email", "sub"])
return 'Welcome %s' % info.get("preferred_username")
else:
return '<h1>Not logged in</h1>'
@app.route('/login')
@oidc.require_login
def login():
token = oidc.get_access_token()
info = oidc.user_getinfo(["preferred_username", "email", "sub"])
username = info.get("preferred_username")
return "Token: " + token + "<br/><br/> Username: " + username
@app.route('/logout')
def logout():
oidc.logout()
return '<h2>Hi, you have been logged out! <a href="/">Return</a></h2>'
Kod aplikacji uruchamia aplikację Flask i zapewnia konfiguracje niezbędne dla flask_oidc. Musimy skonfigurować
nazwa naszego królestwa
klienta secret_key oraz
dodatkowe ustawienia, które odzwierciedlają nasz specyficzny przepływ próbek.
Ponadto ta konfiguracja wskazuje na inny plik konfiguracyjny, keycloak.json, który odzwierciedla dalsze ustawienia naszego obszaru Keycloak. W szczególności można w nim znaleźć identyfikator klienta i sekret, a także punkty końcowe, w których Keycloak udostępnia dalsze informacje o ustawieniach obszaru.
Utwórz wymagany plik keycloak.json, w tym samym folderze roboczym co plik app.py:
{
"web": {
"client_id": "myapp",
"client_secret": "XXXXXX",
"auth_uri": "http://64.225.128.216:8080/realms/myrealm/protocol/openid-connect/auth",
"token_uri": "http://64.225.128.216:8080/realms/myrealm/protocol/openid-connect/token",
"issuer": "http://64.225.128.216:8080/realms/myrealm",
"userinfo_uri": "http://64.225.128.216:8080/realms/myrealm/protocol/openid-connect/userinfo",
"token_introspection_uri": "http://64.225.128.216:8080/realms/myrealm/protocol/openid-connect/token/introspect",
"redirect_uris": [
"http://localhost:5000/*"
]
}
}
Zauważ, że app.py tworzy 3 trasy:
- /
W tej trasie wyświetlana jest strona zawierająca nazwę zalogowanego użytkownika. Alternatywnie, jeśli użytkownik nie jest jeszcze zalogowany, wyświetlany jest monit o zalogowanie.
- /login
Ta trasa przekierowuje użytkownika do strony logowania Keycloak i po pomyślnym uwierzytelnieniu podaje nazwę użytkownika i token
- /logout
Wprowadzenie tej trasy powoduje wylogowanie użytkownika.
Krok 7 Przetestuj aplikację
Aby przetestować aplikację, wykonaj poniższe polecenie z katalogu roboczego, w którym znajduje się plik app.py:
flask run
Oto wynik w oknie CLI:
Teraz wiemy, że localhost jest uruchomionym serwerem Flask na porcie 5000. Wpisz localhost:5000 w pasku adresu przeglądarki, a wyświetli się strona obsługiwana na trasie podstawowej: / . Nie zalogowaliśmy jeszcze naszego użytkownika, stąd odpowiedni komunikat:
Następnym krokiem jest wprowadzenie trasy /login. W pasku adresu przeglądarki należy wpisać localhost:5000/login. Spowoduje to przekierowanie do Keycloak z prośbą o zalogowanie się do myapp:
Aby się uwierzytelnić, wprowadź nazwę użytkownika, którą utworzyliśmy w kroku 3 (nazwa użytkownika: test) oraz hasło użyte do utworzenia tego użytkownika. Przy domyślnych ustawieniach, po pierwszym zalogowaniu może pojawić się prośba o zmianę hasła, wtedy należy postępować zgodnie z instrukcjami. Po zalogowaniu, nasza nazwa użytkownika i token zostaną wyświetlone (ze względów bezpieczeństwa, części tokena są pomalowane na żółto):
Ostatnią trasą do przetestowania jest /logout . Po wpisaniu localhost:5000/logout w przeglądarce możemy zobaczyć poniższy ekran. Wpisanie tej trasy wywołuje metodę flask-oidc, która wylogowuje użytkownika, czyszcząc również plik cookie sesji pod maską.