Magnolia 5.6 reached end of life on June 25, 2020. This branch is no longer supported, see End-of-life policy.
Java filters were introduced in the Java Servlet specification version 2.3. A filter intercepts requests and responses to transform or use the information. Filters typically do not themselves create responses, but instead provide universal functions that can be "attached" to any type of servlet or JSP page.
Since the filter chain is responsible for request handling in Magnolia, the default chain illustrates how filters are used to process requests. This document provides minimal information on filters. For more, see Request processing and filters and the filters
package.
Don't change the filter order
Magnolia handles incoming requests to display a page through its own filter chain. Filters in the chain are executed in the order in which they are declared until a filter decides that it can fulfill the request.
Be careful
When editing properties in the filter chain be careful. Always test the changes on test environment before applying it to production.
For instance, if you add a
The first filter in the filter chain is
MgnlContext
and configures MDC logging. MgnlContext
is local to the request and available on every further filter. The context provides a lot of useful functions, see The job of the ContentTypeFilter
is to initialize the non-content related attributes of the
It's created and populated with:
The AggregationState
is accessible using MgnlContext.getAggregationState()
.
Magnolia 5.4.5+ The Content-Type
header is not set by ContentTypeFilter
anymore. The MIME type was incorrectly set according to the request extension. It is now the responsibility of renderers/servlets to set the correct content type. For instance
Magnolia 5.4.3+ Content type filter can be configured to match requests to content types. See Restricting responses to configured MIME types.
TraitCollector
.
Country#REQUEST_PARAMETER
with an IP address is supplied, this address is used to resolve the country, which is stored in the TraitCollector
.visitorCookies
can be configured for returning and registered users.Node name | Value |
---|---|
visitor | |
visitorCookies | |
returning | returning |
level | 5 |
name | VISITOR |
value | returning |
registered | registered |
name | VISITOR |
value | registered |
new | new |
maxAge | 86400 |
name | NEW_VISITOR |
value | new |
class | info.magnolia.personalization.visitor.VisitorDetectorFilter |
Additional Properties
(Applicable to the cookie name nodes, i.e. to "returning", "registered" and "new" in the above examples.)
httpOnly | optional, default is A security setting that prevents cookies from being read by a potentially malicious code. |
secure | optional, default is Setting the property to |
Only used by the STK.
Handles incoming login requests and delegates to login handlers. The handlers are configured under this filter.
The activation filter handles incoming activation requests. This filter is the receiving part of the activation process.
The activation filter is implemented using
ReceiveFilter
to provide transaction related communications with syndicators.Here's an example of how to use the bypass feature to avoid specific filters. This configuration will only handle requests where the URI starts with /.magnolia/activation
.
Node name | Value |
---|---|
activation | |
bypasses | |
allButActivationHandler | |
class | info.magnolia.voting.voters.URIStartsWithVoter |
not | true |
pattern | /.magnolia/activation |
class | info.magnolia.module.exchangetransactional.XAReceiveFilter |
To increase the performance of the site
doFilter(..)
call to the filter chain. After all the following filters have been executed, content is extracted from the ResponseWrapper, gzipped and written to the original response.mgnlLogout
is set as a request parameter. If this flag is found, the user will be logged out and the filter chain will restart with the first filter.AccessDeniedExceptions
. The filter renders an appropriate "login form" that can consist of a redirect or anything else.Multiple HttpClientCallbacks
with different configuration and behavior can be configured for this filter.
Here is the client callback configuration for the Travel demo members area redirect and login form.
Node name | Value |
---|---|
securityCallback | |
clientCallbacks | |
travel-demo-pur | |
originalUrlPattern | |
class | info.magnolia.cms.util.SimpleUrlPattern |
patternString | (*|travel)/members/(profile-update|protected)* |
class | info.magnolia.cms.security.auth.callback.RedirectClientCallback |
location | /travel/members/login.html |
form | |
class | info.magnolia.cms.security.SecurityCallbackFilter |
Both callback classes implement the
Classes:
loginForm
.url
. Current request URL decoded and without the context path.urlPattern
originalUrl
. Original request URL decoded and without the context path, but not modified by any filter.originalUrlPattern
hostPattern
voters
For example, in a multisite installation for the request
http://demo.magnolia-cms.com/travel/about.html :
url
is /about.html
originalUrl
is /travel/about.html
.The Multisite filter removes the first-level node name from the URL.
The methods provided by AbstractHttpClientCallback
are also provided by the utility class
If you access Magnolia with a script, set the referer header in your script to ensure the script can access Magnolia. Similarly, if you embed Magnolia content into a different website, disable the CSRF filter or add a voter (see below) that bypasses the CSRF filter for any requests coming from the trusted URL.
The CSRF security filter causes a request to fail if:
The referer header is empty
Host: mysite.com/.magnolia/pages/adminCentral.html Referer:
The host part of the referer header does not match the requested host.
Host: mysite.com/.magnolia/pages/adminCentral.html Referer: hackersite.io
You can bypass the CSRF security filter with a voter.
By default, the filter is bypassed if:
/.magnolia
. Only AdminCentral URLs are vulnerable to CSRF attacks. Other URLs are not checked. You can create your own whitelist of referrer domains or URIs using a voter. The filter is bypassed for the whitelisted referrers. In this example we bypass the filter for any requests referred by http://www.trustedsite.com/
.
Node name | Value |
---|---|
csrfSecurity | |
bypasses | |
BypassWhenNotInAdminCentral | |
BypassWhenNotAuthenticated | |
BypassWhenNoQueryParameters | |
BypassWhenVaadinRequest | |
whitelist | |
class | info.magnolia.voting.voters.RequestHeaderPatternSimpleVoter |
headerName | referer |
pattern | http://www.trustedsite.com |
class | info.magnolia.cms.security.CsrfSecurityFilter |
Voter properties:
<voter node> | required Voter node. Name the node for example |
| required Fully-qualified voter class name. Available classes:
|
| required Header you are checking such as |
| required Domain or URI pattern compliant to $webResourceManager.requireResource("info.magnolia.sys.confluence.artifact-info-plugin:javadoc-resource-macro-resources")
SimpleUrlPattern
. The pattern must be present in the header for the filter to be bypassed. |
Some builds of Internet explorer don't send the HTTP request header referrer when submitting a form or when opening a pop up. If the referrer is not in the HTTP request header, CsrfSecurityFilter#handlePossibleCsrf
interprets the request as potential CSRF attack which forces the user to login on the pop up. (See
MAGNOLIA-6211
-
Getting issue details...
STATUS
). To overcome this "issue", add voter class
Node name | Value |
---|---|
csrfSecurity | |
bypasses | |
userAgent | |
allowed | |
IE6 | .*MSIE 6\.0.* |
IE11 | .*Trident/7.0; rv:11.0.* |
class | info.magnolia.voting.voters.UserAgentVoter |
Below the node allowed
you can add a list of regular expressions to match the HTTP header userAgent. In the example above we have bypassed Internet Explorer 6 and 11.
To ensure the filter is bypassed, make sure to have at least one property on the node allowed
with a value which will match the userAgent of the browser for which you want to bypass the filter. (For Internet Explorer 11, the userAgent might be Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko.)
Always test changes on test environment before applying it to a productive system. When adding an erroneous regular expression - you won't access admin central anymore. (In such case you have to use Groovy Rescue App).
travel
site through www.travel.com
, no other URL can be used to access the content. When a user tries to access one site's content through another site's domain name, the system displays a HTTP 404 error (page not found). See Cross-site securityUriSecurityFilter
to provide site aware functionality.The following constraints are considered in finding the permissions of the user:
If the user does not have the permission to access the URI then JAAS will provide a login form. This default behavior of the URI security filter can be changed in JAAS configuration.
You can configure your own login form in the URI security filter to replace the default Magnolia login form. The form is configured in /server/filters/securityCallback/clientCallbacks
. Here is an example of a custom form used to grant public users access to a restricted members area. Authentication is delegated to the custom form when a particular URI is accessed.
If you don't grant permission to the custom login form path then a standard Magnolia login form will be displayed, usually on author instance.
The cache filter checks if a requested resource is already stored in the cache to avoid recreation of the resource. If the resource is in the cache, then it will be written to the response and the filter chain stops. If the resource is not found in the cache, then a ResponseWrapper
which not only writes to the "standard" response, but also saves the response, is passed to the chain. After the filters that follow have been executed (and the requested resource created), the content is extracted from the response wrapper and stored in the cache.
The cache filter is part of Cache core and the respective configuration can be found in the module configuration.
The servlets configured in modules are installed in Magnolia's servlets filter chain using the
service(..
) method of the servlet is called. See Registering a servlet for more.Finally we arrive at the filter chain which does the page rendering and delivery. The filters are grouped in this filter chain so they share a co-bypass definition.
website
workspace. Therefore a request URI is interpreted as the path to a node in the website
workspace. If you want to address nodes in other workspaces you need to specify a repository mapping in /server/URI2RepositoryMapping
.Whereas the URI security filter checks permissions on the URI,
If the user does not have permission to the resource, then JAAS will provide a login form. This default behavior of the content security filter can be changed in JAAS configuration.
Target | Collected information |
Page |
|
NodeData |
|
AggregationState
) using all available traits stored in the TraitCollector
and wraps it accordingly, if required. It only uses PersonalizationNodeWrapper
if a variant was resolved. Non-variants are not wrapped.Node name | Value |
---|---|
server | |
filters | |
cms | |
variantResolver | |
wrapOnlyPersonalizedNodes | true |
Property:
| optional , default is If set to |
Deprecated since Magnolia 5.1. This filter is no longer used. It's function is now handled in part by the page editor and in part by the MultiChannelFilter
.
redirect
, permanent
or forward
.Finally,
The rendering filter is terminal, meaning it ends the filter chain and filtering process. If no filter before it has been able to fulfill the request and the rendering filter cannot find the page either, then a 404 "Page not found" error is returned. This is default behavior.
You can change the behavior by adding a terminateChain
property under the rendering filter and setting it to false
. When a request for a page such as /home/some/page
is received and no such page exists in the JCR, your own servlets can have a go at fulfilling the request. The default value for the terminateChain
property is true.
Access to resources is defined in the /modules/resources/config/resourceFilter
filter. By default, the filter allows access to resources as follows:
byType
css, map, js, htm(l), ico, woff(2), ttf, svg, gif, jp(e)g, tiff, bmp
byLocation
webresources
' directoryThe AddHeadersFilter implementation class allows configuration of a filter for adding HTTP headers to enable, for example, Cross-origin resource sharing (CORS). The parameters configured in this filter are added to the HTTP header if the filter is triggered. You can restrict the filter's scope by adding and configuring a bypasses
node to it. For details please refer to the Magnolia main filter page.
Example configuration for CORS
The example allows CORS with header types true info.magnolia.cms.filters.AddHeadersFilter X-Requested-With, Content-Type, AcceptX-Requested-With
, Content-Type
, Accept
, with the GET
method, and from any origin:Node name Value GET *
The position of a filter whithin the filter chain matters. The appropriate position depends on the use case.
When using this filter to enable cross origin resource sharing (CORS) - place it after uriSecurity
filter.
Properties used in the example:
Property | Value |
---|---|
enabled | required, deafult is Enables or disables the filter. |
class | required Class that implements the filter: AddHeadersFilter. |
Access-Control-Allow-Headers | optional Headers allowed for the request. |
Access-Control-Allow-Methods | optional The HTTP verbs that are allowed to make the request. See: RFC 7231, section 4: Request methods and RFC 5789, section 2: Patch method. |
Access-Control-Allow-Origin | optional The origin of the request (URL/host). The wildcard |
If you need a custom filter, please read Custom filters.