uPortal is capable of retrieving user attributes from an LDAP source. To configure this behavior, you'll need to do the following.
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.
# 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= |
<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 () [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. |
<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> |
Open uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml
Edit the mergedPersonAttributeDao bean definition to add uPortalLdapAttributeSource under personAttributeDaos:
<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.
<!-- 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> |
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:
<!-- 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> |
From the root of your uPortal source:
ant clean deploy-war |
Restart your tomcat server after deploying your modifications
Additional References uPortal mailing list Q&A related topic |
Please send us feedback at uportal-user@lists.ja-sig.org |