Pular para o conteúdo

Controle de acesso e roles

O modelo de controle de acesso do Mondrian permite dividir seu schema em roles. Uma role é um conjunto nomeado de grants e denials que cobre todo o schema — de quais cubos são visíveis até quais membros individuais um usuário tem permissão de ver. Você define roles diretamente no arquivo de schema, e o Saiku Cloud as aplica quando estabelece uma conexão em nome de um usuário.

Definir uma role

Elementos <Role> são filhos diretos de <Schema>, colocados após o último <Cube>. Aqui está um exemplo completo:

- 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"

As seções abaixo explicam cada elemento em detalhe.


<SchemaGrant>

<SchemaGrant> define o acesso default ao schema inteiro. Seu atributo access pode ser:

ValorSignificado
allA role pode ver cada cubo e dimensão no schema.
all_dimensionsA role pode ver todas as dimensões, mas ainda precisa de entradas <CubeGrant> explícitas para acessar os dados de qualquer cubo.
noneA role não pode ver nada a menos que seja explicitamente concedido.

No exemplo acima, access="none" significa que o usuário pode navegar somente pelo cubo “Sales”, porque é o único explicitamente concedido.


<CubeGrant>

<CubeGrant> controla acesso a um cubo específico. Seu atributo access pode ser:

ValorSignificado
allAcesso completo ao cubo e a todas as suas dimensões e hierarquias.
customO acesso é definido pelos elementos filhos <DimensionGrant> e <HierarchyGrant>.
noneO cubo é escondido da role.

<DimensionGrant>

<DimensionGrant> controla acesso a uma dimensão inteira dentro de um cubo. Seu atributo access pode ser:

ValorSignificado
allTodas as hierarquias filhas desta dimensão são acessíveis.
customSem acesso inerente às hierarquias filhas — cada hierarquia deve ser concedida separadamente usando <HierarchyGrant>.
noneA dimensão é escondida.

O atributo dimension recebe o nome único MDX da dimensão (por exemplo "[Measures]" ou "[Store]").


<HierarchyGrant>

<HierarchyGrant> controla acesso a uma hierarquia, opcionalmente restringindo os levels e membros visíveis.

AtributoObrigatórioDescrição
hierarchysimNome único MDX da hierarquia, ex. "[Store]".
accesssim"all", "custom" ou "none".
topLevelnãoNome único MDX do level mais alto visível. Membros acima deste level são escondidos.
bottomLevelnãoNome único MDX do level mais baixo visível. Membros abaixo deste level são escondidos.
rollupPolicynãoComo calcular totais quando alguns filhos estão escondidos. Veja Política de rollup.

Valores de access

ValorSignificado
allCada membro é visível.
noneA hierarquia é escondida da role.
customA visibilidade é controlada por topLevel, bottomLevel e/ou filhos <MemberGrant>.

<MemberGrant>

<MemberGrant> concede ou nega acesso a um membro específico e todos os seus filhos. Você só pode usar <MemberGrant> quando o <HierarchyGrant> que o envolve tem access="custom".

AtributoObrigatórioDescrição
membersimNome único MDX do membro, ex. "[Store].[USA].[CA]".
accesssim"all" ou "none".

Regras para member grants

Member grants interagem de uma forma específica quando múltiplos grants se aplicam à mesma hierarquia:

  1. Membros herdam acesso dos seus pais. Negar acesso à Califórnia automaticamente nega acesso a San Francisco.
  2. Grants dependem da ordem. Se você conceder acesso aos EUA e depois negar Oregon, Oregon fica escondido. Se você negar Oregon primeiro e depois conceder EUA, tudo fica visível. Ordem importa.
  3. Um membro é visível se algum dos filhos for visível. Se você negar EUA mas conceder Califórnia, verá EUA e Califórnia — mas nenhum outro estado. Nota: totais para EUA sob a política de rollup full ainda refletem todos os estados (veja Política de rollup). Se um topLevel for definido, só pais nesse level ou abaixo são mostrados.
  4. Member grants não sobrescrevem topLevel e bottomLevel. Se topLevel="[Store].[Store State]" está definido e você concede Califórnia, ainda não pode ver o level EUA.

Walkthrough do exemplo

Com a role “California manager” do exemplo de abertura, o usuário pode:

  • Ver Califórnia e todas as cidades na Califórnia exceto Los Angeles.
  • Ver EUA (porque Califórnia, um filho visível, torna o pai visível), mas nenhum outro país.
  • Não ver “All Stores” porque fica acima do topLevel de Store Country.
  • Não ver clientes fora da faixa State Province até City, e não Los Angeles.
  • Não ver a hierarquia Gender de jeito nenhum.

Row security baseada em predicado (<PredicateGrant>)

