O armazenamento em cache sensível a permissões possibilita armazenar páginas seguras em cache. O Dispatcher verifica as permissões de acesso do usuário para uma página antes de entregar a página em cache.
O Dispatcher inclui o módulo AuthChecker, que implementa o armazenamento sensível a permissões. Quando o módulo é ativado, o Dispatcher chama um servlet do AEM para executar a autenticação e autorização do usuário para o conteúdo solicitado. A resposta do servlet determina se o conteúdo é ou não entregue ao navegador da Web a partir do cache.
Como os métodos de autenticação e autorização são específicos para a implantação do AEM, é necessário criar o servlet.
Use filtros de deny
para aplicar restrições gerais de segurança. Use o armazenamento em cache sensível a permissões para páginas configuradas para acessar um subconjunto de usuários ou grupos.
Os diagramas a seguir ilustram a ordem dos eventos que ocorrem quando um navegador da Web solicita uma página para a qual o armazenamento em cache sensível a permissões é usado.
Para implementar o armazenamento em cache sensível a permissões, execute as seguintes tarefas:
Normalmente, os recursos seguros são armazenados em uma pasta separada dos arquivos não seguros. Por exemplo, /content/secure/
Quando há um CDN (ou qualquer outro cache) na frente do Dispatcher, você deve definir os cabeçalhos de armazenamento em cache adequadamente, para que o CDN não armazene em cache o conteúdo privado. Por exemplo: Header always set Cache-Control private
.
Para o AEM as a Cloud Service, consulte a página de Armazenamento em cache para obter mais detalhes sobre como definir cabeçalhos de cache privados.
Crie e implante um servlet que execute a autenticação e a autorização do usuário que solicita o conteúdo da Web. O servlet pode usar qualquer método de autenticação e autorização, como a conta de usuário do AEM e ACLs do repositório ou um serviço de pesquisa LDAP. Você implanta o servlet na instância de AEM que o Dispatcher usa como renderizador.
O servlet deve ser acessível a todos os usuários. Portanto, seu servlet deve estender a classe org.apache.sling.api.servlets.SlingSafeMethodsServlet
, que fornece acesso somente de leitura ao sistema.
O servlet recebe apenas solicitações HEAD do renderizador, portanto, você só precisa implementar o método doHead
.
O renderizador inclui o URI do recurso solicitado como parâmetro da solicitação HTTP. Por exemplo, um servlet de autorização é acessado via /bin/permissioncheck
. Para executar uma verificação de segurança na página /content/geometrixx-outdoors/en.html, o renderizador inclui o seguinte URL na solicitação HTTP:
/bin/permissioncheck?uri=/content/geometrixx-outdoors/en.html
A mensagem de resposta do servlet deve conter os seguintes códigos de status HTTP:
O servlet de exemplo a seguir obtém o URL do recurso da solicitação HTTP. O código usa a anotação Felix SCR Property
para definir o valor da propriedade sling.servlet.paths
como /bin/permissioncheck. No método doHead
, o servlet obtém o objeto da sessão e usa o método checkPermission
para determinar o código de resposta apropriado.
O valor da propriedade sling.servlet.paths deve ser ativado no serviço Sling Servlet Resolver (org.apache.sling.servlets.resolver.SlingServletResolver).
package com.adobe.example;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Session;
@Component(metatype=false)
@Service
public class AuthcheckerServlet extends SlingSafeMethodsServlet {
@Property(value="/bin/permissioncheck")
static final String SERVLET_PATH="sling.servlet.paths";
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void doHead(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try{
//retrieve the requested URL
String uri = request.getParameter("uri");
//obtain the session from the request
Session session = request.getResourceResolver().adaptTo(javax.jcr.Session.class);
//perform the permissions check
try {
session.checkPermission(uri, Session.ACTION_READ);
logger.info("authchecker says OK");
response.setStatus(SlingHttpServletResponse.SC_OK);
} catch(Exception e) {
logger.info("authchecker says READ access DENIED!");
response.setStatus(SlingHttpServletResponse.SC_FORBIDDEN);
}
}catch(Exception e){
logger.error("authchecker servlet exception: " + e.getMessage());
}
}
}
Se seus requisitos permitirem o armazenamento em cache de documentos autenticados, defina a propriedade /allowAuthorized na seção /cache como /allowAuthorized 1
. Consulte Armazenamento em cache quando a autenticação é usada para obter mais detalhes.
A seção auth_checker do arquivo dispatcher.any controla o comportamento do armazenamento em cache sensível a permissões. A seção auth_checker inclui as seguintes subseções:
url
: O valor da propriedade sling.servlet.paths
do servlet que executa a verificação de segurança.
filter
: Filtros que especificam as pastas às quais o armazenamento em cache sensível a permissões é aplicado. Normalmente, um filtro deny
é aplicado a todas as pastas, e os filtros allow
são aplicados às pastas seguras.
headers
: Especifica os cabeçalhos HTTP que o servlet de autorização inclui na resposta.
Quando o Dispatcher é iniciado, o arquivo de log do Dispatcher inclui a seguinte mensagem no nível de depuração:
AuthChecker: initialized with URL 'configured_url'.
O exemplo de seção auth_checker a seguir configura o Dispatcher para usar o servlet do tópico anterior. A seção de filtro faz com que as verificações de permissão sejam executadas somente em recursos HTML seguros.
/auth_checker
{
# request is sent to this URL with '?uri=<page>' appended
/url "/bin/permissioncheck"
# only the requested pages matching the filter section below are checked,
# all other pages get delivered unchecked
/filter
{
/0000
{
/glob "*"
/type "deny"
}
/0001
{
/glob "/content/secure/*.html"
/type "allow"
}
}
# any header line returned from the auth_checker's HEAD request matching
# the section below will be returned as well
/headers
{
/0000
{
/glob "*"
/type "deny"
}
/0001
{
/glob "Set-Cookie:*"
/type "allow"
}
}
}