Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

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

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

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.

This document describes the installation and configuration of the uPortal extension, developed for the University of Chicago by Unicon, that facilitates the passing of the said SAML assertion to portlets that require that assertion. In addition to the SAML assertion, the Shibboleth Service Provider (SP) that controls Shibboleth authentication and attribute release can optionally release the public keys of the Identity Provider (IdP). These public keys can be used to verify the authenticity of the IdP and prevent "man in the middle" attacks.

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:

  1. Retrieve a SAML assertion that was issued for the logged in user's portal session and the optional IdP public key(s).
  2. Make these attributes available to portlets that request them.

The project can be built with the following command:

mvn install

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.

Following the uPortal's project convention, there are two places, or Maven pom.xml files, where this library must be added for uPortal to use it:

  1. uPortal's top-level pom.xml will contain the definition of the library's name and version
  2. pom.xml in uPortal's uportal-impl module will cause Maven to include the library in the resulting deployable war file

Here are couple of fragments of uPortal's top-level pom.xml:

<servlet-api.version>2.5</servlet-api.version>
<shibboleth-integration.version>1.0</shibboleth-integration.version>  <!-- This is the new line inserted here in its alphabetically ordered place.  -->
<spring-framework.version>2.5.6</spring-framework.version>

<!-- Much detail omitted -->

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

And the following is a fragment of pom.xml in the uportal-impl module:

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

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

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <scope>compile</scope>
</dependency>

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.

To remedy this situation, a new "logical" endpoint was invented to allow uPortal to coexist peacefully with Shibboleth. This endpoint is /uPortal/LoginShib. The /LoginShib endpoint is mapped in uPortal's deployment descriptor to the Login servlet just as the original /uPortal/Login endpoint. This is the servlet to which the SAML assertion capturing filter will be attached. This filter can also capture the IdP's public key for IdP authentication. Here is the web.xml fragment that configures this filter:

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

<servlet-mapping>
  <servlet-name>Login</servlet-name>
  <url-pattern>/LoginShib</url-pattern>
</servlet-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.

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.

To configure uPortal to use SamlAssertionUserInfoService, file portletContainerContext.xml must be edited. See below for the relevant portion of this file:

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

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

  • No labels