View on GitHub

Single Sign-On for the Web

Attribute Release

Attributes are controlled by the Person Directory project and returned to scoped services via the SAML 1.1 protocol or the CAS protocol. The Person Directory dependency is automatically bundled with the CAS server. Therefore, declaring an additional dependency will not be required. This Person Directory project supports both LDAP and JDBC attribute release, caching, attribute aggregation from multiple attribute sources, etc.

Attributes pass through a two-step process:

Service Management

Attribute release may also be configured via the Service Management tool.

Components

A PersonDirectory IPersonAttributeDao attribute source is defined and configured to describe the global set of attributes to be fetched for each authenticated principal. That global set of attributes is then filtered by the service manager according to service-specific attribute release rules.

Person Directory

More about the Person Directory and its configurable sources can be found here.

CAS

The CAS project provides the following additional implementations:

Sample Usage

LDAP

The following snippet assumes that connection information beans are already defined.


<context:component-scan base-package="org.jasig.cas" />
<context:annotation-config />

<bean id="ldapPersonAttributeDao"
      class="org.jasig.cas.persondir.LdapPersonAttributeDao"
      p:connectionFactory-ref="pooledLdapConnectionFactory"
      p:baseDN="${ldap.baseDn}"
      p:searchControls-ref="searchControls"
      p:searchFilter="mail={0}">
    <property name="resultAttributeMapping">
        <map>
            <!--
               | Key is LDAP attribute name, value is principal attribute name.
               -->
            <entry key="member" value="member" />
            <entry key="mail" value="mail" />
            <entry key="displayName" value="displayName" />
        </map>
    </property>
</bean>

JDBC

The following snippet assumes that connection information beans are already defined.

<bean id="singleRowJdbcPersonAttributeDao"
    class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
    <constructor-arg index="0" ref="dataSource" />
    <constructor-arg index="1" value="SELECT * FROM USER_DATA WHERE {0}" />
    <property name="queryAttributeMapping">
        <map>
            <entry key="username" value="uid" />
        </map>
    </property>
    <property name="resultAttributeMapping">
        <map>
            <entry key="uid" value="username" />
            <entry key="first_name" value="first_name" />
            <entry key="last_name" value="last_name" />
            <entry key="email" value="email" />
        </map>
    </property>
</bean>

Caching, Merging and Cascading

<bean id="mergedPersonAttributeDao"
        class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl">
    <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="cachedPersonAttributesDao" >
        <bean id="mergedPersonAttributeDao"                 
                class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl">
            <property name="merger">
                <bean class="org.jasig.services.persondir.support.merger.NoncollidingAttributeAdder" />
            </property>
            <property name="personAttributeDaos">
                <list>
                    <bean class="org.jasig.services.persondir.support.CascadingPersonAttributeDao">
                        <property name="personAttributeDaos">
                            <list>
                                <ref bean="anotherDao" />
                            </list>
                        </property>
                    </bean>
                </list>
            </property>
        </bean>
    </property>
</bean>

Configuration

Once principal attributes are resolved, adopters may choose to allow/release each attribute per each definition in the registry. Example configuration follows:

<bean class="org.jasig.cas.services.RegisteredServiceImpl">
  <property name="id" value="0" />
  <property name="name" value="HTTPS Services" />
  <property name="description" value="YOUR HTTP Service" />
  <property name="serviceId" value="https://**" />
  <property name="allowedAttributes">
    <list>
      <value>yourAttributeName</value>
    </list>              
  </property>
</bean>

Principal-Id Attribute

The service registry component of CAS has the ability to allow for configuration of a usernameAttribute to be returned for the given registered service. When this property is set for a service, CAS will return the value of the configured attribute as part of its validation process.

<bean class="org.jasig.cas.services.RegisteredServiceImpl">
  <property name="id" value="0" />
  <property name="name" value="HTTPS Services" />
  <property name="description" value="YOUR HTTPS Service" />
  <property name="serviceId" value="https://**" />
  <property name="evaluationOrder" value="0" />
  <property name="usernameAttribute" value="mail" />
  <property name="allowedAttributes">
    <list>
      <value>someAttributeName</value>
    </list>              
  </property>
</bean>

Attribute Filters

The service registry component has the ability to allow for configuration of an attribute filter. Filters have the ability to do execute additional processes on the set of attributes that are allocated to the final principal for a given user id. For instance, you might want to decide that certain attribute need to be removed from the final resultset based on a user role, etc.

RegisteredServiceAttributeFilter

If you wish to write your own filter, you need to design a class that implements this interface and as such, plug that custom instance into the specific service registry entry you intend to use.

RegisteredServiceRegexAttributeFilter

A regex-aware filter responsible to make sure only attributes that match a certain pattern are released for a given service.

This example also demonstrates the configuration of an attribute filter that only allows for attributes whose length is 3.

<bean class="org.jasig.cas.services.RegexRegisteredService">
   <property name="id" value="1" />
   <property name="name" value="HTTP and IMAP on example.com" />
   <property name="description" value="Allows HTTP(S) and IMAP(S) protocols on example.com" />
   <property name="serviceId" value="^(https?|imaps?)://([A-Za-z0-9_-]+\.)*example\.com/.*" />
   <property name="evaluationOrder" value="0" />
   <property name="attributeFilter">
      <bean class="org.jasig.cas.services.support.RegisteredServiceRegexAttributeFilter" 
            c:regex="^\w{3}$" /> 
   </property>
</bean>