Versions Compared

Key

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

...

WebproxyPortlet v2 Gateway SSO is a feature that allows uPortal to signon to any remote system even if the remote system does not share any authentication information with uPortal.  Gateway SSO will submit login information to the remote system and then redirect to that remote system.  Other SSO solution assume that uPortal has authenticated to some system, such as CAS and will then trust CAS to say the user is authenticated.  In this system, the authentication information is submitted to the remote system invisibly invisible to the user.  This solution has the inherent risks of sending user authentication information over the wire, rather than a security token, but this solution does not require external systems to implement CAS or another authentication system.  It is therefore nearly invisible to any external system to which uPortal would want to connect.

...

  1. The main portlet controller loops through each GatewayEntry associated with the portlet.
  2. Each GatewayEntry runs through each Interceptor associated with it to ensure that the entry is valid and then calls the
  3. The main JSP to render.render the gateway portlet (list of external systems to connect to).  Each GatewayEntry is rendered on the page, displaying the name, icon and if valid a link to the external system.  Invalid external systems display a message about describing the issue (such as credentials not being configured).
  4. The user then clicks on the link for the external system they wish to access.  This makes an Ajax call to the handling controller.By default this opens a new tab that returns a page with a Javascript AJAX handler to request connection information from the handling controller, but there is a portlet preference to replace the existing page. 
  5. The handling controller gathers all of the form information stored in the HttpContentRequestImpl parameters configuration (basically a list of form fields and values) and readies it them for return to the calling JSPbrowser
  6. All configured Interceptors perform any substitutions on configuration data, such as inserting usernames and passwords.
  7. All configured external logic modules run.  This adds additional parameter fields to the result and may perform additional configuration (depending upon the implementation.)IAuthenticationFormModifier modules run.  These can add additional parameter fields to the result and may perform additional custom logic (depending upon the implementation).  An example of an IAuthenticationFormModifier is a need to contact an external system to get a token that is submitted with the authentication form to the external system.  The custom logic can invoke the external system, parse out the token, and add it as a form field or modify the submit URL to include the token.
  8. The controller returns all of the gathered data to the calling JSPbrowser (by default a JSON response).
  9. The JSP Javascript Ajax handler builds an appropriate form and submits it to the external system.  The external system then handles the call and will render whatever page a successful login would render.

...

Code Block
titlegateway-sso-portlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <context:component-scan base-package="org.jasig.portlet.proxy.mvc.portlet.gateway" />
    <context:annotation-config />

    <bean
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:configuration.properties" />
    </bean>
    <util:list id="gatewayEntries" scope="session">
          <bean class="org.jasig.portlet.proxy.mvc.portlet.gateway.GatewayEntry" p:name="MyZimbra"
              p:iconUrl="/ResourceServingWebapp/rs/tango/0.8.90/32x32/apps/internet-mail.png">

            <property name="authenticationFormModifier">
                <util:list>
 <property name="externalLogic">
                <util:list>
                   <!-- This bean modifies a special field that alters the location to POST the form data to -->
                   <bean <bean id="step1" 
						class="org.jasig.portlet.proxy.service.web.MyCustomClass"  
						scope="session" 
						p:fieldName="proxiedLocation"/>
                    <bean id="step2" 
						class="org.jasig.portlet.proxy.service.web.MyCustomClass2" 
						scope="singleton" 
						p:fieldName="testField" />
                </util:list>
            </property>

            <property name="contentRequests">
                <util:map>
                    <entry>
                        <key>
                            <bean class="org.jasig.portlet.proxy.service.web.HttpContentRequestImpl"
                                  p:proxiedLocation="https://zimbra.unicon.net/zimbra/"
                                  p:form="true" p:method="POST">
                                <property name="parameters">
                                    <util:map>
                                        <entry>
                                            <key><value>loginOp</value></key>
                                            <bean class="org.jasig.portlet.proxy.service.web.FormFieldImpl"
                                                    p:name="loginOp" p:value="login"/>
                                        </entry>
                                        <entry>
                                            <key><value>username</value></key>
                                            <bean class="org.jasig.portlet.proxy.service.web.FormFieldImpl"
                                                    p:name="username" p:value="{prefs.myzimbra.uid}"/>
                                        </entry>
                                        <entry>
                                            <key><value>password</value></key>
                                            <bean class="org.jasig.portlet.proxy.service.web.FormFieldImpl"
                                                    p:name="password" p:value="{prefs.myzimbra.pwd}" p:secured="true"/>
                                        </entry>
                                    </util:map>
                                </property>
                            </bean>
                        </key>
                        <util:list>
                            <value>userInfoUrlParameterizingPreInterceptor</value>
                            <value>UserPreferencesPreInterceptor</value>
                        </util:list>
                    </entry>
                </util:map>
            </property>
        </bean>

		<!-- additional external systems to display -->
		<bean ...></bean> 
    </util:list>
    <bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors"><bean class="org.jasig.portlet.proxy.mvc.MinimizedStateHandlerInterceptor"/></property>
    </bean>

