Permission Sensitive Caching (PSC)

Permission Sensitive Caching

In AEM, we have both secured pages as well as public pages. Dispatcher provides the capability to cache all the pages but dispatcher doesn’t know about secured or un-secured pages, so it serves all the pages to an Anonymous user. To get rid of this problem, dispatcher needs to know whether a page is to be served to a particular user. In AEM, Permission Sensitive Caching(PSC) provides this functionality which enables you to cache secured pages. Dispatcher checks user’s access permissions for a page before displaying the cached page.

So, when any request comes to the dispatcher, it hits an AEM servlet to check the user permission.

 

Let’s elaborate PSC integration with AEM 6.4 and Dispatcher 2.4.

Step 1: Dispatcher configurations need to be updated as explained below:

a. Add this code in publish-farm :

/auth_checker
  {
  # request is sent to this URL with '?uri=<page>' appended
  /url "/content.pagePermission.getPermission"    
  # 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/we-retail/secure-pages/*.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"
      }
    }
  }

Brief description about dispatcher configuration:

  • URL: The URL of the servlet that performs the security check.
  • filter: To specify specific folders on which permission sensitive caching is applied.
  • headers: Specifies the HTTP headers that the Authorization Servlet includes in the response.

b. Also, make sure allow Authorized is set to 1 under the cache configuration.

/cache
{
 ...
 allowAuthorized “1”   
 ...
}	

Note: Any page path which matches the PSC filters, the dispatcher will hit AEM servlet before serving the page from cache, so wisely define filters because network calls increase on each page hit.

 

Step 2: Now we must create a servlet in AEM which will check if the resource or page is authorized or not for the user who requests the web content and sends response Header.

Below is the Java Servlet to which dispatcher sends HEAD request :

import java.security.AccessControlException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.sling.SlingServlet;
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;
 
/**
* This servlet will validate that the requested page uri is accessible or not and then accordingly set the response header.
*
*/
@Component( service = Servlet.class,
property = { sling.servlet.methods= "HEAD", sling.servlet.resourceTypes = "sling/servlet/default” sling.servlet.selectors = {"pagePermission"}, sling.servlet.extensions = {"getPermission"})
public class AuthcheckerServlet extends SlingSafeMethodsServlet {
 
  /** The Constant LOGGER. */
  private static final Logger logger = LoggerFactory.getLogger(AuthcheckerServlet.class);
 
  /**
   * Method to handle the HEAD request for the servlet.
   * 
   * @param request - The request object.
   * @param response - The response object.
   *
   */
  @Override
  public void doHead(SlingHttpServletRequest request, SlingHttpServletResponse response) {
      logger.debug("Start of doHead Method");
      // retrieve the requested URL
      String uri = request.getParameter("uri");
      uri = uri.replace(HTML, EMPTY);
      // obtain the session from the request
      Session session = request.getResourceResolver().adaptTo(javax.jcr.Session.class);
      if (session != null) {
        try {
     // perform the permissions check
        session.checkPermission(uri, Session.ACTION_READ);
        response.setStatus(SlingHttpServletResponse.SC_OK);
      } catch (AccessControlException | RepositoryException e) {
          response.setStatus(SlingHttpServletResponse.SC_FORBIDDEN);
        }
      }
      else {
        response.setStatus(SlingHttpServletResponse.SC_FORBIDDEN);
      }
      logger.debug("End of doHead Method"); 
  }
}

 

Step 3: Restart the dispatcher and you are all set up.

 

Verification

To check if the Permission sensitive caching is working or not, goto dispatcher.log file, this message must be present there:

AuthChecker: initialized with URL ‘configured_url‘.

 

To Check the AuthChecker Servlet response, hit the following curl command:

  1. Without Authentication

curl –head http://publishserver:port/content.pagePermission.getPermission?uri=/content/we-retail/secure-pages/pageName.html

Response:

HTTP/1.1 403 Forbidden
Date: Tue, 04 Sep 2018 09:38:31 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 0

2. With Authentication

curl –head http://publishserver:port/content.pagePermission.getPermission?uri=/content/we-retail/secure-pages/pageName.html –user username: password

Response:

HTTP/1.1 200 OK
Date: Tue, 04 Sep 2018 09:42:19 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 0