A principal maneira de obter uma sessão administrativa ou um resolvedor de recursos no AEM era usando o SlingRepository.loginAdministrative()
e ResourceResolverFactory.getAdministrativeResourceResolver()
métodos fornecidos pelo Sling.
No entanto, nenhum desses métodos foi projetado em torno do princípio do privilégio mínimo e tornar muito fácil para um desenvolvedor não planejar uma estrutura adequada e os respectivos Níveis de controle de acesso (ACLs) para o conteúdo antecipadamente. Se uma vulnerabilidade estiver presente em um serviço desse tipo, ela geralmente leva a escaladas de privilégio para o admin
mesmo se o código em si não precisasse de privilégios administrativos para funcionar.
Pode haver casos em que a sessão de administrador não seja usada ou o recurso seja totalmente desativado. Se esse for o caso com sua implementação, remova o recurso completamente ou ajuste-o com Código NOP.
Sempre que possível, refatore seu recurso para que a sessão de solicitação fornecida e autenticada possa ser usada para ler ou gravar conteúdo. Caso tal não seja possível, pode muitas vezes conseguir-se aplicando as prioridades que se seguem.
Muitos problemas podem ser resolvidos reestruturando o conteúdo. Lembre-se dessas regras simples ao fazer a reestruturação:
Alterar controle de acesso
Refinar estrutura de conteúdo
Refatorar seu código para ser um serviço adequado
Além disso, verifique se os novos recursos desenvolvidos seguem estes princípios:
Os requisitos de segurança devem orientar a estrutura do conteúdo
Usar tipos de nós
Respeitar as configurações de privacidade
/profile
nó.Se você aplicar o controle de acesso ao reestruturar o conteúdo ou quando o fizer para um novo usuário de serviço, deverá aplicar as ACLs mais rigorosas possíveis. Usar todos os recursos possíveis de controle de acesso:
Por exemplo, em vez de aplicar jcr:read
em /apps
, aplique-o somente a /apps/*/components/*/analytics
Uso restrições
Aplicar ACLs para tipos de nó
Limitar permissões
jcr:write
permissão; usar jcr:modifyProperties
em vez dissoSe o procedimento acima falhar, o Sling 7 oferecerá um serviço de Mapeamento de usuários do serviço, que permite configurar um mapeamento de pacote para usuário e dois métodos de API correspondentes:
Os métodos retornam um resolvedor de sessão/recurso com os privilégios somente de um usuário configurado. Esses métodos têm as seguintes características:
Eles permitem serviços de mapeamento para usuários
Eles permitem definir usuários de subserviço
O ponto de configuração central é: org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl
service-id
= service-name
[":" subservice-name]
service-id
é mapeado para um resolvedor de recursos e/ou ID de usuário do repositório JCR para autenticação
service-name
é o nome simbólico do pacote que fornece o serviço
Um usuário de serviço é um usuário JCR sem senha definida e com um conjunto mínimo de privilégios necessários para executar uma tarefa específica. Não ter uma senha definida significa que não será possível fazer logon com um usuário de serviço.
Uma maneira de descontinuar uma sessão administrativa é substituí-la por sessões de usuário de serviço. Ele também pode ser substituído por vários usuários de subserviço, se necessário.
Para substituir a sessão de administrador por um usuário de serviço, execute as seguintes etapas:
Identifique as permissões necessárias para seu serviço, tendo em mente o princípio de menos permissão.
Verifique se já existe um usuário disponível com exatamente a configuração de permissão necessária. Crie um usuário de serviço do sistema se nenhum usuário existente atender às suas necessidades. O RTC é necessário para criar um usuário de serviço. Às vezes, faz sentido criar vários usuários de subserviço (por exemplo, um para escrita e outro para leitura) para compartimentalizar ainda mais o acesso.
Configurar e testar ACEs para o usuário.
Adicionar um service-user
mapeamento para seu serviço e para user/sub-users
Disponibilize o recurso sling do usuário de serviço para o seu pacote: atualização para a versão mais recente do org.apache.sling.api
.
Substitua o admin-session
em seu código com o loginService
ou getServiceResourceResolver
APIs.
Depois de verificar que nenhum usuário na lista de usuários do serviço AEM se aplica ao seu caso de uso e que os problemas de RTC correspondentes foram aprovados, você pode adicionar o novo usuário ao conteúdo padrão.
A abordagem recomendada é criar um usuário de serviço para usar o explorador do repositório em https://<server>:<port>/crx/explorer/index.jsp
O objetivo é obter um certificado válido jcr:uuid
propriedade obrigatória para criar o usuário por meio de uma instalação do pacote de conteúdo.
Você pode criar usuários de serviço ao:
Acessar o explorador de repositório em https://<server>:<port>/crx/explorer/index.jsp
Para fazer logon como administrador, pressione a tecla Fazer logon no canto superior esquerdo da tela.
Em seguida, crie e nomeie o usuário do sistema. Para criar o usuário como um sistema, defina o caminho intermediário como system
e adicione subpastas opcionais de acordo com suas necessidades:
Verifique se o nó do usuário do sistema tem a seguinte aparência:
Não há tipos de mixin associados a usuários de serviço. Isso significa que não haverá políticas de controle de acesso para usuários do sistema.
Ao adicionar o .content.xml correspondente ao conteúdo do pacote, verifique se você definiu o rep:authorizableId
e que o tipo primário é rep:SystemUser
. Deve ter esta aparência:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:rep="internal"
jcr:primaryType="rep:SystemUser"
jcr:uuid="4917dd68-a0c1-3021-b5b7-435d0044b0dd"
rep:principalName="authentication-service"
rep:authorizableId="authentication-service"/>
Para adicionar um mapeamento de seu serviço aos Usuários do sistema correspondentes, crie uma configuração de fábrica para o ServiceUserMapper
serviço. Para manter essa configuração modular, ela pode ser fornecida usando o Mecanismo de alteração do Sling. A maneira recomendada de instalar essas configurações com seu pacote é usando Carregamento do conteúdo inicial do Sling:
Crie uma subpasta SLING-INF/content abaixo da pasta src/main/resources do seu pacote
Nesta pasta, crie um arquivo chamado org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.ended-<some unique="" name="" for="" your="" factory="" configuration="">.xml com o conteúdo da configuração de fábrica (incluindo todos os mapeamentos de usuário de subserviço). Exemplo:
Criar um SLING-INF/content
pasta abaixo do src/main/resources
pasta do seu pacote;
Nesta pasta, crie um arquivo named org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-<a unique name for your factory configuration>.xml
com o conteúdo da configuração de fábrica, incluindo todos os mapeamentos de subserviço de usuário.
Para fins ilustrativos, use o arquivo chamado org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-com.adobe.granite.auth.saml.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<node>
<primaryNodeType>sling:OsgiConfig</primaryNodeType>
<property>
<name>user.default</name>
<value></value>
</property>
<property>
<name>user.mapping</name>
<values>
<value>com.adobe.granite.auth.saml=authentication-service</value>
</values>
</property>
</node>
Faça referência ao conteúdo inicial do Sling na configuração do maven-bundle-plugin
no pom.xml
do seu pacote. Exemplo:
<Sling-Initial-Content>
SLING-INF/content;path:=/libs/system/config;overwrite:=true;
</Sling-Initial-Content>
Instale seu pacote e verifique se a configuração de fábrica está instalada. Você pode fazer isso ao:
Chamadas para loginAdministrative()
aparecem frequentemente junto com sessões compartilhadas. Essas sessões são adquiridas na ativação do serviço e só são desconectadas após a interrupção do serviço. Embora essa seja uma prática comum, ela gera dois problemas:
A solução mais óbvia para o risco de segurança é simplesmente substituir o loginAdministrative()
chamar com um loginService()
um para um usuário com privilégios restritos. No entanto, isso não terá impacto em nenhuma possível degradação do desempenho. Uma possibilidade de mitigar isso é envolver todas as informações solicitadas em um objeto que não esteja associado à sessão. Em seguida, crie (ou destrua) a sessão sob demanda.
A abordagem recomendada é refatorar a API do serviço para dar ao chamador controle sobre a criação/destruição da sessão.
JSPs não podem usar loginService()
, pois não há serviço associado. No entanto, as sessões administrativas em JSPs geralmente são um sinal de violação do paradigma MVC.
Isso pode ser corrigido de duas maneiras:
O primeiro método é o preferido.
Ao processar eventos ou trabalhos e, às vezes, workflows, a sessão correspondente que acionou o evento é perdida. Isso faz com que manipuladores de eventos e processadores de trabalho geralmente usem sessões administrativas para fazer seu trabalho. Existem diferentes abordagens concebíveis para resolver este problema, cada uma com suas vantagens e desvantagens:
Passe o user-id
no payload do evento e usar representação.
Vantagens Fácil de usar.
Desvantagens: Ainda usa loginAdministrative()
. Ele reautentica uma solicitação que já foi autenticada.
Criar ou reutilizar um usuário de serviço que tenha acesso aos dados.
Vantagens Consistente com o design atual. Precisa de mudanças mínimas.
Desvantagens: Precisa de usuários avançados de serviço para ser flexível, o que pode facilmente levar a escalonamentos de privilégios. Contorna o modelo de segurança.
Transmita uma serialização do Subject
na carga do evento, e crie uma ResourceResolver
com base nesse assunto. Um exemplo seria o uso do JAAS doAsPrivileged
no ResourceResolverFactory
.
Vantagens Implementação limpa do ponto de vista da segurança. Ela evita a reautenticação e opera com os privilégios originais. O código relevante para a segurança é transparente para o consumidor do evento.
Desvantagens: Precisa de refatoração. O fato de o código relevante para a segurança ser transparente para o consumidor do evento também pode causar problemas.
A terceira abordagem é a técnica de processamento preferida.
Nas implementações do processo de fluxo de trabalho, a sessão do usuário correspondente que acionou o fluxo de trabalho é perdida. Isso leva a processos de fluxo de trabalho que geralmente usam sessões administrativas para executar seu trabalho.
Para corrigir esses problemas, recomenda-se que as mesmas abordagens mencionadas no Eventos de processamento, pré-processadores e trabalhos de replicação ser utilizado.
Há algumas sessões administrativas usadas em implementações do processador sling POST. Normalmente, as sessões administrativas são usadas para acessar nós com exclusão pendente no POST que está sendo processado. Em consequência, eles não estarão mais disponíveis por meio da sessão de solicitação. Uma exclusão pendente de um nó pode ser acessada para divulgar metadados que, de outra forma, não deveriam estar acessíveis.