Default Person Directory configuration

In uPortal 4.0, by default user attribute collection is configured in a properties files named uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml in the language of Spring beans.

Versions of PersonDirectory

PersonDirectory was refactored for uPortal 2.5 to be backed by Spring to wire together its implementation. However, documentation exists for PersonDirectory in uPortal 2.4 and earlier.

PersonDirectory as API

The basic class for a uPotal user is an implementation of the IPerson object. The uPortal Person Directory Service is used to populate and retrieve user attributes.  Person Directory is maintained as a separate source project PersonDirectory.  uPortal 4 provides the single class, PersonDirectory, to obtain an instance of IPersonAttributeDao. This class is currently deprecated and will no longer be needed in a future version of uPortal that is entirely Spring configured.  Attributes can be acquired from multiple sources via LDAP, JDBC or other sources as required.

An example of how to get a standard IPerson and attributes for it:

IPersonAttributeDao dao = PersonDirectory.getPersonAttributeDaoInstance();
Map userAttributes = dao.getUserAttributes(UserID);
IPerson person = PersonFactory.createPerson();
person.setAttributes(userAttributes);

Below is a description of the default Person Directory configuration.  See JDBC User Attribute Sources and LDAP User Attribute Sources for examples of setting additional attributes via JDBC and LDAP.

Configuring PersonDirectory

PersonDirectory is a uPortal customization point.

The standard recommended approach to customizing PersonDirectory is to modify the PersonDirectory Spring context.  It is also still possible to replace the name of the class in personDirectoryContext.xml and supply an entirely custom implementation.  If you have a legacy implementation from a previous version of uPortal, this may be an attractive option.

PersonDirs.xml is not supported

The legacy xml configuration PersonDirs.xml is not supported in uPortal 3.0 and later.

Using Spring to configure an IPersonAttributeDao implementation

The recommended approach is to use Spring to wire together a Java object that implements IPersonAttributeDao. This facility was added in uPortal 2.5. We expect that the provided implementations of IPersonAttributeDao will be sufficient for most uPortal deployments, however you can also develop a custom IPersonAttributeDao to meet additional needs.

Spring and PersonDirectory

Currently a Spring beans.dtd-compliant XML file named personDirectoryContext.xml declares the configuration of an instance of IPersonAttributeDao. The class PersonDirectory delegates to this Spring-configured IPersonAttributeDao instance to actually implement the PersonDirectory behavior.

JDBC Example

For examples, visit the page dedicated to JDBC User Attribute Sources.

LDAP example

For examples, visit the page dedicated to LDAP User Attribute Sources.

Request Attribute Filter Example

The Request Attribute Filter is designed for use with Shibboleth. For a complete discussion of configuring uPortal for Shibboleth, see Shibboleth.  The following example shows a use of the RequestAttributeSourceFilter to retrieve the serverName attribute.  In a real life scenario you would want to retrieve person attributes provided in the request.

    <!--
     | Servlet filter that creates an attribute for the serverName
     +-->
    <bean id="requestAttributeSourceFilter" class="org.jasig.services.persondir.support.web.RequestAttributeSourceFilter">
        <property name="additionalDescriptors" ref="requestAdditionalDescriptors" />
        <property name="serverNameAttribute" value="serverName" />
        <property name="processingPosition" value="BOTH" />
    </bean>

Merging example

This would get pretty boring if we could only ever have one source of user attributes at a time. MergingPersonAttributeDaoImpl merges attributes from multiple sources.

Here we're merging together attributes from a JDBCPersonAttributeDaoImpl and from an LdapPersonAttributeDaoImpl. Here we've accepted the default merge strategy, but MergingPersonAttributeDaoImpl is configurable to accept alternative merge strategies. MergingPersonAttributeDaoImpl can also be configured as to how it should handle exceptions thrown by the DAOs it is merging.

<beans>
    <bean id="personAttributeDao"
        class="org.jasig.portal.services.persondir.support.MergingPersonAttributeDaoImpl">
        <property name="personAttributeDaos">
            <list>
                <bean
                    class="org.jasig.portal.services.persondir.support.JdbcPersonAttributeDaoImpl">
                    <constructor-arg>
                       <bean
                         class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		         <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
		         <property name="url"><value>${jdbc.url}</value></property>
		         <property name="username"><value>${jdbc.username}</value></property>
		         <property name="password"><value>${jdbc.password}</value></property>
	               </bean>
                    </constructor-arg>
                    <constructor-arg>
                        <value>SELECT name, shirt_color FROM
                            someschema.sometable WHERE uid = ?</value>
                    </constructor-arg>
                    <property name="columnsToAttributes">
                        <map>
                            <entry key="name">
                                <value>name</value>
                            </entry>
                            <entry key="shirt_color">
                                <value>shirtColor</value>
                            </entry>
                        </map>
                    </property>
                </bean>
                <bean
                    class="org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl">
                    <property name="ldapAttributesToPortalAttributes">
                        <map>
                            <entry key="name">
                                <value>name</value>
                            </entry>
                            <entry key="shirt_color">
                                <value>shirtColor</value>
                            </entry>
                        </map>
                    </property>
                    <property name="ldapServer">
                        <bean
                            class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                            <property name="staticMethod" value="org.jasig.portal.ldap.LdapServices.getLdapServer"/>
                            <property name="arguments">
                                <list>
                                    <value>personLdap</value>
                                </list>
                            </property>
                        </bean>
                    </property>
                    <property name="uidQuery" value"(cn={0})"/>
                    <property name="queryType" value="OR"/>
                </bean>
            </list>
        </property>
    </bean>
</beans>

Rolling your own

If you have special requirements not handled by the Person Directory implementations you can still use the provided IPersonAttributeDao support classes where they fit in with the particular attribute retrieval strategy you're trying to implement.

<beans>
    <bean id="personAttributeDao"
        class="edu.youruniv.portal.persondir.CustomPersonAttributeDaoImpl">
    </bean>
</beans>

Custom Java implementation

Not Recommended

Although not recommended it is possible to change the class name in the personDirectory.xml beans declaration to be a custom class of your choice, so long as it implements IPersonAttributeDao. You could then write a custom implementation that does exactly the queries, caching, and any other behavior you need.
<beans>
<!- notice that the bean's class has changed ->
<bean id="personAttributeDao">
<!-- if you're implementing all your configuration directly in the Java, you need not
add any properties here -->
</bean>
</beans>