Wiem, że spóźniłem się 2+ lata, ale myślę, że podzielę się tym, co wiem i miejmy nadzieję, że złagodzę ból dla przyszłych czytelników. Pełna przejrzystość - w żadnym wypadku nie jestem ekspertem od Keycloak / OAuth / OIDC i wiem, że to głównie z czytania dokumentów, książek, starego dobrego YouTube'a i zabawy z narzędziem.
Ten post będzie składał się z dwóch części:
- Postaram się odpowiedzieć na wszystkie Twoje pytania najlepiej jak potrafię
- Pokażę ci wszystko, jak możesz bawić się zasadami / zakresami / uprawnieniami w Keycloak bez konieczności wdrażania oddzielnej aplikacji, aby lepiej zrozumieć niektóre z podstawowych pojęć w tym wątku. Zwróć jednak uwagę, że ma to głównie na celu rozpoczęcie pracy. Używam
Keycloak 8.0.0
.
Część I.
Kilka terminów, zanim zaczniemy:
- W Keycloak możesz utworzyć 2 typy uprawnień: oparte na zasobach i na zakresie .
- Mówiąc najprościej, w przypadku
Resource-Based
uprawnień stosujesz je bezpośrednio do swojego zasobu
- Aby uzyskać
Scoped-Based
pozwolenie, stosujesz je do zakresu (-ów) lub zakresu (-ów) i zasobu.
Czy najlepszą praktyką jest tworzenie tylko jednego zakresu „widoku” i używanie go w wielu zasobach (konto, transakcja itp.)? A może powinienem utworzyć zakres „viewAccount”, zakres „viewTransaction” itp.?
Zakresy reprezentują zestaw praw do chronionego zasobu. W twoim przypadku masz 2 zasoby: account
i transaction
dlatego skłaniałbym się do drugiego podejścia.
W dłuższej perspektywie, o globalny view
zakres związaną ze wszystkimi swoimi zasobami (np account
, transaction
, customer
, settlement
...) sprawia, że trudno jest autoryzacja zarówno zarządzanie i dostosować się do zmian wymagań bezpieczeństwa.
Oto kilka przykładów, które możesz sprawdzić, aby poczuć projekt
Zwróć jednak uwagę - nie twierdzę, że nie należy udostępniać zakresów między zasobami. W rzeczywistości Keycloak
pozwala na to dla zasobów z tym samym type
. Możesz na przykład potrzebować obu viewAccount
i viewTransaction
zakresu, aby odczytać transakcję na danym rachunku (w końcu możesz potrzebować dostępu do rachunku, aby wyświetlić transakcje). Twoje wymagania i standardy będą miały duży wpływ na Twój projekt.
Czy w przypadku każdego praktycznego połączenia zasobów i zakresu zwykle tworzy się pozwolenie?
Przepraszam, nie do końca rozumiem pytanie, więc będę trochę szerszy. Aby przyznać / odmówić dostępu resource
, musisz:
- Zdefiniuj swoje zasady
- Określ swoje uprawnienia
- Zastosuj swoje zasady do swoich uprawnień
- Skojarz swoje uprawnienia z
scope
lub resource
(lub obydwoma)
aby egzekwowanie zasad zaczęło obowiązywać. Zobacz proces autoryzacji .
To, jak sobie z tym poradzisz, zależy wyłącznie od Ciebie. Możesz na przykład:
Zdefiniuj indywidualne zasady i przypisz je do odpowiednich uprawnień.
Jeszcze lepiej, zdefiniuj indywidualne zasady, a następnie zgrupuj wszystkie powiązane zasady w ramach aggregated
polityki (polityki zasad), a następnie skojarz tę zagregowaną politykę z scope-based
uprawnieniem. Możesz mieć to scoped-based
uprawnienie dotyczące zarówno zasobu, jak i całego powiązanego z nim zakresu.
Możesz też dalej rozdzielić swoje uprawnienia, wykorzystując dwa oddzielne typy. Możesz tworzyć uprawnienia wyłącznie dla swoich zasobów za pomocą resource-based
typu uprawnienia i oddzielnie kojarzyć inne uprawnienia wyłącznie z zakresem za pomocą scope-based
typu uprawnienia.
Masz opcje.
Co robi Keycloak, jeśli istnieje wiele uprawnień pasujących do danego zasobu / zakresu?
To zależy od
- Serwer zasobów
Decision Strategy
- Każde pozwolenie
Decision Strategy
Logic
Wartość każdej polisy .
Logic
Wartość jest podobna Java !
operatora. Może to być Positive
lub Negative
. Gdy Logic
to Positive
, ostateczna ocena polityki pozostaje niezmieniona. Kiedy jej Negative
, ostateczny wynik jest zanegowany (np. Jeśli w ocenie zasady jest fałsz i tak Logic
jest Negative
, to tak będzie true
). Aby uprościć sprawę, załóżmy, że opcja Logic
jest zawsze ustawiona na Positive
.
To Decision Strategy
jest to, czym naprawdę chcemy się zająć. Decision Strategy
Może być albo Unanimous
albo Affirmative
. Z dokumentów,
Strategia decyzyjna
Ta konfiguracja zmienia sposób, w jaki aparat oceny zasad decyduje, czy zasób lub zakres powinien zostać przyznany na podstawie wyniku wszystkich ocenionych uprawnień. Twierdzący oznacza, że co najmniej jedno zezwolenie musi dać pozytywną decyzję, aby przyznać dostęp do zasobu i jego zakresów. Jednogłośność oznacza, że wszystkie pozwolenia muszą zostać ocenione pozytywnie, aby ostateczna decyzja była również pozytywna. Na przykład, jeśli dwa uprawnienia do tego samego zasobu lub zakresu są ze sobą w konflikcie (jedno z nich przyznaje dostęp, a drugie odmawia dostępu), uprawnienie do zasobu lub zakresu zostanie przyznane, jeśli wybrana strategia jest potwierdzona. W przeciwnym razie pojedyncza odmowa dowolnego uprawnienia spowoduje również odmowę dostępu do zasobu lub zakresu.
Skorzystajmy z przykładu, aby lepiej zrozumieć powyższe. Załóżmy, że masz zasób z 2 uprawnieniami i ktoś próbuje uzyskać do niego dostęp (pamiętaj, że Logic
dotyczy Positive
wszystkich zasad). Teraz:
Permission One
ma Decision Strategy
zestaw do Affirmative
. Ma również 3 zasady, w których każda z nich ocenia:
Ponieważ jedna z zasad jest ustawiona na true
, Permission One
jest ustawiona na true
(Twierdząca - tylko 1 musi być true
).
Permission Two
ma Decision Strategy
zestaw Unanimous
z 2 zasadami:
W tym przypadku Permission Two
jest tak, false
ponieważ jedna zasada jest fałszywa (jednogłośnie - wszystkie muszą być true
).
- Teraz nadchodzi ostateczna ocena. Jeśli serwer zasobów
Decision Strategy
jest ustawiony na Affirmative
, dostęp do tego zasobu zostanie przyznany, ponieważPermission One
jest true
. Jeśli z drugiej strony serwer zasobów Decision Strategy
jest ustawiony na Unanimous
, dostęp byłby zabroniony.
Widzieć:
Będziemy to ponownie odwiedzać. Wyjaśniam, jak ustawić serwer zasobówDecision Strategy
W części II .
więc na przykład mógłbym mieć pozwolenie na dostęp do „kont” i pozwolenie na zakres „widok”, więc miałbym uprawnienia do przeglądania kont?
Krótka odpowiedź brzmi: tak. Teraz rozwińmy to trochę :)
Jeśli masz następujący scenariusz:
- Serwer zasobów jest
Decision Strategy
ustawiony na Unanimous
lubAffirmative
- Uprawnienie do dostępu do
account/{id}
zasobu totrue
- Uprawnienie do dostępu do
view
zakresu totrue
Otrzymasz dostęp do przeglądania konta.
true
+ true
jest równe true
pod Affirmative
lub Unanimous
Decision Strategy
.
Teraz, jeśli to masz
- Serwer zasobów jest
Decision Strategy
ustawiony naAffirmative
- Uprawnienie do dostępu do
account/{id}
zasobu totrue
- Uprawnienie do dostępu do
view
zakresu tofalse
Otrzymasz również dostęp do przeglądania konta.
true
+ false
jest true
w ramach Affirmative
strategii.
Chodzi o to, że dostęp do danego zasobu zależy również od twojej konfiguracji, więc bądź ostrożny, ponieważ możesz nie chcieć drugiego scenariusza.
Ale czy mam rację, że to oznacza, że potrzebuję polityki dla każdej starszej grupy, do której mógłby należeć użytkownik?
Nie jestem pewien, jak Keycloak zachowywał się 2 lata temu, ale możesz określić zasady oparte na grupach i po prostu dodać wszystkie swoje grupy do tej polityki. Z pewnością nie musisz tworzyć jednej polityki na grupę.
Na przykład, jeśli pełnię rolę „helpdesk”, potrzebuję zasady „członkostwa w helpdesku”, którą mogę następnie dodać do uprawnienia „viewAccount”. Czy to jest poprawne?
Dość dużo. Można to ustawić na wiele sposobów. Na przykład możesz:
- Utwórz zasób (np.
/account/{id}
) I powiąż go z account:view
zakresem.
- utwórz zasadę opartą na rolach i dodaj
helpdesk
rolę w ramach tej polityki
- Utwórz
Scope-Based
uprawnienie o nazwie viewAccount
i powiąż je z scope
, resource
ipolicy
W części II ustawimy coś podobnego.
część druga
Keycloak ma zgrabne małe narzędzie, które pozwala przetestować wszystkie zasady. Co więcej, w rzeczywistości nie trzeba uruchamiać kolejnego serwera aplikacji i wdrażać oddzielnej aplikacji, aby to zadziałało.
Oto scenariusz, który skonfigurujemy:
- Stworzymy nowe królestwo o nazwie
stackoverflow-demo
- Stworzymy
bank-api
klienta w tym królestwie
- Zdefiniujemy zasób wywoływany
/account/{id}
dla tego klienta
account/{id}
Będzie miał account:view
zakres
- Stworzymy użytkownika o nazwie
bob
w nowej dziedzinie
- Będziemy także tworzyć trzy role:
bank_teller
, account_owner
iuser
- Nie będziemy kojarzyć się
bob
z żadnymi rolami. Nie jest to teraz potrzebne.
- Skonfigurujemy następujące dwie
Role-Based
zasady:
bank_teller
i account_owner
mieć dostęp do /account/{id}
zasobu
account_owner
ma dostęp do account:view
zakresu
user
nie ma dostępu do zasobu lub zakresu
- Będziemy bawić się
Evaluate
narzędziem, aby zobaczyć, jak można przyznać lub odmówić dostępu.
Wybaczcie, ten przykład jest nierealny, ale nie znam sektora bankowego :)
Konfiguracja Keycloak
Pobierz i uruchom Keycloak
cd tmp
wget https://downloads.jboss.org/keycloak/8.0.0/keycloak-8.0.0.zip
unzip keycloak-8.0.0.zip
cd keycloak-8.0.0/bin
./standalone.sh
Utwórz początkowego administratora
- Iść do
http://localhost:8080/auth
- Kliknij na
Administration Console
łącze
- Utwórz administratora i zaloguj się
Odwiedź stronę Pierwsze kroki , aby uzyskać więcej informacji. Do naszych celów wystarczy powyższe.
Przygotowanie sceny
Stwórz nowe królestwo
- Najedź myszką po
master
królestwie i kliknijAdd Realm
przycisk.
- Wchodzić
stackoverflow-demo
jako nazwę.
- Kliknij
Create
.
- W lewym górnym rogu powinno być teraz napisane
stackoverflow-demo
zamiast master
sfery.
Zobacz Tworzenie nowego królestwa
Utwórz nowego użytkownika
- Kliknij
Users
link po lewej stronie
- Kliknij
Add User
przycisk
- Wpisz
username
(np. bob
)
- Upewnij się, że
User Enabled
jest włączony
- Kliknij
Save
Zobacz Tworzenie nowego użytkownika
Utwórz nowe role
- Kliknij
Roles
łącze
- Kliknij
Add Role
- Dodaj następujące role:
bank_teller
, account_owner
iuser
Ponownie, nie kojarz swojego użytkownika z rolami. Dla naszych celów nie jest to potrzebne.
Zobacz role
Utwórz klienta
- Kliknij
Clients
łącze
- Kliknij
Create
- Wejdź
bank-api
doClient ID
- Do
Root URL
wejściahttp://127.0.0.1:8080/bank-api
- Kliknij
Save
- Upewnij się, że
Client Protocol
takopenid-connect
- Zmień
Access Type
naconfidential
- Zmień
Authorization Enabled
naOn
- Przewiń w dół i naciśnij
Save
. NowyAuthorization
górze powinna pojawić się karta.
- Kliknij
Authorization
kartę, a następnieSettings
- Upewnij się, że
Decision Strategy
jest ustawiony naUnanimous
- To jest serwer zasobów
Decision Strategy
Widzieć:
Utwórz niestandardowe zakresy
- Kliknij
Authorization
kartę
- Kliknij
Authorization Scopes
>, Create
aby wyświetlić Add Scope
stronę
- Wpisz
account:view
nazwę i naciśnij Enter.
Utwórz „Wyświetl zasoby konta”
- Kliknij
Authorization
link powyżej
- Kliknij
Resources
- Kliknij
Create
- Wpisz
View Account Resource
zarówno, jak Name
iDisplay name
- Wejdź
account/{id}
doURI
- Wpisz
account:view
w polu Scopes
tekstowym
- Kliknij
Save
Zobacz Tworzenie zasobów
Utwórz swoje zasady
- Ponownie w
Authorization
zakładce kliknijPolicies
- Wybierz
Role
zCreate Policy
rozwijanej
- W
Name
sekcji wpiszOnly Bank Teller and Account Owner Policy
- W obszarze
Realm Roles
wybierz zarówno rolę, jak bank_teller
iaccount_owner
- Upewnij się, że
Logic
jest ustawiona naPositive
- Kliknij
Save
- Kliknij
Policies
łącze
- Wybierz
Role
ponownie z listy Create Policy
rozwijanej.
- Tym razem użyj
Only Account Owner Policy
dlaName
- Pod
Realm Roles
wybierzaccount_owner
- Upewnij się, że
Logic
jest ustawiona naPositive
- Kliknij
Save
- Kliknij
Policies
link u góry, powinieneś zobaczyć nowo utworzone zasady.
Zobacz Zasady oparte na rolach
Zwróć uwagę, że Keycloak ma znacznie silniejsze zasady. Zobacz Zarządzanie zasadami
Utwórz uprawnienie oparte na zasobach
- Ponownie w
Authorization
zakładce kliknijPermissions
- Wybierz
Resource-Based
- Wpisz
View Account Resource Permission
dlaName
- Pod
Resources
typemView Account Resource Permission
- Pod
Apply Policy
wybierzOnly Bank Teller and Account Owner Policy
- Upewnij się, że
Decision Strategy
jest ustawiony naUnanimous
- Kliknij
Save
Zobacz Tworzenie uprawnień opartych na zasobach
Uff ...
Ocena uprawnienia opartego na zasobach
- Ponownie na
Authorization
karcie wybierzEvaluate
- Pod
User
wejściembob
- Pod
Roles
wybierzuser
- Tutaj będziemy kojarzyć naszego użytkownika z naszymi utworzonymi rolami.
- Pod
Resources
wybierz View Account Resource
i kliknijAdd
- Kliknij Oceń.
- Rozwiń,
View Account Resource with scopes [account:view]
aby zobaczyć wyniki i powinieneś zobaczyć DENY
.
- Ma to sens, ponieważ zezwalamy tylko dwóm rolom na dostęp do tego zasobu za pośrednictwem
Only Bank Teller and Account Owner Policy
. Przetestujmy to, aby upewnić się, że to prawda!
- Kliknij
Back
link tuż nad wynikiem oceny
- Zmień rolę boba na
account_owner
i kliknij Evaluate
. Powinieneś teraz zobaczyć wynik jako PERMIT
. To samo, jeśli wrócisz i zmienisz rolę nabank_teller
Zobacz Ocenianie i testowanie zasad
Utwórz uprawnienie oparte na zakresie
- Wróć do
Permissions
sekcji
- Wybierz
Scope-Based
ten czas z listy Create Permission
rozwijanej.
- Pod
Name
, wprowadźView Account Scope Permission
- Pod
Scopes
, wprowadźaccount:view
- Pod
Apply Policy
, wprowadźOnly Account Owner Policy
- Upewnij się, że
Decision Strategy
jest ustawiony naUnanimous
- Kliknij
Save
Zobacz Tworzenie uprawnień opartych na zakresie
Drugi przebieg próbny
Ocena naszych nowych zmian
- Wróć do
Authorization
sekcji
- Kliknij
Evaluate
- Użytkownik powinien być
bob
- Role powinny być
bank_teller
- Zasoby powinny być
View Account Resource
i kliknijAdd
- Kliknij
Evaluate
i powinniśmy dostać DENY
.
- Ponownie nie powinno to być zaskoczeniem, ponieważ
bank_teller
ma dostęp do, resource
ale nie scope
. Tutaj jedno zezwolenie jest oceniane jako prawdziwe, a drugie jako fałszywe. Biorąc pod uwagę, że serwer zasobów Decision Strategy
jest ustawiony na Unanimous
, ostateczną decyzją jest DENY
.
- Kliknij na
Settings
pod Authorization
zakładki i zmienić Decision Strategy
się Affirmative
i wrócić do kroków 1-6 ponownie. Tym razem ostateczny wynik powinien być PERMIT
(jedno zezwolenie jest prawdziwe, więc ostateczna decyzja jest prawdziwa).
- Ze względu na kompletność przełącz serwer zasobów z
Decision Strategy
powrotem na Unanimous
. Ponownie wróć do kroków od 1 do 6, ale tym razem ustaw rolę jako account_owner
. Tym razem ostateczny wynik jest znowu PERMIT
sensowny, biorąc pod uwagę, że account_owner
ma dostęp zarówno do, jak resource
i scope
.
Schludnie :) Mam nadzieję, że to pomoże.