Magnolia 5.7 reached extended end of life on May 31, 2022. Support for this branch is limited, see End-of-life policy. Please note that to cover the extra maintenance effort, this EEoL period is a paid extension in the life of the branch. Customers who opt for the extended maintenance will need a new license key to run future versions of Magnolia 5.7. If you have any questions or to subscribe to the extended maintenance, please get in touch with your local contact at Magnolia.
Magnolia LDAP Connector is a JAAS login module that connects to any LDAP v3 directory service. The LDAP Connector is used in intranet environments where an enterprise user management infrastructure already exists. With JAAS you can meet single sign-on requirements or connect to legacy LDAP servers.
Installing
<version/>
in the dependency.<dependency> <groupId>info.magnolia</groupId> <artifactId>magnolia-ldap</artifactId> </dependency>
Module configuration
Since module version 1.9, the configuration of the following is done directly in the user manager:
allowPartialResults
ignoreGroupsWithIllegalName
pageSize
envPropertiesPredicate
LDAP configuration
An LDAP configuration file tells Magnolia where to find your LDAP directory server. The file also says whether Magnolia should resolve users, groups or both from the directory.
The LDAP Connector module bundle provides two sample files in the configuration-samples
folder:
ldap.properties
defines an LDAP server.ad.properties
defines an Active Directory server.
Properties (LDAP and/or Active Directory)
Properties used in the
ldap.properties
and/or
ad.properties
file(s):
File(s) | Property | Description |
---|---|---|
both |
| required URL of the LDAP/AD service provider. Example: |
both |
| required, default is the LDAP provider's default User or program doing the authentication. Use an appropriate DN/CN for your server. Example: Originally interchangeable with the now deprecated |
both |
| required Password or encrypted data such as a digital certificate that the implementation uses to authenticate the client. Originally interchangeable with the now deprecated |
both |
| optional, default is Authentication mechanism (password encryption) used. Possible values are |
both |
| optional, default is Indicates to the service provider how to handle referrals. Valid values are If the LDAP/AD service provider receives a referral despite you having set the property to To deal with the |
both |
| optional (but recommended) The class name of the of the initial context. The class must implement the The default value for java.naming.factory.initial will depend on your container or Java configuration. For example, the default configuration for Apache Tomcat specifies the class |
both | initialSearchAttributes | required Defines the initial connect point to the directory service. Example: |
both |
| required Name mapping(s) taking the form
See also: Accessing properties from LDAP |
both | userSearchFilter | optional When searching a user from a wide initialSearchAttribute, a custom filter might come in handy. Be aware that attribute used for resolving Example: It's also possible to reuse the mapped
|
both | allUsersSearchFilter | optional Custom filter can be used also when searching all users from a wide initialSearchAttribute. Example: ADUserManager default users search filter is: |
both |
| required (if A class responsible for resolving roles assigned to a user. The class must implement the Implementations:
|
ad. | ssoSlave | optional , default is Set |
ad. | userMembershipAttribute | required (only if The name of the user attrribute which specifies the groups the user is a member of. Example: |
ldap. | groupSearchFilter | required (if A filter used to find groups the user is a member of. Example: |
ldap. | groupMembershipAttributeValue | required (if The value of the Example: |
both | groupIdAttribute | required (only if either The name of the group ID attribute in LDAP/AD. Example: |
both | groupSearchContext | optional (only if either A subtree for groups in the LDAP/AD structure if groups are managed in different subtree than the users. If missing then the Example: |
both | groupsSearchFilter | optional (only if either
A filter for searching groups in LDAP/AD. |
both | groupMembershipAttribute | required (only if either The name of the group attrribute which specifies the members belonging to the group. Example: |
Deprecated properties:
adminUserDN
adminUserPassword
Instead use
java.naming.security.principal
and
java.naming.security.credentials
properties respectively.
magnolia.properties
Put theldap.properties
or ad.properties
file inside your Magnolia webapp, for example in /<CATALINA_HOME>/webapps/<contextPath>/WEB-INF/config
. Reference the file location from a magnolia.properties file using the jndi.ldap.config
property. Set the value to an absolute or relative path inside the webapp. You can also use the ${magnolia.home}
variable.
jndi.ldap.config=WEB-INF/config/ldap.properties
Configuring multiple directory servers
To configure multiple LDAP and AD directories, use the pattern jndi.ldap.config.<realmName>
where realmName
corresponds to a realm name in the user manager.
Example: Configuring multiple directory servers in magnolia.properties
.
jndi.ldap.config.ad=WEB-INF/config/ad.properties jndi.ldap.config.ldap=WEB-INF/config/ldap.properties jndi.ldap.config=WEB-INF/config/default-ldap.properties
Explanation:
- A user manager with realm name
ad
will use an Active Directory property file defined under thejndi.ldap.config.ad
key. - A user manager with realm name
ldap
will use an LDAP property file defined under thejndi.ldap.config.ldap
key. - A user manager with realm name
external
will use the default LDAP property file defined under thejndi.ldap.config
key since no specific property file is configured for this realm.
Corresponding user manager configuration:
Node name | Value |
---|---|
server | |
security | |
userManagers | |
system | |
ad | |
class | info.magnolia.jaas.sp.ldap.ADUserManager |
realmName | ad |
ldap | |
class | info.magnolia.jaas.sp.ldap.LDAPUserManager |
realmName | ldap |
external | |
class | info.magnolia.jaas.sp.ldap.LDAPUserManager |
realmName | external |
A custom configuration resolver
( LDAP module 1.9+) You can write your own configuration resolver in JAVA. Add the following component to your module descriptor,
<components> <id>main</id> <component> <type>info.magnolia.jaas.sp.ldap.config.ConfigResolver</type> <implementation>your-own-resolver-class</implementation> </component> </components>
change the implementation class accordingly, and make sure that your module depends on (i.e. is loaded after) Magnolia's LDAP module.
JAAS login configuration
Magnolia uses the Java Authentication and Authorization Service (JAAS) to authenticate users. When you store users in a directory outside of Magnolia configure the directory as a LoginModule. You can list several LoginModules. Authentication proceeds down the module list in the order you specify with flags, see javax.security.auth.login.Configuration. Depending on the servlet container you use the configuration for JAAS is slightly different.
jaas.config for Tomcat
For the Tomcat application server, create a jaas.config
file and list the LoginModules in the following format:
magnolia { <LoginModule> <flag> <options>; <LoginModule> <flag> <options>; <LoginModule> <flag> <options>; };
Properties:
| required A class that implements the desired authentication technology. Implementations:
Set also the |
| required The flag indicates whether success of the preceding LoginModule is |
options | optional Options is a space-separated list of LoginModule-specific values which are passed directly to the LoginModule. The options are defined by the LoginModule itself, and control its behavior. Options for
|
Example 1: Authenticate against Magnolia on Tomcat
magnolia { info.magnolia.jaas.sp.jcr.JCRAuthenticationModule requisite; info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required; };
Example 2: Authenticate against LDAP on Tomcat
magnolia { info.magnolia.jaas.sp.jcr.JCRAuthenticationModule optional; info.magnolia.jaas.sp.ldap.LDAPAuthenticationModule requisite skip_on_previous_success=true; info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required; };
Notes about example 2:
JCRAuthenticationModule
authenticates users who are stored only in Magnolia such assuperuser
andanonymous
.optional
means the module is not required to succeed. Authentication proceeds to the next module whether the user is found or not.LDAPAuthenticationModule
authenticates users who are stored in LDAP.requisite
means that if the login module succeeds, authentication continues down the list. If the module fails, authentication does not proceed down the list. This module is skipped if the previous module was successful. This module could also beinfo.magnolia.jaas.sp.ldap.ADAuthenticationModule
.JCRAuthorizationModule
isrequired
to succeed.
User manager
You also need to configure an external UserManager
. Make sure it is placed before the
admin
but after the system
user managers. Any other order may result in 401 errors (authentication failed) during publishing and unpublishing of content.
Node name | Value |
---|---|
server | |
security | |
userManagers | |
system | |
external | |
class | info.magnolia.jaas.sp.ldap.LDAPUserManager |
realmName | external |
admin | |
public |
Properties:
allowCrossRealmDuplicateNames | optional , default is Allows duplicate usernames in different realms. Only applicable to |
| required A class that implements the Implementations:
|
disableCache | optional , default is Allows to disable caching if set to |
realmName | required Realm name corresponding to JAAS login configuration. |
| optional, default is Indicates what methods are used to deal with the
|
| optional A subnode which allows to specify a custom |
| The class that implements the The default class used is Two additional implementations are available:
|
| optional A subnode which specifies the If not defined explicitly then the predicate accepts anything within the following namespaces:
|
| The class that implements the The default class is |
| optional A subnode which defines the decoding method of the admin password used by the
|
| The decoder is available in three implementations:
|
pageSize | optional, default is Specifies the number of objects to be returned in a single search result. |
User managers and caching
By default the ad
and ldap
user managers use a basic cache (Cache modules) to avoid repeated calls to LDAP/AD. If Ehcache is used then the default configuration is automatically bootstraped into /modules/cache/config/cacheFactory/caches/ldap-user-manager-cache
. Caching may disabled by adding the disableCache
property to the manager's node and setting it to true
, for example
Node name | Value |
---|---|
ad | |
class | info.magnolia.jaas.sp.ldap.ADUserManager |
disableCache | true |
realmName | ad |
Accessing properties from LDAP
If you need to access more user properties than name, full name and language, extend info.magnolia.jaas.sp.ldap.LDAPAuthenticationModule#setEntity
to push the desired properties into the Entity
object, and the info.magnolia.cms.security.ExternalUserManager
/info.magnolia.cms.security.ExternalUser
pair to expose it.
Same-name users in different realms
If you are resolving roles or groups, add the allowCrossRealmDuplicateNames
property under /server/security/userManagers/admin
and set its value to true
. This property allows you to create users with the same name in different realms when replicating LDAP/AD users in the repository. By default, Magnolia does not allow the same user name to be repeated.
Node name | Value |
---|---|
security | |
userManagers | |
system | |
external | |
admin | |
allowCrossRealmDuplicatNames | true |
class | info.magnolia.cms.security.MgnlUserManager |
lockTimePeriod | 0 |
maxFailedLoginAttempts | 5 |
realmName | admin |
public |
See also: Configuring multiple directory servers
Groups and roles
LDAP typically mirrors the organization structure. If your company has a Marketing department then create a marketing
group in the LDAP directory and assign employees to the group. Magnolia also organizes users into groups.
Magnolia also has roles. A role grants a user permission to do something. For example, the editor
role grants the user a permission to edit content. Permissions are configured using access control lists. A role can be assigned directly to an user or to a group.
When you authenticate users against an LDAP directory a resolver class finds the groups and roles the user belongs to. This process is called resolving. Since role is the element that grants the user a permission to do something, you must resolve at least roles. You can optionally also resolve groups.
Group resolving
A groupResolverClass
configured in ldap.properties finds groups in the LDAP directory and matches them to groups in Magnolia. The group names must match exactly.
Choose a resolver depending on where the groups are stored:
info.magnolia.jaas.sp.ldap.resolver.MagnoliaGroupResolver
resolves groups from Magnolia.info.magnolia.jaas.sp.ldap.resolver.OpenLDAPGroupResolver
resolves groups from any LDAP directory.info.magnolia.jaas.sp.ldap.resolver.ADGroupResolver
resolves groups from Active Directory.
Role resolving
A roleResolverClass
configured in ldap.properties finds roles. Roles must always be stored in Magnolia, they cannot be stored in the LDAP directory. The reason is that the ACLs that grant permissions are attached to roles.
Magnolia provides one role resolver:
-
info.magnolia.jaas.sp.ldap.resolver.MagnoliaRoleResolver
resolves roles from theuserroles
workspace in Magnolia.
Implementing your own resolver
Magnolia does not provide ready-made resolver classes for every possible LDAP product but you can write your own class. Implement the info.magnolia.jaas.sp.ldap.resolver.NameResolver
interface and the methods to fetch group names from the directory.
Testing and validating LDAP Configuration
The magnolia-ldap-tester
artifact is a self-contained executable jar which can be executed with:
java -jar magnolia-ldap-tester-<version>.jar <LoginModule class name> <config.properties> <username> <password>
<LoginModule class name>
should be either info.magnolia.jaas.sp.ldap.LDAPAuthenticationModule
or info.magnolia.jaas.sp.ldap.ADAuthenticationModule
, depending on which one you're using in jaas.config
(or login-config.xml
with JBoss).
The tool simulates a user login with the given credentials and configuration, outputs the main results, and logs everything else in magnolia-ldap-tester.log
.
A successful login attempt looks like this in the log:
INFO i.m.jaas.sp.ldap.ConnectionFactory - Trying to log in as cn=jsmith,dc=example,dc=com with a password. DEBUG i.m.jaas.sp.ldap.ConnectionFactory - Login succeeded. DEBUG i.m.j.s.l.Tester$MockSecuritySupport - Getting user jsmith from realm admin INFO info.magnolia.ldap.tool.LDAPTester - Login result: true INFO info.magnolia.ldap.tool.LDAPTester - Commit result: true DEBUG info.magnolia.ldap.tool.LDAPTester - Subject: DEBUG info.magnolia.ldap.tool.LDAPTester - User: null INFO info.magnolia.ldap.tool.LDAPTester - Properties: {title=jsmith, email=john.smith@example.com, name=jsmith, fullName=jsmith, password=secret} DEBUG info.magnolia.ldap.tool.LDAPTester - State: {groupNames=[], statusValue=1, roleNames=[]} INFO info.magnolia.ldap.tool.LDAPTester - Group names: (none) INFO info.magnolia.ldap.tool.LDAPTester - Role names: (none) DEBUG info.magnolia.ldap.tool.LDAPTester - AttributesMap
Do not expect to see any groups or roles assigned. The tester tool does not connect to Magnolia in any way. It connects to the LDAP. It is normal for group assignments handled in Magnolia not to show up.