Permission Sensitive Caching in AEM

In Adobe Experience Manager (AEM), some pages are public (accessible to everyone), while others are secured (restricted to certain users). By default, the Dispatcher stores all pages—both public and secured—but it doesn’t check who should see them. This means that even secured pages could be displayed to unauthorized or anonymous users, which poses a security risk.

Permission-sensitive caching enables you to cache secured pages. Dispatcher checks the user’s access permissions for a page before delivering the cached page.

The Dispatcher integrates the AuthChecker module, which enables permission-sensitive caching. When activated, this module triggers an AEM servlet to verify the user’s authentication and authorization for the requested content. Based on the servlet’s response, the Dispatcher decides whether to serve the content from the cache or not.

Implementing permission-sensitive caching

  • Create the Auth Checker servlet:

Create and deploy a servlet that performs authentication and authorization for the user requesting web content and sends a response Header.

The servlet obtains the session object and uses the checkPermission method to determine the appropriate response code.

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

  • Configure Dispatcher for permission-sensitive caching:

The auth_checker section of the dispatcher.any file controls the behavior of permission-sensitive caching. Add this code to the publish-farm. The auth_checker section includes the following subsections:

  • 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.
/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"
}
}
}

Also, ensure that ‘allowAuthorized’ is set to 1 under the cache configuration.

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

References: https://experienceleague.adobe.com/en/docs/experience-manager-dispatcher/using/configuring/permissions-cache

AEM Content Distribution – Forward Distribution

AEM distribution agents execute the requests by creating packages from a source Sling instance containing content for the specified paths and then pushing and installing these on a target instance.

In AEM, the distribution agent is used to push the content from the author instance to the publish instance. AEM provides the following way to replicate content:

  • Forward Distribution: “pushing” the content to target instances

  • Reverse Distribution: “pulling” content from the remote source instances

  • Sync Distribution: “synchronizing,” i.e., synchronizing content across multiple instances with a coordinating instance.

  • If you want to configure or create a forward distribution agent in the AEM touch UI, you must follow this step.

    1. Navigate to Tools > Deployment > Distribution > Publish Agent, and click on the Publish Agent to configure your settings.
      AEM Content Distribution - Aurx

    2. You can also create your custom agent by clicking on the Create button on the top right.

      And fill in some information about your agent.

      Note: Always keep in mind that when you provide a name to your custom agent, there should be no spaces between that name; otherwise, “JobHandlingDistributionQueue” could not add an item to the queue.

      Example:

      Non-compliant name: Distribution Agent (it will raise a NullPointerException)
      Compliant name: customDistributionAgent
      AEM Content Distribution - Aurx

      AEM Content Distribution - Aurx
      Configuration Field List:

      1. Name: name of distribution Agent

      2. Type: Type of Distribution Agent (ex: Forward distribution or Reverse distribution)

      3. Title: Title of your distribution agent

      4. Enabled: Field to Enable or Disable your agent

      5. Service Name: The service name is optional, if required, create a service user with the required permission and change the level if required

      6. Allowed roots: Configure the content Roots the agent allowed to distribute

      7. Importer Endpoints: List of publisher endpoints to which packages are sent

        An endpoint is, by default:

        endpoint0=http://localhost:4503/libs/sling/distribution/services/importers/default

        But you can provide your server-specific endpoint URL, like:

        endpoint0=http://192.168.29.76:4503/libs/sling/distribution/services/importers/customDistributionAgent.

        But for your own definition of endpoint URL, you have to configure something.

    3. If you are not using the default admin credentials, then you need to configure the distribution agent with a different username and password.
      Follow the steps below:

      1. Navigate to Tools > Operations > Web Console or http://<host>:<port>/system/console/configMgr to open the Adobe Experience Manager Web Console screen.
      2. Search for Apache Sling Distribution Transport Credentials – User Credentials based DistributionTransportSecretProvider.
        AEM Content Distribution - Aurx
      3. Create a configuration by populating the name, username, and password.
        AEM Content Distribution - Aurx
        Configuration Field List:

        1. Name: Give a name to DistributionTransportSecretProvider

        2. User Name: Name of your publish instance user

        3. password: Password of your publish instance user

      4. Click save.
      5. Use Cmd +F to search for Apache Sling Distribution Agent – Forward Agents Factory to open the configurations and search for Transport Secret Provider.
        AEM Content Distribution - Aurx
      6. Update the (name=default) with (name=customDistributionAgent)Custom distribution data filled image
      7. Configuration Field List:
        1. Name: Give a name to the Distribution agent’s forward factory(customDistributionAgent)

        2. Title: Title of Distribution agent’s forward factory(Custom Distribution Agent)

        3. Transport Secret Provider: update this field with your custom TransportSecretProvider name(customDistributionAgent)
      8. In the publish instance, navigate to Tools > Operations > Web Console or hit this URL: http://<publish_host>:<publish_port>/system/console/configMgr.
      9. Use Cmd +F to search for Apache Sling Distribution Importer – Local Package Importer Factory, open the configurations, and enter the name as “customDistributionAgent”.
      10. Click Save and run the test connection from the Distribution Agent screen on your AEM instance.
      11. Click Test Connection from the action bar to validate the communication of the author with the publish instance, as shown in the figure below.
        AEM Content Distribution - Aurx
        Now we are ready with the forward content distribution agent, but it will not be used in the replication process if we publish any page from the sites console, because AEM uses the default replication agent to complete that publication. Below, we will understand this in a more efficient manner.
        AEM Content Distribution - Aurx
        If we want to publish any page, then we click on that page and click on Quick Publish, so our page will be published. But now the default replication agent is working, not our custom distributed agent. We can check this in the logs of both agents. I published a /content/we-retail/language-masters/en/experience/arctic-surfing-in-lofoten page.
        Note: If you want to check the logs of the default replication agent, then you should navigate to Tools > Deployment > Replication > Agent Author and click on the default agent (author). Click on View Log.
        AEM Content Distribution - AurxAEM Content Distribution - AurxAEM Content Distribution - Aurx
        When we compare both images, there are no logs printed in our customDistributionAgent. While in AEM default replication agent did the publication.
        In AEM out-of-the-box functionality, by default, when we publish any content, the automatic replication agent invokes and completes the process of publication. If we want to use our distribution agent, then we should do some configuration in the AEM replication default agent.

        To activate our distribution agent as the default distribution agent, we have to do more configuration. Until now, our distribution agent is ready.

        Navigate to Tools > Deployment > Replication > Agents on Author and click on the Default Agent (Publish) to configure the setting.

      12. Now click on the edit button and make the required configuration changes, as shown in the figure below:

    4. user, password field will be blank.
    5. Configuration Field List:
      1. In the settings tab:
        1. Name: Name of your replication agent

        2. Description: Description of agent

        3. Enabled: To Enable or disable your Agent

        4. Serialization Type: Select ‘Distribution’ from dropdown.
      2. In Transport tab:
        1. URI: Publisher endpoints to which packages are sent (But in this configuration, we are providing our distribution agent URL) i.e.(distribution://customDistributionAgent)

        2. User: should be kept blank
        3. Password: should be kept blank

    6. Click OK to save the changes.
      Note: As you can see in the figure, in the transport tab, you get the default URL, which you have to replace with your distribution agent name (distribution://<customDistributionAgentName>). The user, password fields must be left blank in order to make the replication agent to work. In the settings tab, the agent user ID field will also be blank.)
    7. To check whether our configuration is working or not, quickly publish a page, and we will check our custom distribution agent logs.

    8. Now our page is published with our custom distribution agent.