Autorizační politiky

Autorizační politika určuje co nad čím může uživatel v CzechIdM provádět.

Politika je přiřazena do role a každý kdo danou roli získá tím získá i práva, která mu politika dává.

  • přiřazení práv v CzechIdM skrz běžné role umožňuje řídit práva na CzechIdM standardním mechanismem

Existuje výchozí role "User", která dává implicitní práva, která má každý uživatel v CzechIdM. Tato role se nepřiřazuje explicitně, je prostě výchozí a aplikuje se vždy (viz následující kapitola).

Na roli byla navázána nová agenda autorizačních politik = práva na data i agendy. Přidělení oprávnění zpřístupňuje přihlášenému uživateli jak agendy na frontendu (respektive restové endpointy na backendu), tak práva na data ⇒ zpřístupňují záznamy v těchto agendách. Oprávnění na agendy (respektive restové endpointy) jsou vyhodnocována dle nastavených oprávnění.

Základní myšlenkou je, že pokud agenda podporuje práva na data, tak ve výchozím stavu žádná data nevidím. Abych nějaká data viděl, potřebuji dostat / vyhovět některé nakonfigurované politice, kterou dostanu na základě svých přidělených rolí.
Jak spolu fungují práva na agendy a práva na data:
  • Abych viděl nějaká data, potřebuji mít přidělenu alespoň jednu roli s politikou přižazující práva

Příklad ze života:

Mějme agendu rolí. Abych mohl vybírat z číselníku rolí (například při žádání o role), musím mít přiřazeno právo na agendu našeptávání pro role Role - AUTOCOMPLETE neboli Zobrazení v našeptávačích, výběrech třeba s typem vyhodnocení BasePermissionEvaluator .

  • BasePermission - základní oprávnění. Mohou být přidávána modulově. Základní oprávnění z jádra IdM, která jsou společná jak pro oprávnění pro přístup do agend, tak pro práva na data:
    • ADMIN - administrace - zahrnuje všechny operace ⇒ wildcard - není potřeba operace vyjmenovávat všechny (viz. IdmAuthorityHierarchy)
    • AUTOCOMPLETE - zobrazení dat v našeptávačích. Nemusím mít práva na čtení záznamu, ale potřebuji jej jen někde vybrat z nabídky (e.g. když si žádám o roli, mám možnost ji vybrat, ale kdybych měl jenom toto právo, tak roli v agendě rolí neuvidím). Toto právo umožňuje číst "trimmed" záznam (možná to ještě omezíme).
    • READ - právo číst celý záznam - záznam se zobrazí v agendě.
    • CREATE - zakládání nových záznamů v agendě
    • UPDATE - úprava záznamu
    • DELETE - smazání záznamu
  • GroupPermission - skupina (cíl) oprávnění (e.g. USER, ROLE …). Skupina základních oprávnění. Tato skupina je přizována konkrétním doménovým třídám (e.g. IdmRole) a definuje, jaká základní oprávnění výše obsahuje ⇒ co je s daným typem možné provádět.
Spojením skupiny a základního oprávnění vznikne autorita - například ROLE_READ, IDENTITY_WRITE.
Speciální skupinou je APP, jenž slouží pro administrátory aplikace - ve spojení skupiny a základního oprávnění vznikne autorita APP_ADMIN, jenž vlastní všechna oprávnění v aplikaci.
  • AuthorizationPolicy - politika, dle které se vyhodnocují práva pro konkrétní agendu (atribut groupPermission) a konkrétní doménový typ (atribut authorizableType). Určuje evaluator (AuthorizationEvaluator) s konkrétním nastavením (atribut ConfigurationMap) a jaká základní oprávnění (atribut basePermissions) je možné dostat, projde-li vyhohnocení.