</beans>

...

FormFieldImpl contains the information about each field that will be included in the form submitted to the external system.  The relevant fields are:

  • name - the name of the HTML fieldof the HTML field.  proxiedLocation is a special value that alters the location the form POSTs to
  • value - the value of the HTML field.  This field is either a static value or a value that an Interceptor will recognize as being overridden.
  • secured - whether the field should be sent as input type of "text" or "password".  If secured is true, it sends as a password field.  In addition, if the secured field is an overridden field that is editable, the editable field will be obscured when editable and will be encrypted when stored.

...

The FormFieldImpl entry for username shows a valud of "{prefs.myzimbra.uid}", which the UserPreferencePreInterceptor would recognize as a PortletPreference and would substitute the value found for this field , if UserPreferencePreInterceptor is configured for this HttpContentRequestImpl.

...

  • intercept() - substitutes the configured value for another, if necessary
  • validate() - returns true if all of the information needed to perform a substitution is avaialbleavailable, otherwise false

UserPreferencePreInterceptor

...

These portlet preferences can be edited by the user.  The portlet must be configured to support Edit mode.  All FormFieldImpl values that match the preferences regex will be displayed for the user to edit as preferences and will be persisted.  Secured fields will be encrypted in the database and will be obscured on the Portlet's Edit page.  To use this interceptor, the encryption password must be set for the bean "stringEncryptionService" in applicationContext.xml.

UserInfoUrlParameterizingPreInterceptor

UserPreferencePreInterceptor overrides FormFieldImpl values with the values stored in UserInfo.  uPortal can be configured to store your uPortal login and password, making them available to userInfo.  If uPortal is configured this way (refer to the uPortal manual for exposing user attributes to a portlet), this interceptor will send the same uid and password that you used to authenticate to uPortal to the external system.  Since uPortal and the external system do not share an authentication system, it is still possible for the two systems to get out of sync.  An example of a valid FormFieldImpl value would be "{user.login.id}"

ExternalLogic

...

Custom Java logic

Java Beans that implement IAuthenticationFormModifier can be embedded in your Gateway SSO to support more complicated scenarios.  The user can create their own Java Bean that implements the ExternalLogic the IAuthenticationFormModifier interface and include it in the portlet definition.  When the controller gathers all of the information required by the JSP to render, in addition to any fields defined in the associated FormFieldImpl fields, it will add a new field for each ExternalLogic bean.

For example, say you have an external system to which you wish to login.  Before you actually login, however, you need to retrieve a token from another system and include it in the submitted form or on the form's action field.  You can write a custom logic bean that will retrieve that value and include it as a field in the submission.  If you wish to create a custom form action, you could return a field named "proxiedLocation" , which would override the proxied location stored with the HttpContentRequestImpl field.

This is how you might add ExternalLogic add IAuthenticationFormModifier to your portlet definition file

Code Block
titleIncluding ExternalLogic in your portlet
          <bean class="org.jasig.portlet.proxy.mvc.portlet.gateway.GatewayEntry" p:name="MyZimbra"
              p:iconUrl="/ResourceServingWebapp/rs/tango/0.8.90/32x32/apps/internet-mail.png">

            <property name="externalLogicauthenticationFormModifier">
                <util:list>
                    <bean id="step1" 
						class="org.jasig.portlet.proxy.service.web.MyCustomClass"  
						scope="session" 
						p:fieldName="proxiedLocation"/>
                    <bean id="step2" 
						class="org.jasig.portlet.proxy.service.web.MyCustomClass2" 
						scope="singleton" 
						p:fieldName="testField" />
                </util:list>
            </property>
			...
		</bean> 

 

...

IAuthenticationFormModifier

ExternalLogic is IAuthenticationFormModifier is an interface that must be implemented by any classes that wish to hook into the External Logic IAuthenticationFormModifier process.  The methods are:

...