Configuring uPortal to pass the SAML Assertion

For portlets to perform delegated authentication they must have access to the SAML assertion that was issued to the portal when the user authenticated. This page documents how to configure uPortal provide this and the IdP's public keys to portlets via the USER_INFO Map. The uportal-shibboleth-delegation-integration library makes this happen via a servlet filter and a plugin for the uPortal USER_INFO services.

Step 1 - Add the Dependency

The following changes will result in uportal-shibboleth-delegation-integration-1.1.0.jar being included in the final uPortal WAR.

In pom.xml add the version property

<servlet-api.version>2.5</servlet-api.version>
<!-- This is the new line inserted here in its alphabetically ordered place. -->
<uportal-shibboleth-delegation-integration.version>1.1.0</uportal-shibboleth-delegation-integration.version>
<slf4j.version>1.5.8</slf4j.version>

and the dependency in the dependencyManagement section

<dependency>
    <groupId>org.jasig.service.persondir</groupId>
    <artifactId>person-directory-impl</artifactId>
    <version>${person-directory.version}</version>
</dependency>
<!-- This is the new dependency element added -->
<dependency>
    <groupId>org.jasig.service</groupId>
    <artifactId>uportal-shibboleth-delegation-integration</artifactId>
    <version>${uportal-shibboleth-delegation-integration.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring-framework.version}</version>
</dependency>

In uportal-impl/pom.xml add the dependency in the dependency section

<dependency>
    <groupId>org.jasig.service.persondir</groupId>
    <artifactId>person-directory-impl</artifactId>
    <scope>compile</scope>
</dependency>

<!-- This is the new dependency element added -->
<dependency>
    <groupId>org.jasig.service</groupId>
    <artifactId>uportal-shibboleth-delegation-integration</artifactId>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jcl</artifactId>
    <scope>compile</scope>
</dependency>

Step 2 - Add the Servlet Filter

In uportal-war/src/main/webapp/WEB-INF/web.xml add

<filter>
    <filter-name>SamlAssertionFilter</filter-name>
    <filter-class>org.jasig.portal.security.provider.SamlAssertionFilter</filter-class>
    <init-param>
        <param-name>samlAssertionSessionAttributeName</param-name>
        <param-value>SAML Assertion</param-value>
    </init-param>
    <init-param>
        <param-name>idpPublicKeysSessionAttributeName</param-name>
        <param-value>IdP Public Keys</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>SamlAssertionFilter</filter-name>
    <servlet-name>Login</servlet-name>
</filter-mapping>

Please note that the filter has two configurable parameters:

  1. The name under which to store the SAML assertion in the HTTP session. This is the name by which the assertion will be retrieved from the session and passed on to portlets that need it.
  2. The name under which to store the IdP public key(s) in the HTTP session. As with the SALM assertion, this is the name under which the portlet container will retrieve the public key(s) from the session for the portlet(s) that require them.

Step 3 - Configure the USER_INFO Service

uPortal uses Apache Pluto's UserInfoService interface implementations to convey user-specific information to portlets as user attributes. A new implementation of this interface was developed to retrieve SAML assertion and IdP public key from the HTTP session and make it available to portlets. Portlets must declare that they need SAML assertion attribute in their deployment descriptor--portlet.xml. When SamlAssertionUserInfoService detects that a portlet requested SAML assertion, it retrieves the assertion from the HTTP session and passes it to the portlet. SamlAssertionUserInfoService deals with the IdP public key the same way.

In uportal-impl/src/main/resources/properties/contexts/portletContainerContext.xml

<bean id="userInfoService" class="org.jasig.portal.portlet.container.services.MergingUserInfoService">
    <property name="userInfoServices">
        <list>
            <ref bean="personDirectoryUserInfoService" />
            <ref bean="casTicketUserInfoService" />
            <ref bean="samlAssertionUserInfoService" /> <!-- this is a new bean defined below -->
        </list>
    </property>
</bean>

<bean id="samlAssertionUserInfoService" class="org.jasig.portal.portlet.container.services.SamlAssertionUserInfoService">
    <property name="userInstanceManager" ref="userInstanceManager" />
    <property name="portletWindowRegistry" ref="portletWindowRegistry" />
    <property name="portletEntityRegistry" ref="portletEntityRegistry" />
    <property name="portletDefinitionRegistry" ref="portletDefinitionRegistry" />
    <property name="portalRequestUtils" ref="portalRequestUtils" />

    <!-- These have to match what portlets declare for user attributes in portlet.xml -->
    <property name="samlAssertionKey" value="samlAssertion" />
    <property name="idpPublicKeysKey" value="idpPublicKeys" />

    <!-- These have to match the values defined for the SamlAssertionFilter in web.xml -->
    <property name="samlAssertionSessionKey" value="SAML Assertion" />
    <property name="idpPublicKeysSessionKey" value="IdP Public Keys" />
</bean>

Portlet Configuration

The steps above are all that is needed in uPortal. For a portlet to make use of this feature please read about using the Delegated Authentication Integration Library