LDAP User Attribute Sources
uPortal is capable of retrieving user attributes from an LDAP source. To configure this behavior, you'll need to do the following.
Step 1: Configure Ldap Settings
Option #1: Add ldap details in your properties file (version uPortal 4.0.9+)
Since uPortal 4.0.9, users can specify their ldap details in the properties file below (filters/local.properties). This feature comes in handy if you have multiple environments (development, test, production, etc..). You can create a properties file for each environment (i.e, dev.properties) and build uPortal with the specified properties file (ant clean deploy-war -Denv=dev). Without the -Denv parameter the local.properties file will be used by default.
- Open your properties file (i.e., filters/local.properties)
- Add your ldap server information below
# LDAP server connection settings (optional) # To connect to LDAP, provide your connection information here and uncomment one # or both integration beans in uportal-war/src/main/resources/properties/contexts/ldapContext.xml environment.build.ldap.url= environment.build.ldap.baseDn= environment.build.ldap.userName= environment.build.ldap.password=
Option #2: Edit the ldapContext.xml file
- Open uportal-war/src/main/resources/properties/contexts/ldapContext.xml
- Add your ldap server information in the defaultLdapContext_target bean (see below)
- NOTE: Based on feedback, some users have found that the baseDN property was required to setup their configuration.
<bean id="defaultLdapContext_target" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="url" value="${ldap.url}"/> <property name="base" value="${ldap.baseDn}"/> <property name="userDn" value="${ldap.userName}"/> <property name="password" value="${ldap.password}"/> <property name="pooled" value="true"/> </bean>
uPortal 4.0.3: If you are receiving the following error ( - UP-3348Getting issue details... STATUS )
[org.springframework.ldap.core.support.LdapContextSource]: Bean property 'userName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Replace the property name, userName, in the defaultLdapContext bean above with userDn.
- If you are configuring your LDAP context to connect to Active Directory, you may need to add the following properties to the bean definition:
<property name="baseEnvironmentProperties"> <map> <entry> <key> <value>java.naming.security.authentication</value> </key> <value>simple</value> </entry> <entry key="java.naming.referral"> <value>follow</value> </entry> </map> </property>
Step 2: Add an LDAP Attribute source
Open uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml
Edit the mergedPersonAttributeDao bean definition to add uPortalLdapAttributeSource under personAttributeDaos:
uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml<bean id="mergedPersonAttributeDao" class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl"> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> <property name="cacheNullResults" value="true" /> <property name="userInfoCache"> <bean class="org.jasig.portal.utils.cache.MapCacheFactoryBean"> <property name="cacheFactory" ref="cacheFactory" /> <property name="cacheName" value="org.jasig.services.persondir.USER_INFO.merged" /> </bean> </property> <property name="cacheKeyGenerator" ref="userAttributeCacheKeyGenerator" /> <property name="cachedPersonAttributesDao" > <bean class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl"> <property name="merger"> <!-- This is a "first one wins" strategy. I.e. the first value found for any given result attribute will be assigned to the user. Different values found in subsequently queried attribute sources will be ignored. Suitable if uP-local attributes should always take precedence. Other options (all in the same package): MultivaluedAttributeMerger - Collects values from all DAOs into lists (does not filter out duplicate values, though) ReplacingAttributeAdder - "Last one wins" strategy. I.e. the opposite of NoncollidingAttributeAdder. --> <bean class="org.jasig.services.persondir.support.merger.NoncollidingAttributeAdder" /> </property> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> <property name="personAttributeDaos"> <list> <!-- Provides a single attribute (but only for the current logged in user): impersonating='true'|'false' --> <bean class="org.jasig.portal.persondir.ImpersonationStatusPersonAttributeDao" /> <bean class="org.jasig.services.persondir.support.CascadingPersonAttributeDao"> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> <property name="personAttributeDaos"> <list> <ref bean="uPortalAccountUserSource" /> <ref bean="uPortalJdbcUserSource" /> </list> </property> </bean> <!-- ADDITIONAL ATTRIBUTE SOURCES GET ADDED HERE Don't add more sources to the CascadingPersonAttributeDao.personAttributeDaos list above unless you're adding "special" DAOs tasked with augmenting/transforming the attributes generated by uP-local DAOs. (CascadingPersonAttributeDao takes the results from the first-DAO, transforms them into a query, and passes that query to each subsequent DAO. I.e. subsequent DAOs in the cascade list will *not* be given a chance to process the original query. But they will if you add them directly to the MergingPersonAttributeDaoImpl.personAttributeDaos list here.) --> <!-- Add your LDAP Attribute source here. <ref bean="uPortalLdapAttributeSource"/> --> </list> </property> </bean> </property> </bean>
Next, add the LDAP attribute source bean definition to the same file. This is where you put your baseDN.
uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml<!-- Where non-local attribute DAOs go --> <!-- Enter the mapping between 'internal' names (keys) and set of one or more LDAP attribute names (values). --> <bean id="uPortalLdapAttributeSource" class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao"> <property name="contextSource" ref="defaultLdapContext" /> <!-- Enter all keys that you want users to search with in the Directory Search portlet or portal search capability. This should contain values from list directoryQueryAttributes in properties/contexts/userContext.xml. Key is internal name, value is ldap attribute name. --> <property name="queryAttributeMapping"> <map> <entry key="username" value="uid" /><!-- should match the uid attribute in your directory; e.g. sAMAccountName for Active Directory. --> <entry key="cn" value="cn" /> <entry key="givenName" value="givenName"/> <entry key="sn" value="sn" /> <entry key="mail" value="mail" /> </map> </property> <property name="queryType" value="OR"/> <!-- key is ldap attribute name, values are internal names. --> <property name="resultAttributeMapping"> <map> <entry key="eduPersonPrimaryAffiliation"> <value>uPortalTemplateUserName</value> </entry> <entry key="eduPersonAffiliation"> <value>eduPersonAffiliation</value> </entry> <entry key="eduPersonNickname"> <set> <value>eduPersonNickname</value> <value>user.name.nickName</value> </set> </entry> <entry key="eduPersonOrgDN"> <set> <value>eduPersonOrgDN</value> <value>user.employer</value> </set> </entry> <entry key="eduPersonOrgUnitDN"> <set> <value>eduPersonOrgUnitDN</value> <value>user.department</value> </set> </entry> <entry key="eduPersonPrimaryAffiliation"> <value>eduPersonPrimaryAffiliation</value> </entry> <entry key="eduPersonPrincipalName"> <value>eduPersonPrincipalName</value> </entry> <entry key="c"> <value>c</value> </entry> <entry key="cn"> <value>cn</value> </entry> <entry key="description"> <value>description</value> </entry> <entry key="displayName"> <value>displayName</value> </entry> <entry key="facsimileTelephoneNumber"> <value>facsimileTelephoneNumber</value> </entry> <entry key="givenName"> <set> <value>givenName</value> <value>user.name.given</value> </set> </entry> <entry key="homePhone"> <value>homePhone</value> </entry> <entry key="homePostalAddress"> <value>homePostalAddress</value> </entry> <entry key="initials"> <value>initials</value> </entry> <entry key="jpegPhoto"> <value>jpegPhoto</value> </entry> <entry key="l"> <value>l</value> </entry> <entry key="labeledURI"> <value>labeledURI</value> </entry> <entry key="mail"> <set> <value>mail</value> <value>user.home-info.online.email</value> </set> </entry> <entry key="mobile"> <value>mobile</value> </entry> <entry key="o"> <value>o</value> </entry> <entry key="ou"> <value>ou</value> </entry> <entry key="pager"> <value>pager</value> </entry> <entry key="postalAddress"> <value>postalAddress</value> </entry> <entry key="postalCode"> <value>postalCode</value> </entry> <entry key="postOfficeBox"> <value>postOfficeBox</value> </entry> <entry key="preferredLanguage"> <value>preferredLanguage</value> </entry> <entry key="seeAlso"> <value>seeAlso</value> </entry> <entry key="sn"> <set> <value>sn</value> <value>user.name.family</value> </set> </entry> <entry key="st"> <value>st</value> </entry> <entry key="street"> <value>street</value> </entry> <entry key="telephoneNumber"> <value>telephoneNumber</value> </entry> <entry key="uid"> <set> <value>uid</value> <value>username</value> <!-- UP-4185 populate username in case user hasn't logged in yet --> <value>user.login.id</value> <!-- UP-4177 LDAP needs to fill in user.login.id --> </set> </entry> <entry key="userCertificate"> <value>userCertificate</value> </entry> <entry key="userSMIMECertificate"> <value>userSMIMECertificate</value> </entry> </map> </property> </bean>
- You may need to update the available attributes and query to match your server. Connections to Active Directory servers will most likely use a query of "(sAMAccountName={0})" which is handled by entry username of queryAttributeMapping mapping to sAMAccountName.
Note: The above querryAttributeMapping map keys need corresponding changes to uportal-war/src/main/resources/properties/contexts/userContext.xml for the Directory Search Portlet to find the values in the LDAP source. See example below:
uportal-war/src/main/resources/properties/contexts/userContext.xml<!-- The following attribute names are used in searching for users through person-directory, such as from within the Directory framework portlet. These should correspond to the internal names (keys, not the ldap attribute names) of the queryAttributeMapping property of bean uPortalLdapAttributeSource in personDirectoryContext.xml. --> <util:list id="directoryQueryAttributes"> <value>givenName</value> <value>sn</value> <value>cn</value> <value>mail</value> <value>username</value> </util:list>
Step 3: Rebuild/Redeploy uPortal
From the root of your uPortal source:
ant clean deploy-war
Step 4: Restart uPortal
Restart your tomcat server after deploying your modifications