技术

AEM特性——作者预览Servlet

里卡多。安嫩代尔7 e2pe9wjl9m Unsplash

为什么这是需要吗?

这可能只是我,但我发现它非常常见的客户未经过身份验证的请求URL查看正在进行的页面在一个AEM作者实例。问很多意义,往往那些批准内容往往会一眼,只是想给AEM作者系统中,不需要大量的时间或专用的登录/帐户。相反,它会很高兴有一个预览内容的方式在上线之前,可能通过离线或电子邮件审批流程。今天,不可用和AEM开箱即用的,人们想有这种行为有一个专门的“预览”发布实例,或者,必须咬紧牙关,迫使他们所有审批人员登录之前看到任何内容。

一个新的挑战者的方法

进入预览Servlet。这个定制servlet直接绕过身份验证,并允许一个页面呈现活跃作者实例。怎么,你问?吊索Servlet规范内的小窍门删除Servlet请求身份验证,再加上一个单独的VHost apache配置用来迫使所有交通要求通过我们预览Servlet。(理想情况下,这是通过一个独立的,特定的子域)

现在,让我们打破这个servlet是如何工作的。

预览Servlet

servlet本身非常简单。这个servlet将侦听给定端点,从传入后缀,确定内容呈现。例如,使用默认的端点,预览。html,我们可以渲染we-retail根与以下页面:

/ preview.html /内容/ we-retail /美国/ en / men.html

上面会看起来非常熟悉那些AEM作者UI内工作,利用相同的概念在使用后缀。类似于编写UI中,我们使用后缀来确定所引用的页面。然而,有一个关键的区别,开箱即用的服务利用后缀是利用初始用户会话/认证,同时我们会需要我们的服务可用于未经身份验证的用户。

幸运的是,有一个吊索的财产删除认证要求一个servlet。属性定义如下:

sling.auth.requirement = - /预览

当然,作为一个惯例您可能想使用一个静态变量来设置这个,而不是硬编码的字符串,所以将看起来像下面的定义:

