Using domains
This section explains how you can use the domain concept directly in your controllers or business logic.
Accessing the current domain
You can access the current domain or its metadata using one of the methods on the WebCmsMultiDomainService
.
From a static context, you can directly use the WebCmsDomainContextHolder
and WebCmsDomainContext
.
Use the service wherever possible, as it will ensure correct behaviour in both a multi-domain and no-domain context.
Mapping handler methods to domain
Most web cms mapping annotations allow you to specify the domain for which they apply.
If you want to create regular @RequestMapping
handler methods for specific domains, you can add the @WebCmsDomainMapping
annotation.
/**
* Declare a handler method that should only execute on the WebCmsDomain with domain key 'my-domain'.
*/
@GetMapping("/my-handler")
@WebCmsDomainMapping("my-domain")
public String domainSpecificMethod() {
...
}
Entity Query Language extensions
WebCmsModule adds some domain-related functions that can be used in EQL statements:
-
selectedDomain()
returns the current domain of the context -
visibleDomains()
returns the domain from which entities can be selected, usually this is the current domain together with non-domain bound entities -
accessibleDomains(ACTION, ACTION, …)
returns the list of domains for which the user has any of the listed actions -
action should be String representing a valid
AllowableAction
The multi-domain auto-configuration will adjust views and selections only be specifying default EQL predicates to apply, containing these functions.
Resolving the current domain
The current domain is resolved in 2 ways:
-
The
AbstractWebCmsDomainContextFilter
is used on every request to determine the initial domain. The default implementation is the WebCmsSiteConfigurationFilter that will use the hostname of the request to lookup the matching WebCmsSiteConfiguration metadata and select the domain accordingly. -
The
CookieWebCmsDomainContextResolver
is used by AdminWebModule to determine the actual domain configured in a cookie. This will overrule any previously configured domain by the filter.
You can alter the resolving mechanism by creating your own AbstractWebCmsDomainContextFilter
implementation and registering it on the WebCmsMultiDomainConfiguration
.
When the domain is changed via the GUI, the CookieWebCmsDomainContextResolver
will send out an event.
The WebCmsDomainChangedEvent
will contain the currentDomain
(the domain being switched from), and the newDomain
(the domain being switched to).
You could for example use this event to reload the Authorities
of the current user, when the authorities differ per domain.
@EventListener(WebCmsDomainChangedEvent.class)
public void reloadAuthorities( WebCmsDomainChangedEvent event ) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
WebCmsDomain domain = webCmsMultiDomainService.getDomain( event.getNewDomain() ); (1)
Collection<? extends GrantedAuthority> authorities = buildAuthoritiesForDomain( auth.getPrincipal(), domain ); (2)
Authentication newAuthentication;
if ( auth instanceof UsernamePasswordAuthenticationToken ) {
UsernamePasswordAuthenticationToken usernamePasswordAuthentication = (UsernamePasswordAuthenticationToken) auth;
newAuthentication = new UsernamePasswordAuthenticationToken( usernamePasswordAuthentication.getPrincipal(), usernamePasswordAuthentication.getCredentials(),
authorities );
SecurityContextHolder.getContext().setAuthentication( newAuthentication ); (3)
}
}
1 | Get the new domain from the event. |
2 | Create your own function to build all the authorities applicable to this domain. |
3 | Set the newly built Authentication object containing the new authorities. |
Using no-domain in a multi-domain setup
In a multi-domain setup items not attached to a specific domain are expected to be shared across all domains. In the default configuration, type specifiers are not domain-bound but shared across all domains. In the administration UI of per-domain management, you will only be able to modify types under Shared settings.
It’s possible to define an item as domain-bound however, but at the same time making the domain optional. This means the entity can be either shared across all domains, or attached to a specific domain.
The following default behaviour will be applied:
-
if an entity is not domain-bound, it will always be looked for in the set of "no-domain" entities, regardless of any domain attached to the current context
-
if an entity is domain-bound, it will be looked for in the entities attached to the domain of the current context (this could be "no-domain")
-
if an entity is domain-bound but the domain is optional, it will be looked for in the set of "no-domain" entities if no entity could be found in the set of entities attached to the domain of the current context
-
This allows you to use entities shared across all domains, but overrule them with domain-specific versions. This can be especially useful in the case of type specifiers.
The available service beans all inspect the multi domain configuration of your application to determine which logic they should apply. This will usually be very transparent for the user \(developer\).