Kontrola dostępu i role
Model kontroli dostępu Mondriana pozwala pokroić Twoją schemę na role. Rola to nazwany zbiór grantów i odmów, który pokrywa całą schemę — od tego, które kostki są widoczne, aż po to, których pojedynczych członków użytkownikowi wolno zobaczyć. Role definiujesz wprost w pliku schemy, a Saiku Cloud stosuje je, gdy ustanawia połączenie w imieniu użytkownika.
Definiowanie roli
Elementy <Role> są bezpośrednimi dziećmi <Schema>, umieszczonymi po ostatnim <Cube>. Oto kompletny przykład:
- name: "California manager" schema_grant: access: "none" cubes: - cube: "Sales" access: "all" dimensions: - dimension: "[Measures]" access: "all" hierarchies: - hierarchy: "[Store]" access: "custom" top_level: "[Store].[Store Country]" members: - member: "[Store].[USA].[CA]" access: "all" - member: "[Store].[USA].[CA].[Los Angeles]" access: "none" - hierarchy: "[Customers]" access: "custom" top_level: "[Customers].[State Province]" bottom_level: "[Customers].[City]" members: - member: "[Customers].[USA].[CA]" access: "all" - member: "[Customers].[USA].[CA].[Los Angeles]" access: "none" - hierarchy: "[Gender]" access: "none"<Role name="California manager"> <SchemaGrant access="none"> <CubeGrant cube="Sales" access="all"> <DimensionGrant dimension="[Measures]" access="all"/>
<HierarchyGrant hierarchy="[Store]" access="custom" topLevel="[Store].[Store Country]"> <MemberGrant member="[Store].[USA].[CA]" access="all"/> <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/> </HierarchyGrant>
<HierarchyGrant hierarchy="[Customers]" access="custom" topLevel="[Customers].[State Province]" bottomLevel="[Customers].[City]"> <MemberGrant member="[Customers].[USA].[CA]" access="all"/> <MemberGrant member="[Customers].[USA].[CA].[Los Angeles]" access="none"/> </HierarchyGrant>
<HierarchyGrant hierarchy="[Gender]" access="none"/> </CubeGrant> </SchemaGrant></Role>Sekcje poniżej wyjaśniają każdy element szczegółowo.
<SchemaGrant>
<SchemaGrant> ustawia domyślny dostęp do całej schemy. Jego atrybut access może być:
| Wartość | Znaczenie |
|---|---|
all | Rola może widzieć każdą kostkę i wymiar w schemie. |
all_dimensions | Rola może widzieć wszystkie wymiary, ale wciąż potrzebuje jawnych wpisów <CubeGrant>, by dostać się do danych jakiejkolwiek kostki. |
none | Rola nie widzi nic, dopóki nie nadano jawnie. |
W przykładzie powyżej access="none" oznacza, że użytkownik może przeglądać tylko kostkę „Sales”, bo to jedyna jawnie nadana.
<CubeGrant>
<CubeGrant> kontroluje dostęp do konkretnej kostki. Jego atrybut access może być:
| Wartość | Znaczenie |
|---|---|
all | Pełny dostęp do kostki i wszystkich jej wymiarów i hierarchii. |
custom | Dostęp jest definiowany przez dziecięce elementy <DimensionGrant> i <HierarchyGrant>. |
none | Kostka jest ukryta przed rolą. |
<DimensionGrant>
<DimensionGrant> kontroluje dostęp do całego wymiaru wewnątrz kostki. Jego atrybut access może być:
| Wartość | Znaczenie |
|---|---|
all | Wszystkie hierarchie-dzieci tego wymiaru są dostępne. |
custom | Brak wrodzonego dostępu do hierarchii-dzieci — każdą hierarchię trzeba nadać osobno przez <HierarchyGrant>. |
none | Wymiar jest ukryty. |
Atrybut dimension przyjmuje unikalną nazwę MDX wymiaru (np. "[Measures]" lub "[Store]").
<HierarchyGrant>
<HierarchyGrant> kontroluje dostęp do hierarchii, opcjonalnie ograniczając widoczne poziomy i członków.
| Atrybut | Wymagany | Opis |
|---|---|---|
hierarchy | tak | Unikalna nazwa MDX hierarchii, np. "[Store]". |
access | tak | "all", "custom" lub "none". |
topLevel | nie | Unikalna nazwa MDX najwyższego widocznego poziomu. Członkowie powyżej tego poziomu są ukryci. |
bottomLevel | nie | Unikalna nazwa MDX najniższego widocznego poziomu. Członkowie poniżej tego poziomu są ukryci. |
rollupPolicy | nie | Jak obliczać sumy, gdy niektóre dzieci są ukryte. Zobacz Polityka rollup. |
Wartości access
| Wartość | Znaczenie |
|---|---|
all | Każdy członek jest widoczny. |
none | Hierarchia jest ukryta przed rolą. |
custom | Widoczność jest kontrolowana przez topLevel, bottomLevel i/lub dzieci <MemberGrant>. |
<MemberGrant>
<MemberGrant> nadaje lub odmawia dostępu do konkretnego członka i wszystkich jego dzieci. Możesz używać <MemberGrant> tylko, gdy zamykający <HierarchyGrant> ma access="custom".
| Atrybut | Wymagany | Opis |
|---|---|---|
member | tak | Unikalna nazwa MDX członka, np. "[Store].[USA].[CA]". |
access | tak | "all" lub "none". |
Reguły dla grantów członków
Granty członków oddziałują na siebie w określony sposób, gdy wiele grantów dotyczy tej samej hierarchii:
- Członkowie dziedziczą dostęp od swoich rodziców. Odmowa dostępu do Kalifornii automatycznie odmawia dostępu do San Francisco.
- Granty są zależne od kolejności. Jeśli nadasz dostęp do USA, potem odmówisz Oregonowi, Oregon jest ukryty. Jeśli najpierw odmówisz Oregonowi, potem nadasz USA, wszystko jest widoczne. Kolejność ma znaczenie.
- Członek jest widoczny, jeśli któreś z jego dzieci jest widoczne. Jeśli odmówisz USA, ale nadasz Kalifornię, zobaczysz USA i Kalifornię — ale żadnych innych stanów. Uwaga: sumy dla USA pod polityką rollup
fullwciąż odzwierciedlają wszystkie stany (zobacz Polityka rollup). Jeśli ustawionotopLevel, pokazywani są tylko rodzice na tym poziomie lub poniżej. - Granty członków nie nadpisują
topLevelibottomLevel. JeślitopLevel="[Store].[Store State]"jest ustawione, a nadasz Kalifornię, wciąż nie możesz zobaczyć poziomu USA.
Przegląd przykładu
Z rolą „California manager” z otwierającego przykładu użytkownik może:
- Widzieć Kalifornię i wszystkie miasta w Kalifornii oprócz Los Angeles.
- Widzieć USA (bo Kalifornia, widoczne dziecko, czyni rodzica widocznym), ale żadnych innych krajów.
- Nie widzieć „All Stores”, bo leży powyżej
topLevelStore Country. - Nie widzieć klientów spoza pasma stan-do-miasta (State Province do City), ani Los Angeles.
- Nie widzieć w ogóle hierarchii Gender.
Bezpieczeństwo wierszy oparte o predykat (<PredicateGrant>)
Granty członków ograniczają, których członków wymiaru rola może zobaczyć. Czasem zamiast tego musisz ograniczyć same wiersze faktów wartością kolumny śledzącą żądającego użytkownika — klasyczne row-level security wielotenantowe lub access_filter z Lookera. Do tego Saiku dodaje <PredicateGrant> (rozszerzenie Saiku do Mondrian 4, issue #106): wiąże rolę z filtrem na prawdziwej kolumnie faktu, zasilanym z parametru zapytania połączenia.
<Role name="Regional"> <SchemaGrant access="all"/> <PredicateGrant measureGroup="Sales" column="region" operator="eq" parameter="region"/></Role>Backend Calcite wstrzykuje predykat jako filtr WHERE przy każdym załadowaniu segmentu nazwanej grupy miar, pre-aggregation, więc sumy — nie tylko wiersze liści — są poprawnie ograniczone, a wynik per rola jest izolowany w cache segmentów. Niezwiązany parametr zawodzi zamknięty (zero wierszy), nigdy nie nieograniczony. operator to eq (równość) lub in (przynależność).
Polityka rollup
Polityka rollup wyznacza, jaką wartość Mondrian pokazuje dla członka-rodzica, gdy bieżąca rola nie może zobaczyć wszystkich jego dzieci.
| Polityka | Znaczenie |
|---|---|
full | Suma rodzica zawiera wszystkie dzieci, widoczne czy nie. To wartość domyślna. |
partial | Suma rodzica zawiera tylko dostępne dzieci. |
hidden | Jeśli jakieś dziecko jest niedostępne, suma rodzica jest stłumiona. |
Przykład: efekt każdej polityki
Załóżmy, że rola może widzieć [USA].[CA] i [USA].[OR], ale nie [USA].[WA], i uruchamia:
SELECT {[Measures].[Unit Sales]} ON COLUMNS, {[Store].[USA], [Store].[USA].Children} ON ROWSFROM [Sales]Full (domyślne) — suma [USA] zawiera 124 366 jednostek Washingtonu:
| Członek | Unit Sales |
|---|---|
[USA] | 266,773 |
[USA].[CA] | 74,748 |
[USA].[OR] | 67,659 |
Partial — suma [USA] odzwierciedla tylko CA i OR:
| Członek | Unit Sales |
|---|---|
[USA] | 142,407 |
[USA].[CA] | 74,748 |
[USA].[OR] | 67,659 |
Hidden — suma [USA] jest stłumiona, bo przynajmniej jedno dziecko jest niedostępne:
| Członek | Unit Sales |
|---|---|
[USA] | — |
[USA].[CA] | 74,748 |
[USA].[OR] | 67,659 |
Określanie polityki rollup
Atrybut rollupPolicy siedzi na <HierarchyGrant>. Możesz stosować różne polityki do różnych hierarchii w tej samej roli:
- name: "South Pacific manager" schema_grant: access: "none" cubes: - cube: "Sales" access: "all" hierarchies: - hierarchy: "[Store]" access: "custom" top_level: "[Store].[Store Country]" rollup_policy: "partial" members: - member: "[Store].[USA].[CA]" access: "all" - member: "[Store].[USA].[CA].[Los Angeles]" access: "none" - hierarchy: "[Customers]" access: "custom" top_level: "[Customers].[State Province]" bottom_level: "[Customers].[City]" rollup_policy: "full" members: - member: "[Customers].[USA].[CA]" access: "all" - member: "[Customers].[USA].[CA].[Los Angeles]" access: "none" - hierarchy: "[Gender]" access: "none"<Role name="South Pacific manager"> <SchemaGrant access="none"> <CubeGrant cube="Sales" access="all"> <HierarchyGrant hierarchy="[Store]" access="custom" rollupPolicy="partial" topLevel="[Store].[Store Country]"> <MemberGrant member="[Store].[USA].[CA]" access="all"/> <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/> </HierarchyGrant>
<HierarchyGrant hierarchy="[Customers]" access="custom" rollupPolicy="full" topLevel="[Customers].[State Province]" bottomLevel="[Customers].[City]"> <MemberGrant member="[Customers].[USA].[CA]" access="all"/> <MemberGrant member="[Customers].[USA].[CA].[Los Angeles]" access="none"/> </HierarchyGrant>
<HierarchyGrant hierarchy="[Gender]" access="none"/> </CubeGrant> </SchemaGrant></Role>Role union
Rola union łączy uprawnienia dwóch lub więcej istniejących ról. Wynik ma najmniej restrykcyjny dostęp ze wszystkich składowych ról: rola union może widzieć każdy obiekt schemy, który widzi przynajmniej jedna składowa rola, a jej polityka rollup dla danej hierarchii to najmniej restrykcyjna polityka spośród wszystkich składowych.
<Role name="Coastal manager"> <Union> <RoleUsage roleName="California manager"/> <RoleUsage roleName="Eastern sales manager"/> </Union></Role>Składowe role muszą być zadeklarowane wcześniej w pliku schemy. Mogą to być zwykłe role, inne role union albo niestandardowe role oparte o klasę. Rola union „Coastal manager” może widzieć dowolnego członka dostępnego dla którejkolwiek składowej i może też widzieć komórki na przecięciu członków, których tylko jedna rola może zobaczyć.
Ustawianie roli połączenia
Rola wchodzi w życie, gdy jest skojarzona z połączeniem. Domyślnie połączenia mają nieograniczoną rolę, która widzi każdą kostkę w schemie. Są dwa sposoby aktywowania konkretnej roli:
W connect-stringu
Włącz słowo kluczowe Role w connect-stringu Mondriana. Saiku Cloud ustawia to w imieniu Twoich użytkowników na podstawie konfiguracji Twojego tenanta:
Provider=mondrian; Role="California manager";Jdbc=jdbc:postgresql://host/db; JdbcUser=user; JdbcPassword=pw;Catalog=/WEB-INF/MySchema.mondrian.xmlAby aktywować wiele ról naraz (tworząc ad-hoc union), oddziel nazwy przecinkami. Jeśli sama nazwa roli zawiera przecinek, escapuj go podwójnym przecinkiem.
Programistycznie
Jeśli osadzasz Mondriana bezpośrednio, wywołaj Connection.setRole(Role) po otwarciu połączenia albo wyszukaj nazwaną rolę przez Schema.lookupRole(String).
Rola domyślna
Możesz oznaczyć jedną rolę jako domyślną w swojej schemie przez atrybut defaultRole na <Schema>. Każde połączenie, które nie określa jawnie roli, użyje tej domyślnej:
<Schema name="FoodMart" defaultRole="California manager"> ...</Schema>Role w schemach YAML
Jeśli autoryzujesz swoją schemę w formacie YAML, role są deklarowane pod kluczem najwyższego poziomu roles. Każdy wpis mapuje się na element <Role>. Zobacz referencję schemy YAML dla pełnej składni roles, w tym kluczy schema_grant, cubes, hierarchies, members, rollup_policy, top_level i bottom_level.
Szybki przykład:
roles: - name: "California manager" schema_grant: access: "none" cubes: - cube: "Sales" access: "all" hierarchies: - hierarchy: "[Store].[Stores]" access: "custom" top_level: "[Store].[Stores].[Store Country]" members: - member: "[Store].[Stores].[USA].[CA]" access: "all" - member: "[Store].[Stores].[USA].[CA].[Los Angeles]" access: "none"
- name: "No HR Cube" schema_grant: access: "all" cubes: - cube: "HR" access: "none"Dostosowane z przewodnika po schemie projektu Mondrian (EPL v1.0).