@ component(服务= {Servlet。类,过滤器。类},立即= true属性={常数。SERVICE_DESCRIPTION + " = " +“预览”servlet, ServletResolverConstants。SLING_SERVLET_METHODS + " = " + HttpConstants。METHOD_GET ServletResolverConstants。SLING_SERVLET_RESOURCE_TYPES + " = " + " perficient / servlet /预览”,ServletResolverConstants。SLING_SERVLET_EXTENSIONS + " = " + PreviewServlet。URL_SUFFIX AuthConstants。AUTH_REQUIREMENTS + + PreviewServlet = -。URL_PREFIX})

太棒了!现在我们有了一个servlet,允许匿名访问,可以阅读页面我们想呈现的路径!然而,我们仍然不做任何路径本身。现在,有趣的东西——是时候页面内容。要做到这一点,我们可以使用另一个方便的类,RequestDispatcher。这将需要提供的资源节点和调度请求呈现。好吧,这太棒了!然而,我们仍然在一个未经身份验证的状态,所以在这一点上我们需要确保我们呈现内容用户有读权限。这就是你的安全团队的一部分被惹恼的时候,我需要给以下免责声明:

* * * *的免责声明

  1. 如果你打开你的网站匿名作者读者,即使只有只读权限,你需要非常注意路径暴露。,请非常非常,仔细的在用户权限分配您的服务。
  2. 匿名用户访问您的端点为目的的审查应算作一个作者用户AEM的许可证。这不是为了让更多作者比合同允许的用户。

免责声明的,让我们继续。

在这一点上我们需要分配一个用户请求转发的服务请求分配器。为此我们使用一个相对常见的策略创建一个包装器的吊索请求包装和更新一套预先配置的倾诉在资源解析器。表示服务用户在我们的实现中通过属性/ conf中是可配置的。虽然不是必需的,但是这是我强烈推荐的方法,特别是对于那些在多租户系统。

这是一个示例servlet的包装和服务用户附件逻辑:

ResourceResolver ResourceResolver = repoService.getResourceResolver(本);对象oldRR = request.getAttribute (AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);WCMMode模式= WCMMode.DISABLED.toRequest(请求);{request.setAttribute (AuthenticationSupport试试。REQUEST_ATTRIBUTE_RESOLVER resourceResolver);SlingHttpServletRequestWrapper包装= new SlingHttpServletRequestWrapper(请求){@Override公共ResourceResolver getResourceResolver(){返回ResourceResolver;}};RequestDispatcher调度员= request.getRequestDispatcher (newResource);调度员。转发(包装、响应);…

还要注意我们设置WCMMode禁用,这样可以确保一切都会呈现,好像一个出版商。

时间测试,对吗?不幸的是,我们错过了一个重要拼图的。

资产和内部链接引用页面上的内容吗? !

当你请求通过servlet端点(/预览。html对于本文章的目的),链接,以及相关的资产仍将没有前缀,因此,需要对作者身份验证。我们如何绕过了吗? !因为大多数发展中存在的问题,有一些方法来解决这个问题。一种可能性是编写一个链接重写重写一切解决通过servlet,基于servlet的前缀。这种方法,虽然可能是困难和挑剔。相反,另一种选择在apache专门创建单独的VHost预览请求。在重写这个方法有几个好处:

  1. 指定预览servlet时一个专门的领域,我们可以很容易地调整透传url总是包含/预览。html,暴露链接匹配您的生产服务器
  2. 不需要维护两个独立的重写管道相同的内容

Apache VHost

在这一点上,我们非常接近的预览方案我们需要一个页面的标记可以未经身份验证的。我们只是需要确保每一个我们未经身份验证的servlet请求通过,而不是最初的页面请求。虽然这听起来复杂,这实际上是最简单的部分!剩下的工作就是创建一个apache VHost致力于你的预览端点。尽管可能没有子域,这里强烈推荐——一个例子:

http://preview-author.perficient.com/

现在,随着一个映射,我们可以很容易地迫使所有流量通过servlet !

重写/ (. *)/ preview.html / (. *) [PT, L]

然后,以防,我也强烈建议阻止一些基本AEM的链接:

# 301 aem网站接口/资产他们寻找RewriteCond ^ /(网站| |编辑资产)。html /重写。+ . html /(. *) /预览。html / 1美元(R = 301,数控,L) # 404系统仅端点RewriteCond ^ / (aem | crx |系统)重写。* - (R = 404 L) #预览交通透传重写/ (. *)/ preview.html / (. *) [PT, L]

当然,上面的是例如目的——并将有更多的路径你想限制从预览的角度来看。说完这些,最好确保你的服务用户最小权限来减少这种风险。另一个重要的安全步骤是配置一个白名单,如果可能的话,只允许人们从特定IP的使用这个功能。

下一个步骤

如果你想要进一步的事情,我建议来实现一个按钮进入AEM“编辑器”界面预览作者“开放”。这将使链接生成和分布更容易传福音。

笔记

上面不会为AEM工作作为云服务(AEMaaCS)部署。然而,如果你正在与AEMaaCS, Adobe还包括一些预览功能正如我们所见它利用一个单独的实例。

荣誉

信贷servlet实现和概念证明我有才华的朋友保罗Bjorkstrand

横幅图片由里卡多。安嫩代尔Unsplash

编码快乐,你们。

关于作者

多解决方案架构师拥有超过十年的经验在Adobe堆栈。

从这个作者

对“AEM特性——作者预览Servlet”的想法

  1. 嗨,保罗,你好瑞恩!

    这是一个很酷的特性,谢谢你的帖子!正如你提到这是一个反复出现的许多客户的请求时,我与我的同事讨论了这个内部。我们总是拒绝了这些原因:

    *一个预览是不错,但预览没有一枝独秀。通常使用一个预览审批工作流的一部分。这意味着有人预览然后接受或拒绝的内容。但在这种情况下预览只是故事的一半,和你批准/拒绝通常带外,通过电子邮件/电话/松弛/…也不好,因为这种反馈不是链接到页面本身,而不是记录在系统中。在一个所有AEM工作流要好得多。

    *安全:基本上你禁用任何安全保护的内容,因为每个人都知道模式可以访问很多AEM创作实例。你甚至不知道谁访问你的新内容之前,已经公开。

    *许可:如果你的AEM许可证有关于命名用户的限制,这种方法可以说你绕过这个限制。因为你不需要创建任何账户了评论家。

    我们的建议总是:实现SSO,那么你的评论家不需要显式地登录了,但你可以让你的评论者直接deep-link开幕请求的页面预览模式。然后他们通过身份验证,可以批准或拒绝工作流,他们的访问可以记录审核,没有许可的问题。

    但是:有预览预览模式需求无法满足,因此有预览环境AEM云服务。的个性化的主题,但这主要是因为编辑预览是真实的难解决。

    欢呼,
    Jorg

  2. 瑞安·麦卡洛文章作者

    嘿,Jorg,

    欣赏有思想的评论。我完全同意,在一个理想世界中,我们能有预览功能的审批人员或用户登录,并利用工作流。话虽这么说,我的很多客户在过去这是一个非起动器因为各种各样的原因,因此需要一个未经身份验证的观点。的安全问题,我想明确,在博客,这是极其危险的公开内容,这样,服务用户权限以及内部IPs(理想情况下)一个白名单或类似添加到域。这并不排除安全隐患,但可以帮助减少他们在该方案中,这是必要的。

    在授权方面,这是一个非常有趣的点。我不认为其目的是绕过这个限制,但是可以看到它如何可能是杠杆等。我会注意添加到文章称,这项服务的用户应该对任何作者用户总数计算。

    总的来说,我完全同意的标准推荐SSO和深度链接,但这篇文章是专门为那些客户端不能的情况下,无论出于何种原因,利用这种方法。例如,我们的许多客户相当犹豫授予SSO访问外部组织,如设计/媒体机构,需要审批流程。对于那些选择不添加SSO占这些外部用户(这是很常见),他们倾向于依靠传统离线方法。这些更加困难和耗时,因为它们主要涉及静态再现(PDF或截图)或screen-shares。在这些情况下,SSO不是一个潜在的解决,Adobe有另一种方法要填补这个空缺吗?

    欢呼,
    瑞安

  3. 嗨,瑞安,

    这解决了要求,和通过电子邮件发送截图早已经解决了吗?在这种情况下我理解,这种方法既可以是一个巨大的进步,但这仍然安全开放的问题。
    如果你的客户不想提供SSO访问AEM的机构,我也认为他们不提供VPN访问。在这种情况下你的“预览”端点是全球开放(只要你知道URL)。

    回答你的最后一个问题:我不知道这是一个差距。假设需要身份验证和授权,SSO仍然是最好的和最容易的方法来解决这个问题。

  4. 你考虑过生成JWT作为请求参数和发送吗?JWT可以验证:

    1。,通过验证的用户拥有一个有效的共享链接JWT对服务器的私钥签名
    2。用户访问内容应该能够通过限制路径JWT体内
    3所示。分享链接没有过期通过检查到期日期

    你可以创建一个工作流或一些UI元素分享内容,允许作者指定的页面(s)分享和截止日期,然后生成共享URL (s)。

    这将是类似于特定资产份额AEM资产的特性。

  5. 瑞安·麦卡洛文章作者

    这是一个了不起的主意——肯定会增加2.0版本的列表功能。谢谢你的反馈,丹。

留下一个回复

这个网站使用Akismet来减少垃圾邮件。学习如何处理你的评论数据

博客订阅每周消化:

报名