Politiky se přiřazují jednotlivým rolím a díky tomu je přihlášený uživatel i dostává (vazba identita - PPV - role - politika).
  • AuthorizationEvaluator - "vyhodnocovač" oprávnění - prakticky je to implementace jednotlivých typů pravidel popsaných výše. Každý evaluator si sebou nese informaci, jaký doménový typ a jaké nastavení podporuje. Některé mohou býti i univerzální pro více doménových typů (e.g. potomků BaseEntity). Pro zjednodušení implementace pravidla byla vytvořena třída AbstractAuthorizationEvaluator, kterou stačí podědit při přidávání dalšího pravidla. Základní evaluatory budou posány dále. Hlavní metody evaloatoru, které je nutné naimplementovat (nebo přetížit z AbstractAuthorizationEvaluator):
    • supports(authorizableType) - jaký domenový typ evaluátor podporuje
    • supportsPermissions() - vrací true, pokud podporuje zadání oprávnění, které přideluje. False - definuje si je sám interně (e.g. AbstractTransitiveEvaluator).
    • getAuthorities(policy) - vrací množinu operací (množinuBasePermission), kterou by mohla aktuálně přihlášená identita dle dané politiky provádět (e.g. READ, UPDATE).
    • getPermissions(policy, authorizable) - vrací množinu operací (množinuBasePermission), kterou může aktuálně přihlášená identita s daným doménovým objektem dle dané politiky provádět (e.g. READ, UPDATE)
    • evaluate(policy, authorizable, permission) - tohle je jen taková zkratka - vrátí true, pokud aktuálně přihlášená identita může provádět dle dané politiky danou operaci (prakticky contains na množinu výše)
    • getPredicate(…) - vrací jpa criteria predicate, který je možné "přilepit" do where clausule ⇒ dotaz pak vrací stránkovatelný, řaditelný výsledek s daty, na které mám dle dané politiky právo. Doporučuje se predikáty psát jako subquery s exists, aby nedocházelo k problémům s joinováním tabulek (pokud se samozřejmě nejedná jen o něco jednoduchého).
  • AuthorizableService - interface slouží pro označení služby pracující s entitami, že podporuje vyhodnocení politik pro práva na data. Bylo přidáno především kvůli zpětné kompatibilitě - práva na data jsou zapojována na jednotlivé agendy postupně. Politiky je tedy možné nakonfigurovat jen pro doménové typy se službami podporující toto interface.
  • AuthorizationManager - načítá a vyhodnocuje nastavené politiky pro přihlášenou identitu napříč aplikací:
    • načítá všechny aktivní politiky dle přiřazených rolí uživatele
    • spojuje predikáty dle politik do where clausule při vyhledávání či našeptávání dat (AuthorizableService.findSecured(…))
    • vyhodnocuje dostupné operace nad danými doménovými objekty na úrovni restových controllerů.

AbstractAuthorizationEvaluator

Přidává defaulní implementaci metod AuthorizationEvaluator. Využívá se jako předek pro ostatní evaluátory.

AbstractTransitiveEvaluator

Slouží jako předek pro vyhodnocování práv dle odvozených objektů - například mám právo na přiřazenou roli, pokud mám právo na identitu atd. Viz potomci této abstraktní třídy uvedené dále (IdentityContractByIdentityEvaluator).

BasePermissionEvaluator

Slouží pro přidělení nakonfigurovaného oprávnění pro nakonfigurovaný doménový typ - pro všechna data daného typu. Je možné jej využít, pokud chceme přidělit přístup do agendy včetně přístupu ke všem datům. Využívá se například pro admina s konfigurací - libovolný typ (práva na všenchny potomky Identifiable) + BasePermission.ADMIN. Zároveň je možné jej využít pro přidělení základního oprávnění pro zobrazení dat při našeptávání (viz výše BasePermission.AUTOCOMPLETE).

BasePermissionEvaluator je použit i pro jednoduché nasdílení agendy, která ještě nepodporuje práva na data. Agendy, které ještě nepodporují práva na data nejsou přilinkovány k doménovému objektu, což je vidět i na frontendu. Pro tyto agendy není možné vybrat jiný evaluator.

UuidEvaluator

"Nasdílí" objekt s daným uuid. Je vhodné jej použít, pokud nejsme schopni nakonfigurovat jiné obecnější pravidlo - prostě a jednoduše někdo potřebuje vidět pouze jeden záznam z celé agendy, tak mu jej "nasdílím" přes identifikátor (bylo by pěkné v konfiguraci nezadávat přímo uuid ale našeptávač … comming soon).

CodeableEvaluator

"Nasdílí" objekt s daným identifikátorem s tím, že je možné zadat uuid nebo kód dané entity. Pro tento evaluátor je třeba vybrat typ entity, pro který je určen - nefunguje napříč entitami.

SubordinatesEvaluator

Právo na identity, které jsou mými podřízenými. Pro vyhodnocení podřízených respektive vedoucích jsou použity přetižitelné filtry.

IdentityContractByIdentityEvaluator

Dává právo na pracovně právní vztahy dle práva na identitu ⇒ e.g. pokud mám právo číst identitu, tak mám právo číst její PPV. Zde se využívá AbstractTransitiveEvaluator.

ContractGuaranteeByIdentityContractEvaluator

Dává právo na garanty pracovně právního vztahu (nastavování garanta "napřímo") dle práva na pracovně právní vztah ⇒ e.g. pokud mám právo číst PPV, tak mám právo číst jeho garanty. Zde se využívá AbstractTransitiveEvaluator. Pokud mám právo editovat PPV, mám právo editovat (přidávat i odebírat) jemu přiřazené garanty.

IdentityRoleByIdentityEvaluator

Dává právo na přiřazené role dle práva na identitu ⇒ e.g. pokud mám právo číst identitu, tak mám právo číst jí přiřazené role. Zde se využívá AbstractTransitiveEvaluator. Pokud mám právo editovat identitu, mám právo editovat (přidávat i odebírat) jí přiřazené role.

RoleGuaranteeEvaluator

Dává právo pracovat s rolemi, které garantuji.

AuthorizationPolicyByRoleEvaluator

