AEM Cloud Service - Permission Sensitive Caching for Protected Pages


This Adobe documentation very well explains the procedure for Caching Secure Content. The following post just puts together the code, dispatcher changes and screenshots to implement and verify dispatcher cache hits..

1) Add a servlet apps.eaem.sites.core.servlets.AuthCheckerServlet accepting HEAD requests for checking user access to protected pages (using SAML Authentication Handler on Publish)
package apps.eaem.sites.core.servlets;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Session;
import javax.servlet.Servlet;

@Component(
immediate = true,
service = Servlet.class,
property = {
"sling.servlet.methods=HEAD",
"sling.servlet.paths=/bin/experience-aem/permissioncheck"
}
)
public class AuthCheckerServlet extends SlingSafeMethodsServlet {
private Logger logger = LoggerFactory.getLogger(this.getClass());

public void doHead(SlingHttpServletRequest request, SlingHttpServletResponse response) {
String uri = request.getParameter("uri");

try{
Session session = request.getResourceResolver().adaptTo(Session.class);

try {
session.checkPermission(uri, Session.ACTION_READ);

logger.info("READ access APPROVED for uri " + uri + ", user : " + session.getUserID());

response.setStatus(SlingHttpServletResponse.SC_OK);
} catch(Exception e) {
logger.info("READ access DENIED! to uri " + uri);
response.setStatus(SlingHttpServletResponse.SC_FORBIDDEN);
}
}catch(Exception oe){
logger.error("Error checking permissions for uri :" + uri, oe);
}
}
}

2) Add necessary configuration in farm file dispatcher\src\conf.dispatcher.d\available_farms\eaem.farm for the dispatcher to call above servlet, check user access to page...

/publishfarm {
....
/cache {
/docroot "${DOCROOT}/content/marketing-hub"
....
/rules {
/0000 { /glob "*" /type "deny" }
/0001 { /glob "*.html" /type "allow" }
}
....
}
/auth_checker {
/url "/bin/experience-aem/permissioncheck"

/filter
{
/0000
{
/glob "*"
/type "deny"
}
/0001
{
/glob "/content/marketing-hub/*.html"
/type "allow"
}
}
/headers
{
/0000
{
/glob "*"
/type "deny"
}
/0001
{
/glob "Set-Cookie:*"
/type "allow"
}
}
}
}

3) Internal Dispatcher request to the publish url /bin/experience-aem/permissioncheck can be debugged in IDE (on both author and publish this safe servlet call doesn't need authentication)



4) Local dispatcher log shows the hits...



5) Opening the Docker Dispatcher Container terminal, you can find the cached protected pages in docroot eg.  /mnt/var/www/html/content/marketing-hub




6) Download the dispatcher log from cloud manager and you can observe the cache hit log statements....

[20/Oct/2022:21:14:26 +0000] [I] [cm-pxxxxx-exxxxx-aem-publish-xxxxxxx-xxxxxx] "GET /content/marketing-hub/en/website-management/aem-handling/adobe-sreek-test.html" -139ms [hub/-] [actionhit] dev.mywebsite.com

7) In the downloaded publish log, auth checker servlet leaves traces of dispatcher calls for checking user permissions....

2022-10-20 21:14:26.065 *INFO* [107.204.55.186 [1666300466054] HEAD /bin/experience-aem/permissioncheck HTTP/1.0] apps.eaem.sites.core.servlets.AuthCheckerServlet READ access APPROVED for uri /content/marketing-hub/en/website-management/aem-handling/adobe-sreek-test.html, user : xxxxxxxx/xxxxxxx

No comments:

Post a Comment