Portlets using Proxy CAS
What is Proxy CAS?
Proxy CAS allows authentication of a chain of services (say, your Calendar Portlet as accessed from your uPortal instance) and its participation in a Single Sign On session (say, end user "awp9" authenticated via CAS to your uPortal, which proxy authenticated via CAS to your JSR-168 calendar portlet, which proxy authenticated via CAS to your calendar feed server). All of this happens with the end user authenticated to CAS using, say, a username and password and the services authenticated to CAS via server-side SSL certificates. No forwarding of primary credentials - only CAS server gets to see the password.
uPortal Portlet ProxyCAS Strategy
The uPortal obtains a Proxy Granting Ticket in the name of the uPortal instance at the time the user authenticates. The Cas Proxy Ticket User Info Service then requests a proxy ticket for a URL representing the portlet (for example, "https://my.school.edu/CalendarPortlet/CasProxyServlet").
The user info service places the resulting proxy ticket in the portlet's UserInfo map under the configured attribute name (by default "casProxyTicket"). The portlet must then validate the proxy ticket and request that a proxy granting ticket be issued to the portlet. This proxy granting ticket may subsequently be used to acquire proxy tickets for other services (e.g. some calendar feed server).
Using ProxyCAS with a Portlet
Configure the CAS Ticket User Info Service
To use the CAS Ticket User Info Service, ensure the bean is mapped in uportal-impl/src/main/resources/properties/contexts/portletContainerContext.xml and included in the userInfoService bean list. This bean is present and appropriately configured in the default uPortal distribution, but it is provided below for completeness.
<bean id="userInfoService" class="org.jasig.portal.portlet.container.services.MergingUserInfoService"> <property name="userInfoServices"> <list> <ref bean="personDirectoryUserInfoService"/> <ref bean="casTicketUserInfoService"/> </list> </property> </bean> <bean id="casTicketUserInfoService" class="org.jasig.portal.portlet.container.services.CasTicketUserInfoService"> <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" /> </bean>
Add the CAS Proxy Ticket Attribute to portlet.xml
The proxy ticket user info service will not request a proxy ticket for the portlet unless the portlet specifically requests it. To ensure a proxy ticket is placed in the UserInfo map, add a user-attribute mapping to the portlet's portlet.xml file. The configured attribute name must precisely match the key name configured in uPortal's CasTicketUserInfoService. This directive is placed outside the <portlet/> element:
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" 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" id="ProxyCasPortlet"> <portlet> . . . </portlet> <user-attribute> <!-- This attribute name must match the key name configured in uPortal's CasTicketUserInfoService --> <name>casProxyTicket</name> </user-attribute> </portlet-app>
Get a Proxy Ticket from the portlet for a backend service
Using Proxy CAS using the 3.1.x Jasig CAS client generally involves configuring filters, then using the CAS Java API to validate the UserInfo map provided CAS ticket.This works as follows:
First the portlet retrieves its own proxy ticket from the portlet's UserInfo map. Next it can use the org.jasig.cas.client.validation.TicketValidator class to validate the ticket and retrieve an Assertion object. The Assertion object encapsulates the Ticket Granting Ticket that the portlet can now use to obtain service tickets for back end services and resources. The Assertion object, once obtained is durable for the life of the portlet instance and can be used multiple times to obtain service tickets. The Assertion can be stored in the session and re-used by other components to obtain service tickets as needed.
Current CAS best practices suggest using Spring's DelegatingFilterProxy to configure a CAS filters via the Spring application context. This strategy allows developers to make use of Java property files for configuring strings such as the portal's base server URL.
Sample code and configuration for getting proxy tickets from a portlet is available in the Cas Proxy Test Portlet. Further documentation on using CAS's filters is available at https://wiki.jasig.org/display/CASC/Configuring+the+JA-SIG+CAS+Client+for+Java+using+Spring.