缓存受保护内容 :headding-anchor:caching-secured-content

利用权限敏感型缓存,您可以缓存受保护页面。Dispatcher 会先检查用户对页面的访问权限,然后再传递缓存页面。

Dispatcher 包含实现权限敏感型缓存的 AuthChecker 模块。在激活此模块后,Dispatcher 会调用 AEM servlet 以对请求的内容执行用户身份验证和授权。servlet 响应将确定是否将内容从缓存传送到 Web 浏览器。

由于身份验证方法和授权方法特定于 AEM 部署,因此您需要创建 servlet。

NOTE
使用 deny 过滤器可强制实施所有安全限制。对配置为允许访问一部分用户或组的页面使用权限敏感型缓存。

下图说明了在 Web 浏览器请求权限敏感型缓存将用于的页面时发生的事件的顺序。

对页面进行缓存并向用户授权 :headding-anchor:page-is-cached-and-user-is-authorized

  1. Dispatcher 确定请求的内容已缓存且有效。
  2. Dispatcher 向渲染器发送请求消息。HEAD 部分包括来自浏览器请求的所有标头行。
  3. 渲染器调用授权检查程序 servlet 以执行安全检查并向 Dispatcher 发出响应。响应消息包含 HTTP 状态代码 200 以表示用户已获得授权。
  4. Dispatcher 向浏览器发送一条响应消息,其中包含渲染器响应中的标头行和正文中的缓存内容。

不对页面进行缓存,但向用户授权 :headding-anchor:page-is-not-cached-and-user-is-authorized

  1. Dispatcher 确定内容未缓存或需要更新。
  2. Dispatcher 将原始请求转发到渲染器。
  3. 渲染器调用 AEM 授权程序 servlet(该 servlet 不是 Dispatcher AuthChcker servlet)以执行安全检查。当用户获得授权时,渲染器将在响应消息的正文中包含渲染的页面。
  4. Dispatcher 将响应转发到浏览器。Dispatcher 将渲染器的响应消息正文添加到缓存。

未向用户授权 :headding-anchor:user-is-not-authorized

  1. Dispatcher 检查缓存。
  2. Dispatcher 向渲染器发送一条请求消息,其中包含浏览器请求中的所有标头行。
  3. 渲染器调用授权检查程序 servlet 以执行安全检查,检查未通过,渲染器将原始请求转发到 Dispatcher。
  4. Dispatcher 将原始请求转发到渲染器。
  5. 渲染器调用 AEM 授权程序 servlet(该 servlet 不是 Dispatcher AuthChcker servlet)以执行安全检查。当用户获得授权时,渲染器将在响应消息的正文中包含渲染的页面。
  6. Dispatcher 将响应转发到浏览器。Dispatcher 将渲染器的响应消息正文添加到缓存。

实施权限敏感型缓存 :headding-anchor:implementing-permission-sensitive-caching

要实施权限敏感型缓存,请执行以下任务:

  • 开发一个执行身份验证和授权的 servlet
  • 配置 Dispatcher
NOTE
通常,安全资源存储在与非安全文件不同的文件夹中。例如,/content/secure/
NOTE
当 Dispatcher 前面有 CDN(或任何其他缓存)时,您应设置相应的缓存标头,以使 CDN 不缓存专用内容。例如:Header always set Cache-Control private
对于 AEM as a Cloud Service,请参阅缓存页面,了解有关如何设置专用缓存标头的更多详细信息。

创建授权检查程序 servlet :headding-anchor:create-the-auth-checker-servlet

创建并部署一个 servlet 来对请求 Web 内容的用户执行身份验证和授权。Servlet 可以使用任何身份验证。它也可以使用任何授权方法。例如,它可以使用 AEM 用户帐户和存储库 ACL。或者,也可以使用 LDAP 查找服务。您将 servlet 部署到 Dispatcher 用作渲染器的 AEM 实例。

此 servlet 必须可供所有用户访问。因此,您的 servlet 应扩展 org.apache.sling.api.servlets.SlingSafeMethodsServlet 类,此类提供对系统的只读访问权限。

servlet 仅接收来自渲染器的 HEAD 请求,因此您只需要实施 doHead 方法。

渲染器包含请求的资源的 URI 作为 HTTP 请求的参数。例如,通过 /bin/permissioncheck 访问授权 servlet。要对 /content/geometrixx-outdoors/en.html 页面执行安全检查,渲染器在 HTTP 请求中包含以下 URL:

/bin/permissioncheck?uri=/content/geometrixx-outdoors/en.html

servlet 响应消息必须包含以下 HTTP 状态代码:

  • 200:已通过身份验证和授权。

以下示例 servlet 从 HTTP 请求中获取所请求资源的 URL。代码使用 Felix SCR Property 注释以将 sling.servlet.paths 属性的值设置为 /bin/permissioncheck。在 doHead 方法中,servlet 获取会话对象并使用 checkPermission 方法确定适当的响应代码。

NOTE
必须在 Sling Servlet Resolver (org.apache.sling.servlets.resolver.SlingServletResolver) 服务中启用 sling.servlet.paths 属性的值。

示例 servlet :headding-anchor:example-servlet

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());
     }
    }
}

配置 Dispatcher 以进行权限敏感型缓存 :headding-anchor:configure-dispatcher-for-permission-sensitive-caching

NOTE
如果您的要求允许缓存经过身份验证的文档,请将 /cache 分区下的 /allowAuthorized 属性设置为 /allowAuthorized 1。 有关详细信息,请参阅主题使用身份验证时缓存

dispatcher.any 文件的 auth_checker 部分控制权限敏感型缓存的行为。auth_checker 部分包含以下子部分:

  • url:执行安全检查的 servlet 的 sling.servlet.paths 属性值。

  • filter:指定将权限敏感型缓存应用于的文件夹的过滤器。通常,deny 过滤器将应用于所有文件夹,allow 过滤器将应用于安全文件夹。

  • headers:指定授权 servlet 包含在响应中的 HTTP 标头。

在 Dispatcher 启动时,Dispatcher 日志文件包含以下调试级别消息:

AuthChecker: initialized with URL 'configured_url'.

以下示例 auth_checker 部分将 Dispatcher 配置为使用上一个主题的 servlet。过滤器部分可促使仅对安全 HTML 资源执行权限检查。

示例配置 :headding-anchor:example-configuration

/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"
      }
    }
  }
recommendation-more-help
ce382601-480f-4a99-8be7-73178d4b6ef5