Dává právo na autorizační politiky dle práva na roli ⇒ e.g. pokud mám právo číst roli, tak mám právo číst jí přiřazené autorizační politiky. Pokud mám právo editovat roli, mám právo editovat (přidávat i mazat) jí přiřazené autorizační politiky.

RoleTreeNodeByRoleEvaluator

Dává právo na automatické role dle práva na roli ⇒ e.g. pokud mám právo číst roli, tak mám právo číst jí přiřazené automatické role. Pokud mám právo editovat roli, mám právo editovat (přidávat i mazat) jí přiřazené automatické role.

ConfigurationEvaluator

Dává právo na konfiguraci aplikace (číst, nastavovat …). Pokud chceme dostat práva i na zabezpečené položky konfigurace, nastavíme parametr secured na true.

RoleCanBeRequestedEvaluator

Přiděluje práva na roli podle atributu role "canBeRequested". To znamená, že pokud mám roli s tímto evaluatorem, tak dostanu práva jen na ty role, které mají atribut canBeRequested nastaven na true.

Konfigurace výchozích práv na agendy i data pro všechny přihlášené uživatele je řešena prostřednictvím defaultní role dle konfigurace aplikace. Defaulní role může mít stejně jako ostatní role nakonfigurovány práva na agendy i data. Po přihlášení se tyto práva doplní do kontextu přihlášeného uživatele (autority i autorizační politiky) - role jako taková nefiguruje v přiřazených rolích uživatele. Defaultní role lze využít především pro přidání základních práv na našeptávače (rolí, identit) a podobně.

U defaulní role nejsou řešeny podřízené role ⇒ to co si u role nastavím, to přihlášený uživatel dostane, nic víc.

Výchozí nastavení práv na profil identity

Pokud chceme číst profil identity včetně přiřazených rolí a PPV, umožnit změnu hesla a žádat o role, lze nastavit autorizační politiky například u výchozí role takto:

  • Právo číst vlastní identitu: Uživatelé (IdmIdentity) | Zobrazení v našeptávačích, výběrech, Čtení, Změna hesla | SelfIdentityEvaluator
  • Právo číst přiřazené role dle identity: Přiřazené role uživatelům (IdmIdentityRole)| - | IdentityRoleByIdentityEvaluator
  • Právo číst PPV dle identity: Pracovně právní vztahy (IdmIdentityContract) | - | IdentityContractByIdentityEvaluator
  • Právo číst garanty PPV: Garanti pracovně právního vztahu (IdmContractGuarantee) | - | ContractGuaranteeByIdentityContractEvaluator
  • Umožnění našeptávání pro entity:
    • Uživatelé (IdmIdentity) | Zobrazení v našeptávačích, výběrech | BasePermissionEvaluator
    • Role (IdmRole) | Zobrazení v našeptávačích, výběrech | BasePermissionEvaluator
    • Pracovně právní vztahy (IdmIdentityContract) | Zobrazení v našeptávačích, výběrech | BasePermissionEvaluator

Výchozí nastavení práv na detail role

Pokud chceme číst a editovat role, kde jsme garantem, včetně přiřazených oprávnění a automatických rolí, lze nastavit autorizační politiky takto:

  • Právo číst garantované role: Role (IdmRole) | Čtení, Úprava | RoleGuaranteeEvaluator
  • Právo číst automatické role dle role: Automatické role (IdmRoleTreeNode) | - | RoleTreeNodeByRoleEvaluator
  • Právo číst oprávnění dle role: Oprávnění (IdmAuthorizationPolicy | - | AuthorizationPolicyByRoleEvaluator

Pro zapojení práv na data pro nový doménový typ je třeba:

  • implementovat rozhraní AuthorizableService pro službu pracující s entitami. Toto vyžaduje, aby repositář nehledal záznamy přes hql query, nýbrž přes jpa criteria api (to je hlavní úprava pro stávající služby, kde je třeba všechny filtry přepsat). Ukázku je možné najít v DefaultIdmAuthorizationPolicyService.
  • Naimplementovat nové pravidlo, pokud si nevystačíme s univerzálními viz výše. Pro zjednodušení implementace nového pravidla byla vytvořena třída AbstractAuthorizationEvaluator, kterou stačí podědit při přidávání dalšího pravidla, ukázka:
/**
 * Adds permission for create new role only
 *
 */
@Component
@Description("Adds permission for create new role")
public class RoleWriteNewOnlyEvaluator extends AbstractAuthorizationEvaluator<IdmRole> {	
 
	@Override
	public Set<String> getPermissions(AuthorizationPolicy policy, IdmRole entity) {
		Set<String> permissions = super.getPermissions(policy, entity);	
		permissions.add(IdmBasePermission.CREATE.getName());
		return permissions;
	}
}
  • o ostatní už se postará AuthenticationManager, který dle aplikačníko kontextu dohledává všechny implementace pravidel, nabízí prodrorované typy a tak dále.