- Published on
AEM Dispatcher Series 3 - Securing Your AEM Site - Deep Dive into Dispatcher `/filter` Rules
- Authors

- Name
- Khalil
- @Im_Khalil
If you’ve been following along, you now understand the role of the AEM Dispatcher and how its dispatcher.any file is structured.
In this post, we’ll focus on one of the most critical parts of that file — the /filter section.
This is the Dispatcher’s security gate — the rulebook that decides which requests are allowed to reach AEM and which are denied at the door.
Why /filter Rules Matter
If you’re an AEM developer, you’ve probably heard something like:
- “I can’t access my servlet.”
- “I’m getting a 403 Forbidden.”
- “Why can’t I hit
/system/consoleon Publish?”
Nine times out of ten, the answer lies in the Dispatcher’s /filter section.
Even though DevOps or AMS teams often maintain these files, understanding filters is vital for developers because:
- You’ll need to safely expose custom endpoints like
/bin/my-servlet. - You’ll debug 403 Forbidden errors during testing.
- You’ll collaborate better with ops teams by explaining what your code needs access to.
Understanding How /filter Works
Dispatcher filters act as allowlists or denylists for incoming HTTP requests. They determine what URLs are allowed to pass through to AEM Publish or Author.
At a high level:
- Each rule has a
/type— either "allow" or "deny". - Each rule has a
/url(and optionally/method) pattern that it applies to. - Dispatcher evaluates rules in order, from top to bottom.
If a request matches a rule, that rule decides whether to allow or deny it. Once a match is found, Dispatcher stops evaluating further rules.
Default Behavior: Deny or Allow?
Dispatcher has no true default allow. If a URL does not explicitly match an allow rule, it is effectively denied.
This default-deny model is intentional. You explicitly allow only what is safe.
Example: A Simple /filter Section
/filter {
/0001 { /type "deny" /url "/crx/*" }
/0002 { /type "deny" /url "/system/console/*" }
/0003 { /type "allow" /url "/content/*" }
/0004 { /type "allow" /url "/etc.clientlibs/*" }
/0005 { /type "allow" /url "/content/dam/*" }
/0006 { /type "allow" /url "/dispatcher/invalidate.cache" }
/0007 { /type "allow" /url "/libs/granite/core/content/login.html" }
}
How it works:
- Requests to
/crx/*or/system/console/*are denied. - Regular website content under
/content/is allowed. - Client libraries and DAM assets are allowed.
- Special endpoints for cache invalidation or login are allowed.
Real-World Example: Allowing a Custom Servlet
Suppose you have a custom path based servlet at /bin/my-servlet. It works on Author, but on Publish you get 403 Forbidden.
This is because /bin/* is not allowed by default. To fix it, add an allow rule.
Step 1: Add the rule
/filter {
...
/0050 { /type "allow" /url "/bin/my-servlet" }
}
Step 2: Restrict it if needed
If the servlet is for authenticated users or internal use, restrict by method:
/filter {
...
/0050 {
/type "allow"
/url "/bin/my-servlet"
/method "POST"
}
}
Only POST requests are allowed; GET requests are denied.
Example: Allowing a JSON Endpoint Safely
Suppose you have a component that fetches JSON data from /content/mysite/en/home.model.json.
If you get 403, explicitly allow .model.json requests:
/filter {
...
/0060 { /type "allow" /url "*.model.json" }
}
Avoid overly broad patterns like /*.json which could expose sensitive endpoints.
Example: Denying Access to AEM Consoles
Blocking access to administrative paths is critical. A recommended set of deny rules:
/filter {
/0001 { /type "deny" /url "/crx/*" }
/0002 { /type "deny" /url "/system/console/*" }
/0003 { /type "deny" /url "/libs/granite/*" }
/0004 { /type "deny" /url "/apps/*" }
/0005 { /type "deny" /url "/bin/querybuilder.json" }
/0006 { /type "deny" /url "/conf/*" }
}
These prevent access to internal tooling and administrative APIs.
Dispatcher processes /filter rules in numerical order, typically /0001, /0002, /0003, etc.
If you add a new rule, ensure it does not override or conflict with existing ones.
For example:
- If
/0002denies/content/*but/0003allows/content/mysite/*,/0002blocks everything before/0003can allow it.
Always order rules carefully, placing specific allows before broader denies when needed.
Debug Tip: Logging and Testing Filters
- Enable Dispatcher debug logging in Apache configuration:
DispatcherLogLevel 3
- Check dispatcher.log for entries:
Filtering URI '/bin/my-servlet' - denied
Filtering URI '/content/mysite/en.html' - allowed
- Test your updated
/filterrules in a lower environment before production.
Key Takeaways for Developers
- The
/filtersection is your security gate. - Dispatcher uses a default-deny model — only explicitly allowed paths are permitted.
- Always write specific rules, never broad wildcards like
/or/*.json. - Order matters — rules are evaluated top to bottom.
- Understanding filters helps you quickly fix 403 and access issues.
Next: Part 4 — A Developer’s Guide to Dispatcher /cache Rules
You might also like to read
- 1.AEM Dispatcher Series 1 - A Developer’s Guide to What It Is and Why You Should Care
- 2.AEM Dispatcher Series 2 - Understanding the `dispatcher.any` File
- 3.AEM Dispatcher Series 4 - A Developer’s Guide to Dispatcher `/cache` Rules
- 4.AEM Dispatcher Series 5 - When and How to Clear Cache
- 5.AEM Dispatcher Series 6 - Handling Vanity URLs, Sessions, and `/renders`