Member grants restringem quais membros de dimensão uma role pode ver. Às vezes você precisa restringir as próprias linhas de fato por um valor de coluna que rastreia o usuário solicitante — row-level security multi-tenant clássica ou o access_filter do Looker. Para isso, o Saiku adiciona um <PredicateGrant> (uma extensão do Saiku ao Mondrian 4, issue #106): ele vincula uma role a um filtro em uma coluna real de fato, com valor vindo do parâmetro de consulta da conexão.

<Role name="Regional">
<SchemaGrant access="all"/>
<PredicateGrant measureGroup="Sales" column="region"
operator="eq" parameter="region"/>
</Role>

O backend Calcite injeta o predicado como um filtro WHERE em cada carregamento de segmento do measure group nomeado, pré-agregação, para que totais — não só linhas folha — sejam corretamente restritos, e o resultado por role seja isolado no cache de segmento. Um parâmetro não vinculado falha fechado (zero linhas), nunca irrestrito. operator é eq (igualdade) ou in (membership).


Política de rollup

Uma política de rollup determina qual valor o Mondrian mostra para um membro pai quando a role atual não pode ver todos os seus filhos.

PolíticaSignificado
fullO total do pai inclui todos os filhos, visíveis ou não. Este é o default.
partialO total do pai inclui apenas os filhos acessíveis.
hiddenSe algum filho for inacessível, o total do pai é suprimido.

Exemplo: efeito de cada política

Suponha que uma role pode ver [USA].[CA] e [USA].[OR] mas não [USA].[WA] e roda:

SELECT {[Measures].[Unit Sales]} ON COLUMNS,
{[Store].[USA], [Store].[USA].Children} ON ROWS
FROM [Sales]

Full (default) — o total de [USA] inclui as 124.366 unidades de Washington:

MembroUnit Sales
[USA]266,773
[USA].[CA]74,748
[USA].[OR]67,659

Partial — o total de [USA] reflete apenas CA e OR:

MembroUnit Sales
[USA]142,407
[USA].[CA]74,748
[USA].[OR]67,659

Hidden — o total de [USA] é suprimido porque ao menos um filho é inacessível:

MembroUnit Sales
[USA]
[USA].[CA]74,748
[USA].[OR]67,659

Especificar a política de rollup

O atributo rollupPolicy fica em <HierarchyGrant>. Você pode aplicar políticas diferentes a hierarquias diferentes na mesma role:

- 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"

Union roles

Uma union role combina os privilégios de duas ou mais roles existentes. O resultado tem o acesso menos restritivo entre todas as suas roles constituintes: a union role pode ver qualquer objeto do schema que pelo menos uma role constituinte possa ver, e sua política de rollup para uma dada hierarquia é a política menos restritiva entre todas as constituintes.

<Role name="Coastal manager">
<Union>
<RoleUsage roleName="California manager"/>
<RoleUsage roleName="Eastern sales manager"/>
</Union>
</Role>

As roles constituintes devem ser declaradas antes no arquivo de schema. Elas podem ser roles regulares, outras union roles ou roles custom baseadas em classe. A union role “Coastal manager” pode ver qualquer membro acessível por qualquer constituinte, e também pode ver células na intersecção de membros que só uma role pode ver.


Definir a role de uma conexão

Uma role entra em vigor quando é associada a uma conexão. Por default, conexões têm uma role irrestrita que pode ver cada cubo no schema. Há duas formas de ativar uma role específica:

Na connect string

Inclua a palavra-chave Role na string de conexão do Mondrian. O Saiku Cloud define isso em nome dos seus usuários com base na configuração do seu tenant:

Provider=mondrian; Role="California manager";
Jdbc=jdbc:postgresql://host/db; JdbcUser=user; JdbcPassword=pw;
Catalog=/WEB-INF/MySchema.mondrian.xml

Para ativar múltiplas roles de uma vez (criando uma union ad-hoc), separe os nomes com vírgulas. Se um nome de role em si contém uma vírgula, escape-a com uma vírgula dupla.

Programaticamente

Se você está embutindo o Mondrian diretamente, chame Connection.setRole(Role) após abrir uma conexão, ou consulte uma role nomeada com Schema.lookupRole(String).


Role default

Você pode marcar uma role como o default no seu schema usando o atributo defaultRole em <Schema>. Qualquer conexão que não especifique explicitamente uma role usará este default:

<Schema name="FoodMart" defaultRole="California manager">
...
</Schema>

Roles em schemas YAML

Se você escreve seu schema em formato YAML, roles são declaradas sob a chave top-level roles. Cada entrada mapeia para um elemento <Role>. Veja a referência de schemas YAML para a sintaxe completa de roles, incluindo chaves schema_grant, cubes, hierarchies, members, rollup_policy, top_level e bottom_level.

Um exemplo rápido:

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"

Adaptado do guia de schema do projeto Mondrian (EPL v1.0).