Skip to main content

Authenticating with Active Directory

Introduction

Traditionally publishing server has had its own "local" user store: comet_admin database in priint suite 3.x and Jackrabbit repository in priint suite 4.0.

With the final release of 4.1 users can additionally log-in via Active Directory.

Active Directory is an LDAP based resource directory service of Microsoft. It is the heart of any Windows domain. If a user log-in into a Windows domain he actually logs-in via the Active Directory.

So, with the final release of 4.1 users can log-in using their Windows user names. Alternatively they can use their mail address as stored in Active Directory.

Authentication and authorization in publishing server is implemented using the well known Shiro library. See https://shiro.apache.org. Shiro has a pluggable design. You can add "realms" to authenticate by database, by LDAP etc. Active Directory is added by configuring the ADRealm class.This class is part of the PubServerKernel modules. As this it is part of the standard installation.

If you are looking for Azure Active Directory - this is NOT the same. Azure Active Directory is a cloud service by Microsoft that also provides authentication and authorization possibilities (and much more). Azure Active Directory is e.g. the basis of  Office 365 authentication. Azure Active Directoryis also supported for publishing server but it is currently not part of the standard installation. Use the CloudAuthRealms module if you need Azure Active Directory (AADRealm) in your project.

Installation and Update

Nothing has to be done. ADRealm for classical Active Directory is already part of publishing server, since final release of 4.1.

Default Configuration - shiro.ini

Configuration is done by special ini file localted in the domain config folder. <installDir>\glassfish\glassfish3\glassfish\domains\pubserver\config\shiro.ini

This file is not part of a standard installation of pubserver. In the standard installation an internal version of shiro.ini is used.

This file is read every time when the PubServerKernel is deployed, i.e. during a server start. This means that shiro.ini is not monitored by the system. Changes in the file will only be applied during a restart.

Default shiro.ini

This is the content of the default shiro.ini to start with. Just copy the contents into the /config/>/shiro.ini.

