Request Header Attribute Source
Overview
The RequestAttributeSourceFilter provides the ability to use values from HttpServletRequest methods and headers as user attributes. The examples below store the attributes in the user's session. The JavaDocs linked for the class provides the configuration options.
Attribute Caching Concerns
The AdditionalDescriptorsPersonAttributeDao
that actually provides the user attributes from the session should not be wrapped in a CachingPersonAttributeDaoImpl or any other cache, the attributes can change from request to request and the cache will hide this changes.
Examples
There are two ways to use the request attribute source. One requires the username be available as part of the request, the other requires that the application can provide the current username when running an attribute query.
<!-- | Use Spring's delegating proxy, uses the spring managed bean with the id that matches the filter-name +--> <filter> <filter-name>requestAttributeSourceFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <!-- | Apply the filter to the URL that will receive the user attribute headers, likely /Login +--> <filter-mapping> <filter-name>requestAttributeSourceFilter</filter-name> <url-pattern>/Login</url-pattern> </filter-mapping>
Example using username from Request
The following example assumes the username is provided by HttpServletRequest.getRemoteUser().
<!-- | This is the actual servlet filter implementation. The delegating fitler proxy configured in web.xml will delegate | to this bean. | | In this example: | - The getRemoteUser value is mapped to the 'username' attribute. | - The getServerName value is mapped to the 'serverName' attribute. | - The headerAttributeMapping declares two headers to turn into attributes (headerAttr1 and headerAttr2). | headerAttr1 will appear as portalAttrName1 in the user's attributes. | headerAttr2 will appear as portalAttr2Varient1 and portalAttr2Varient2 in the user's attributes. | - processingPosition Tells the filter to store the user attributes in the session both before and after | doFilter is called. This is useful when filtering around things like the uPortal login servlet which | invalidates and re-creates the session during execution. +--> <bean id="requestAttributeSourceFilter" class="org.jasig.services.persondir.support.web.RequestAttributeSourceFilter"> <property name="additionalDescriptors" ref="requestAdditionalDescriptors" /> <property name="remoteUserAttribute" value="username" /> <property name="serverNameAttribute" value="serverName" /> <property name="processingPosition" value="BOTH" /> <property name="headerAttributeMapping"> <map> <entry key="headerAttr1" value="portalAttrName1" /> <entry key="headerAttr2"> <set> <value>portalAttr2Varient1</value> <value>portalAttr2Varient2</value> </set> </entry> </map> </property> <property name="processingPosition" value="BOTH" /> </bean> <!-- | This object holds the user attributes set by the RequestAttributeSourceFilter for later retrieval. Since | these attributes are tied to the user's session the bean is declared in the globalSession scope and tagged | as an aop:scoped-proxy. The result of this is each user will get their own copy of this bean and the proxy | that classes referencing this bean will use will automatically find the correct instance from the current | user's session. +--> <bean id="requestAttributeDescriptors" class="org.jasig.services.persondir.support.AdditionalDescriptors" scope="globalSession"> <!-- Required so Spring injects an AOP proxy instead of the actual bean instance --> <aop:scoped-proxy/> </bean> <!-- | The AdditionalDescriptorsPersonAttributeDao is what you would configure in the tree of IPersonAttributeDaos | used to get user attributes. It can be treated just like a JDBC or LDAP dao. +--> <bean id="requestAttributesDao" class="org.jasig.services.persondir.support.AdditionalDescriptorsPersonAttributeDao"> <property name="descriptors" ref="requestAdditionalDescriptors" /> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> </bean>
Example using ICurrentUserProvider
The following example assumes the username is not available from the request. In this case the application must implement the ICurrentUserProvider and inject it into the AdditionalDescriptorsPersonAttributeDao. This is required so the DAO knows for which queries to return the attributes from the request.
<!-- | This is the actual servlet filter implementation. The delegating fitler proxy configured in web.xml will delegate | to this bean. | | In this example: | - The getServerName value is mapped to the 'serverName' attribute. | - The headerAttributeMapping declares two headers to turn into attributes (headerAttr1 and headerAttr2). | headerAttr1 will appear as portalAttrName1 in the user's attributes. | headerAttr2 will appear as portalAttr2Varient1 and portalAttr2Varient2 in the user's attributes. | - processingPosition Tells the filter to store the user attributes in the session both before and after | doFilter is called. This is useful when filtering around things like the uPortal login servlet which | invalidates and re-creates the session during execution. +--> <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" /> <property name="headerAttributeMapping"> <map> <entry key="headerAttr1" value="portalAttrName1" /> <entry key="headerAttr2"> <set> <value>portalAttr2Varient1</value> <value>portalAttr2Varient2</value> </set> </entry> </map> </property> <property name="processingPosition" value="BOTH" /> </bean> <!-- | This object holds the user attributes set by the RequestAttributeSourceFilter for later retrieval. Since | these attributes are tied to the user's session the bean is declared in the globalSession scope and tagged | as an aop:scoped-proxy. The result of this is each user will get their own copy of this bean and the proxy | that classes referencing this bean will use will automatically find the correct instance from the current | user's session. +--> <bean id="requestAttributeDescriptors" class="org.jasig.services.persondir.support.AdditionalDescriptors" scope="globalSession"> <!-- Required so Spring injects an AOP proxy instead of the actual bean instance --> <aop:scoped-proxy/> </bean> <!-- | The AdditionalDescriptorsPersonAttributeDao is what you would configure in the tree of IPersonAttributeDaos | used to get user attributes. It can be treated just like a JDBC or LDAP dao. +--> <bean id="requestAttributesDao" class="org.jasig.services.persondir.support.AdditionalDescriptorsPersonAttributeDao"> <property name="descriptors" ref="requestAdditionalDescriptors" /> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> <property name="currentUserProvider" ref="currentUserProvider" /> </bean>
Example using username from Request and handling session invalidation
The following example assumes the username is provided by HttpServletRequest.getRemoteUser(). This example also handles session invalidation which happens during the login request on some applications, including uPortal. The additional attributes are stored the current request as well as the session ensuring that they are available
at every point during the request.
<!-- | This is the actual servlet filter implementation. The delegating fitler proxy configured in web.xml will delegate | to this bean. | | In this example: | - The getRemoteUser value is mapped to the 'username' attribute. | - The getServerName value is mapped to the 'serverName' attribute. | - The headerAttributeMapping declares two headers to turn into attributes (headerAttr1 and headerAttr2). | headerAttr1 will appear as portalAttrName1 in the user's attributes. | headerAttr2 will appear as portalAttr2Varient1 and portalAttr2Varient2 in the user's attributes. | - processingPosition Tells the filter to store the user attributes in the session both before and after | doFilter is called. This is useful when filtering around things like the uPortal login servlet which | invalidates and re-creates the session during execution. +--> <bean id="requestAttributeSourceFilter" class="org.jasig.services.persondir.support.web.RequestAttributeSourceFilter"> <property name="additionalDescriptors" ref="requestAdditionalDescriptors" /> <property name="remoteUserAttribute" value="username" /> <property name="serverNameAttribute" value="serverName" /> <property name="processingPosition" value="BOTH" /> <property name="headerAttributeMapping"> <map> <entry key="headerAttr1" value="portalAttrName1" /> <entry key="headerAttr2"> <set> <value>portalAttr2Varient1</value> <value>portalAttr2Varient2</value> </set> </entry> </map> </property> <property name="processingPosition" value="BOTH" /> </bean> <!-- | Delegates to two data holding AdditionalDescriptors objects. The first is session scoped, used to store | the attributes for the duration of the user's session. The second is request scoped, ensuring that on the | request that the attributes were provided if the session is invalidated the attributes will still be | available. +--> <bean id="requestAdditionalDescriptors" class="org.jasig.services.persondir.support.MediatingAdditionalDescriptors"> <property name="delegateDescriptors"> <list> <bean class="org.jasig.services.persondir.support.AdditionalDescriptors" scope="globalSession"> <aop:scoped-proxy /> </bean> <bean class="org.jasig.services.persondir.support.AdditionalDescriptors" scope="request"> <aop:scoped-proxy /> </bean> </list> </property> </bean> <!-- | The AdditionalDescriptorsPersonAttributeDao is what you would configure in the tree of IPersonAttributeDaos | used to get user attributes. It can be treated just like a JDBC or LDAP dao. +--> <bean id="requestAttributesDao" class="org.jasig.services.persondir.support.AdditionalDescriptorsPersonAttributeDao"> <property name="descriptors" ref="requestAdditionalDescriptors" /> <property name="usernameAttributeProvider" ref="usernameAttributeProvider" /> </bean>