Powerful, file-based configuration in Magnolia
The configuration of Magnolia in Light Modules via YAML is an extremely handy feature that we started shipping with Magnolia 6.1. It's been quite a few months since I first used it, but I still remember getting excited when I realized its potential, and I am eager to showcase it here.
Besides configuring dialogs and templates, you can now also change some of Magnolia's core functionality using YAML. The benefit of this low-code approach is a faster implementation of configuration changes without having to deploy a Java module.
In this blog, I will show examples of the configuration of two new Magnolia features using YAML:
Cross-Origin Resource Sharing (CORS)
Single Sign-On (SSO)
CORS configuration
One common requirement in headless projects is CORS, but did you know that you can configure CORS faster than ever using Light Development?
While not explicitly mentioned in our documentation, it is possible to configure CORS through YAML decoration in a Light Module.
These are the prerequisites that can be configured by following the documentation for REST endpoints and CORS:
A REST endpoint: For this demonstration, I will use the status endpoint.
The site-aware CORS filter: This is the default. To be sure, check /server/filters/cors.
A CORS configuration for your site, for example /modules/multisite/config/sites/<YOUR_SITE>/cors/<YOUR_SITE_CORS_NAME>
Please note that Magnolia offers two options of Magnolia DX Core - with and without our travel demo. I used Magnolia DX Core without the travel demo because the demo’s configuration of the fallback site would interfere with the example.
Since a configuration node now exists, you can use definition decoration from the scope of the Light Module to extend it.
Create the following file:
modules/<YOUR_LIGHT_MODULE>/decorations/multisite/config.yaml.
Now configure CORS as per the documentation and allow requests from localhost:8080:
sites:
fallback:
cors:
fallback:
uris:
rest:
patternString: /.rest/*
allowedOrigins:
- http://localhost:8080
allowedMethods:
- GET
allowedHeaders:
- Accept
- Content-Type
- Origin
- X-PINGOTHER
- X-Requested-With
The security settings are now applied to the endpoint, changing its response to an unauthorized origin. You can verify the result using the following command:
curl 'http://localhost:8080/.rest/status' -H "Origin: http://localhost:8081" -v -o /dev/null
You should see a 403 error code:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /.rest/status HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: http://localhost:8081
>
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0< HTTP/1.1 403
< Set-Cookie: JSESSIONID=06AC2693F1AB32108B6CF6E1EA8C6551; Path=/; HttpOnly
< Pragma: no-cache
< Cache-Control: no-cache, no-store, must-revalidate, max-age=0
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< WWW-Authenticate: FormBased
< Content-Type: text/html;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Mon, 31 May 2021 08:10:05 GMT
<
{ [1386 bytes data]
100 1379 0 1379 0 0 478 0 --:--:-- 0:00:02 --:--:-- 478
* Connection #0 to host localhost left intact
* Closing connection 0
This configuration approach has the following benefits over the standard configuration:
It is independent from the instance's configuration, and you do not have to write it to JCR using a Java module.
Updating this configuration is much easier. Just update the file for Magnolia to implement the change immediately.
It is stored in a plain text file that can easily be added to a Git repository with all its benefits.
Low-code Development
Simplify and speed up development with Magnolia using file-based configuration.
SSO configuration
The new pac4j-based Magnolia SSO module also uses YAML decoration, simplifying the complex integration with authentication services as much as possible.
A word of caution: When you install the module, we assume you'll want to use it, and the module will attempt to take control of your instance. We recommend installing the module in a development environment before rolling it out to production, but I assume that this is already an established good practice.
The initial configuration file is empty, waiting to be decorated. Once the configuration is tuned, Magnolia will implement any changes instantly.
This is the first half of the configuration file
<MODULE_NAME>/decorations/magnolia-sso/config.yaml:
authenticationService:
path: /.magnolia/admincentral
callbackUrl: http://localhost:8080/.auth
groupMappings:
/magnolia-sre:
roles:
- superuser
This configuration:
Delegates authentication for your instance's AdminCentral to a third-party identity provider
Asks the identity provider to redirect to callbackUrl when a user has been logged in
Applies groupMappings to the user's groups property to grant access to AdminCentral
Integration with pac4j's file-based configuration
I'm very eager to share a great improvement in the latest version of the module: it integrates with pac4j's YAML configuration. This means that the module is compatible with any OpenID Connect identity provider.
We’ve validated the use case with Keycloak and Okta. This is the configuration we've used to describe the client's OpenId Connect properties for pac4j to assess incoming requests from the identity provider.
authenticationService:
pac4j:
oidc.id: magnolia-sso
oidc.secret: 2ff75b44-c7ef-4932-91c8-59e6ea5f35b6
oidc.scope: openid profile email
oidc.discoveryUri: https://<YOUR_OIDC_IDP_DOMAIN>/…/.well-known/openid-configuration
oidc.preferredJwsAlgorithm: RS256
This is what the entire configuration file looks like:
authenticationService:
path: /.magnolia/admincentral
callbackUrl: http://localhost:8080/.auth
groupMappings:
/magnolia-sre:
roles:
- superuser
pac4j:
oidc.id: magnolia-sso
oidc.secret: 2ff75b44-c7ef-4932-91c8-59e6ea5f35b6
oidc.scope: openid profile email
oidc.discoveryUri: https://<YOUR_OIDC_IDP_DOMAIN>/…/.well-known/openid-configuration
oidc.preferredJwsAlgorithm: RS256
Conclusion
I hope this article was helpful in explaining definition decoration. It’s an auxiliary mechanism that is explained in later sections of our documentation and often considered in later stages of a project. There’s a bit of overhead for the setup, but I hope I have convinced you that the benefits are well worth the effort.
If you need help getting this implemented, you can send me an email.