[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager.sessionDAO = $sessionDAO
securityManager.sessionManager = $sessionManager
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager
credentialsMatcher = org.apache.shiro.authc.credential.Md5CredentialsMatcher
pubCredentialsMatcher = com.priint.pubserver.auth.realm.PubServerCredentialsMatcher
pubServerAuthenticationToken = com.priint.pubserver.auth.realm.PubServerAuthenticationToken
authcListener1 = com.priint.pubserver.auth.PubServerAuthenticationListener
securityManager.authenticator.authenticationListeners = $authcListener1
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = PubServSessID
cookie.path = /
securityManager.sessionManager.sessionIdCookie = $cookie
securityManager.sessionManager.globalSessionTimeout = 36000000
sessionListener = com.priint.pubserver.auth.PubServerSessionListener
securityManager.sessionManager.sessionListeners = $sessionListener
sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
sessionValidationScheduler.interval = 3600000
sessionValidationScheduler.sessionManager = $sessionManager
securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler

# DEFAULT REALM
pubServerRealm = com.priint.pubserver.auth.realm.PubServerRealm
pubServerRealm.credentialsMatcher = $pubCredentialsMatcher

# CUSTOM REALMS
# add your custom realms over here
# ...

# attach the realms to shiro
securityManager.realms = $pubServerRealm

Do not change any content before the "# CUSTOM REALMS". To add a new realm just put the relevant realm configuration settings below the "# CUSTOM REALMS" and finally add the new realm to the list of securityManager.realms. That is all.

Active Directory Configuration

After you have created the default shiro configuration you are ready for adding further realms.

For Active Directory you will have to

  • Configure the AADRealm in shiro.ini
  • Add a special service user into you Active Directory, that is entitled to read Active Directory for user properties and group memberships. This is optional. It is needed if users are allowed to login via their mail address, instead of windows user name and domain.
  • Add SSL certificates for the AD server to Glassfish truststore This is only needed if you use LDAPS (LDAP via SSL) protocol.
  • Test your configuration.

Shiro.ini

Configuration by Example

This has to be placed in the shiro.ini file as custom realm.

\# CUSTOM REALMS
adRealm = com.priint.pubserver.auth.realm.ad.ADRealm
adRealm.searchBase = OU=Users,OU=MyBusiness,DC=example,DC=com
adRealm.url = ldap://dc.example.com
adRealm.systemUsername = ad-reader@example.com
adRealm.systemPassword = topsecret
adRealm.config.name = example.com
adRealm.config.includePattern = ^.+@example\\.com$
adRealm.config.userSearchFilter = (|(mail={0})(sAMAccountName={1}))
adRealm.config.defaultRole = Normal User
adRealm.config.defaultMenu = publications
adRealm.config.defaultDataset = DefaultProject
adRealm.config.memberSearchFilter = (member:1.2.840.113556.1.4.1941:={0})
adRealm.config.membershipMapping = print\_
# === ASSIGN THE REALMS ===
securityManager.realms = $adRealm, $pubServerRealm

Please replace all marked values by appropriate values for you domain.

IMPORTANT: Add the aadRealm to the list of realms. Otherwise system update and login of "admin" user will not work anymore and the system will not be usable.

IMPORTANT: Assure that pubServerRealm is the last element in the list.

Configuration Properties

Property Description
searchBaseRequiredBasis for LDAP queries to identify users and groups. Ask the domin admin for the correct value. (Defined in Shiros AbstractLdapRealm class.)
urlRequiredLDAP url. Ask the domin admin for the correct value. (Defined in Shiros AbstractLdapRealm class.)
principalSuffixOptionalThe domain name including a prefixed "@". E.g. "@example.local". This is only needed if you do not use systemUsername and systemPassword. In this case the user login is restricted to the userPrincialName, like "john@example.local" (Defined in Shiros AbstractLdapRealm class.)
systemUsernameOptionalWindows login name of a service user to read the directory. Ask the domin admin to create such a user. This is not required if login is based on windows usernames only. (Defined in Shiros AbstractLdapRealm class.)
systemPasswordOptionalPassword of the system user specified by systemUsername. (Defined in Shiros AbstractLdapRealm class.) Starting from priint:suite 4.1.8.352 you can use a Payara Password Alias (Jakarta Microprofile Config) instead adding the password in clear text. Create an alias <code>adSysUserPassword </code> (or similar) with asadmin or the Payara web console. In shiro.ini type then <code>adRealm.systemPassword = {ALIAS=adSysUserPassword}</code>.
nameRequiredYour configuration MUST have a config.name attribute. This is used to identify the realm. It also helps to see by which realm a user is created or updated in pubserver.
includePatternOptionalRegular expression pattern. If a login name does NOT match this pattern the authentication attempt on the current realm is aborted immediately.
excludePatternOptionalRegular expression pattern. If a login name does match this pattern the authentication attempt on the current realm is aborted immediately.
userSearchFilterRequiredLDAP search filter to read the properties of a user. The default "(|(mail=0)(sAMAccountName=1))" is a good value here. User search filter has two potenials inputs 0 and 1, where 0 is the full loginName (mail) and 1 is the extracted user name from full loginName, i.e. the sAMAccountName. Read Microsoft's LDAP help pages for more information.
defaultMenuOptionalIf a new user is created on first login this is the default menu entry she will see in publishing planner. This can be reassigned in planner UI later.
defaultDatasetOptionalIf a new user is created on first login this is the default dataset (i.e.CometProject) that the user will be assigned to. The user can only login into publishing planner if a dataset is assigned. The dataset name should be the identifier of your comet project, as can be seen in ison.
defaultRoleOptionalIf a new user is created on first login this is the default role in pubserver it is assigned to. Further roles can be assigned by publishing planner UI. This can be overruled by setting memberSearchFilter and membershipMappings.
memberSearchFilterOptionalLDAP search filter to read the groups of a user from the directory. Typical variants are:Variant 1:(member:1.2.840.113556.1.4.1941:=0) This reads all group memberships including nested groups. Variant 2:(member:=0) This reads all direct group memberships. For other options read Microsofts documentation:  https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx Note:The variable 0 is always set to the DN of the user (distinguished name).
membershipMappingOptionalComma separated string with directoryGroup:pubserverRole pairs defining a mapping between Active Directory groups and publishing server roles. Alternativly a simple group name prefix can be defined. This is only used if membershipFunction is also set. This overrules the defaultRole setting.
defaultTeamOptionalSet a default workflow team for the user
membershipTeamMappingOptionalComma separated string with directoryGroup:pubserverTeam pairs defining a mapping between Active Directory groups and publishing server workflow teams. (Syntax:[AD-Group1]:[Team1]:[Team2],[AD-Group2]:[Team3] This overrules the defaultTeam setting.

#Login by Windows User Name

Users can log in with their windows user name. They have to provide the full user name in form of a special email address. This is called "userPrincialName" by Microsoft, like "JohnDoe@mydomain.local". Although this has the form of an email it is - in most cases - different from the regular email address. It is the windows user name plus the principalSuffix.

This is the simplest setup. You do not need an extra user in Active Directory to read user names from the directory.

Requires "principalSuffix" to be set. "systemUsername" and "systemPassword" can be omitted.

# adRealm.systemUsername  = 
# adRealm.systemPassword =
adRealm.principalSuffix = @example.local

Login by Mail Adress

Users can log-in with their email address. This is the recommended setup. Users have to provide their email address as stored in the directory.

If a user has more than one mail address, this will also work as long as there is only one user associated with the mail address.

The "userPrincialName" (windows name + "@" login domain name) can also be used.

You need to setup an extra service user in Active Directory with the permissions to read the directories for users and user memberschips. You configure this user via "systemUsername" and "systemPassword".

You can omit setting of "principalSuffix".

adRealm.systemUsername  = ad-reader
adRealm.systemPassword = ********
# adRealm.principalSuffix =

Mapping memberships

Option 1: Memberships are controlled by publishing planner

Do not set memberSearchFilter and membershipMapping (comment out in shiro.ini by prefixing with #). Set defaultRole instead: typical value "Normal user".

Option 2: Memberships are controlled by Active Directory

Do not set defaultRole (comment out in shiro.ini by prefixing with #). Set memberSearchFilter and membershipMapping instead. Membership mapping can be done in two ways. See the examples below:

membershipMappingDescription
priint-usr:Normal User,designer:Whiteboard(type: full list of mappings) If a user is in Active Directory Group "print-usr" it will be assigned into pubplanner role "Normal User.  If a user is in Active Directory Group "designer" it will be assigned into pubplanner role "Whiteboard". Use the role's Identifier, not Display Name.
print_(type: prefix for Active Directory Group names) If a user is in Active Directory Group "print_Normal User" it will be assigned into pubplanner role "Normal User.  If a user is in Active Directory Group "print_Whiteboard" it will be assigned into pubplanner role "Whiteboard".

Notes:

a) membershipMapping uses the CN (common name) of an AD group for mapping. Example: For a group with distinguishedName "CN=InDesigner,OU=Print Groups,OU=Groups,DC=CPC,DC=Kontoso,DC=de" only the "InDesigner" will be used for the mapping.

b) AD Groups must be reachable from the search base: Example: If you have a user like "CN=Doe\, Joanne, OU=Externals,DC=CPC,DC=Kontoso,DC=de" and you expect to find a group membership for "CN=InDesigner,OU=Print Groups,OU=Groups,DC=CPC,DC=Kontoso,DC=de", then your search base should just be "DC=CPC,DC=Kontoso,DC=de".

SSL Certificates

You may use secure connection to ActiveDirectory (LDAPS). In this cases the certificate of the ldap server must be added to the Glassfish trust store.

Retrieve the certificate from a trusted source. Ask your domain admin. The file should be in "crt" format.

Import the crt-file into the trust store by executing a windows batch file like this: Please adapt the values marked to your needs. "changeit" is the default value for the truststore passphrase in Java and Glassfish.

SET DevstackPath=C:\\devstack
SET JAVA\_HOME=%DevstackPath%\\java\\jdk
SET GlassfishDomainPath=%DevstackPath%\\glassfish\\glassfish3\\%GlassfishPath%\\glassfish\\domains\\pubserver
SET GlassfishTruststorePath=%GlassfishDomainPath%\\config\\cacerts.p12
SET GlassfishTruststorePassword=changeit
SET CERT\_FILE=%CD%\\example.local.crt
SET CERT\_ALIAS=example.local
"%JAVA\_HOME%\\bin\\keytool" -import -trustcacerts -keystore "%GlassfishTruststorePath%" -storepass "%GlassfishTruststorePassword%" -noprompt -alias "%CERT\_ALIAS%" -file "%CERT\_FILE%"

Note: It is always good to make a backup of cacerts.p12 before changing it.

Active Directory Service User

This is a task of the domain admin. Add a service user for priint suite, that is only to be used as reader of the active directory. It will search user by mail addresses or other properties and read memberships for these user. Username and password are admin's free choice. As user name we recommend something like "priint_adreader"