Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

For portlets to perform delegated authentication they must have access to the SAML assertion that was issued to the portal when the user authenticated. uPortal can provide this and other needed information 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

Code Block
xml
xml

<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

Code Block
xml
xml

<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

Code Block
xml
xml

<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

Code Block
xml
xml

<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>

...

Overview

Portlets wishing to authenticate to Web Service Providers (WSP) to obtain and present information to the logged in uPortal users need to obtain access to the SAML assertion that was issued to uPortal. Per portlet specification, portlets must run in their own Web applications, and are hence isolated from uPortal.

...

IdP public keys are passed to the portlets without any modification. That's different from the SAML assertion, which actually has to be obtained by the special Web filter by a back-channel connection back to the SP. These public keys could be available to the portlets the same way that person attributes are passed by the SP and then made available using uPortal's Person Directory system. However, since the IdP public keys are not really person attributes, their handling is done separately using the SAML assertion Web filter.

Building and installing the executable code

Building the library using Maven

The code supporting the passing of the SAML assertion and IdP public key to the portlets that may need them exists in its own Maven project. The main goal of this Maven project is to build a Java jar file that contains the compiled Java code that has two functions:

...

This will build the Java jar file, called shibboleth-integration-1.0.jar, and install it in the local Maven repository.

Adding the library to the uPortal project

Once the library is built and installed in the local Maven repository, it is available to other local projects to use it. As of this writing, there is no public Maven repository housing this library, so it has to be built locally as described above.

...

With these additions, the jar file shibboleth-integration-1.0.jar will be included with uPortal. However, it will not be active until it is properly configured. The section below provides these details.

Configuring the SAML assertion filter

The SAML assertion is passed to uPortal during authentication. This is usually when Apache passes the /uPortal/Login request to uPortal. However, using this endpoint interferes with uPortal's support for guest, or unauthenticated, users. In a nutshell, after a logout, uPortal redirects the browser to /uPortal/Login, which normally recognizes no login credentials and makes a guest session. With Shibboleth SSO, this was being intercepted by the Shibboleth SP, and the user was logged back in.

...

  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.

Passing SAML assertion and the optional IdP public key(s) to portlets

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.

...

Code Block
xml
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" />
  <property name="samlAssertionKey" value="samlAssertion" />  <!-- This has to match what the portlet declares in its deployment descriptor (portlet.xml) -->
  <property name="samlAssertionSessionKey" value="SAML Assertion" />  <!-- This has to match the value defined in web.xml -->
  <property name="idpPublicKeysKey" value="idpPublicKeys" />  <!-- This has to match what the portlet declares in its deployment descriptor (portlet.xml) -->
  <property name="idpPublicKeysSessionKey" value="IdP Public Keys" />  <!-- This has to match the value defined in web.xml -->
</bean>

Configuring portlets

As mentioned before, portlets must declare names of all person attributes they will need to access. This is mandated by the portlet specification. Portlets list the names of the attributes they will need at runtime in their deployment descriptor, which is the file called portlet.xml. Below is a fragment of the portlet deployment descriptor configured to require SAML assertions and IdP public keys. Even though there may be multiple IdP public keys present, they will appear to the portlet as a single encoded string. The string is not encrypted. It's only Base64-encoded to be compliant with HTTP specifications.

Code Block
xml
xml
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
	version="1.0">

  <portlet>
  <!-- ... -->
  </portlet>

  <user-attribute>
    <description>SAML Assertion</description>
    <name>samlAssertion</name>
  </user-attribute>

  <user-attribute>
    <description>IdP Public Keys</description>
    <name>idpPublicKeys</name>
  </user-attribute>

</portlet-app>

Conclusion

These steps are required for portlets to have access to SAML assertion and to the optional IdP public key(s). The portlets have to make use of these attributes in order to communicate with a WSP and to present data on behalf of the logged-in user. The details of how portlet developers can use these attributes for WSP authentication are documented elsewhere.