Ensemble Development

Customizing the Login Process

What a user sees when logging in and out of Ensemble resources can be customized using a login resource. Based on the experience definition associated with the user, different pages can be delivered to the user at different steps in the login process, including custom login, interstitial, error and logout pages.

Configuring Custom Login Pages

On the Log In Settings page of experience definition configuration, you can define the login resource and login, logout, error, and other interstitial pages. The login resource is a proxied application server used to host the various login pages associated with the experience definition. To define a login resource, create a resource and select Is login resource on the General tab.

The following table describes the login pages that can be associated with an experience definition.

Page

Definition

Pre-login page

Displayed before attempting to authenticate the user.

Login page

Only applicable when form authentication is being used, and provides the form for login.

Post-login page

Displayed to the user after successful authentication and before the resource is accessed.

Error page

Displayed if there is an error in the login process.

Post-logout page

Displayed after the user logs out of the resource.

Caution: The settings in the experience definition are used regardless of the authenticator used to access a resource. If the required authenticator uses a login page, and there is no login page configured in the experience definition, the user will be presented with a blank page and unable to authenticate. For details, see the AquaLogic Ensemble Administrator Guide Chapter 8, “Experience Definitions”.

Communication between login resource pages and Ensemble is done using HTTP headers. The following table describes the available headers, including how and when they are used. (Error and Post-logout pages are considered terminal pages and do not communicate with Ensemble using headers.)

 

Page

Header

Values

Pre-login

runner_pre_interstitial_complete

true indicates that the pre-login page has completed successfully. Ensemble proceeds to the login page.

false (or no header) means the page has not completed successfully. The pre-login page is displayed again.

Login

runner_username

The user name Ensemble will use to authenticate the user.

runner_password

The password Ensemble will use to authenticate the user.

runner_authentication_provider

The provider for authentication. For AquaLogic Ensemble 1.0, the only valid value is portal. If the header is not present, the provider defaults to portal.

runner_portal_authentication_source

The authentication source against which to authenticate the user. This is the same as the authentication source the user would use to log in to the portal.

Post-login

runner_post_interstitial_complete

true indicates that the post-login page has completed successfully. Ensemble proceeds to the resource.

false (or no header) means the page has not completed successfully. The post-login page is displayed again.

 

Creating Custom Login Pages

As explained above, the pages displayed to a user during the login process are configured through experience definitions. The content and functionality on these pages can be customized in a wide range of ways.

The Ensemble Adaptive Tag Library provides login UI elements and other functionality for use in custom login pages. The relevant tags are explained in the sections that follow.

Pre-Login Page

The pre-login page allows you to display an interstitial page before providing a login form. (An interstitial page is a page that appears before the expected content page.) For example, the pre-login page could display an important message about availability or new functionality. The pre-login page can also be used to display a custom message to users who are part of an experience definition that is blocked from accessing the requested resource.

In the example below, the Pre-login page (preinterstitialpage.jsp) displays a message about server maintenance. This page uses the pt:common.error tag to display any errors within the page, and the pt:core.html tag to display the submit button. For details on using tags, see Adaptive Tags.

<%@page contentType="text/html;charset=UTF-8"%>

<HTML>
<BODY>
<SPAN xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

<FORM action="./processpreinterstitialpage.jsp" method="POST">
<P>
<TABLE>
<TR><TD>
<CENTER><B>Maintenance Updates</B></CENTER>
</TD></TR>

   <TR><TD>
This server will be going down for maintenance on 5/28/07 at 6:37PM and 24 seconds.<BR>

   <pt:common.error>
<P>
<B><FONT color="red"><pt:logic.value pt:value="$#10.ptmsgs_login"/></FONT>:</B>
<pt:common.errortext/>
</P>
</pt:common.error>

   </TD></TR>
 

   <TR><TD>
<CENTER>
<pt:core.html pt:tag="input" type="submit" value="$#2.ptmsgs_samples"/>
</CENTER>
</TD></TR>
</TABLE>
</FORM>

</SPAN>
</BODY>
</HTML>

When the user clicks the submit button, the processing page (processpreinterstitialpage.jsp) sets the runner_pre_interstitial_complete header to true, which directs the browser to the login page. It also provides error text for the error page in case processing fails.  

<%@page contentType="text/html;charset=UTF-8"%>

<HTML>
<BODY>
<%

        out.println( "<P>Runner pre-login interstitial page processing login completion error.  Contact your system administrator.</P>");
 response.addHeader( "runner_pre_interstitial_complete", "true");

%>
</BODY>
</HTML>

Login Page

The login page allows you to customize the login form display and functionality. The pt:ensemble.authsourcedata tag provides a collection of the authentication sources available for the resource. The data is stored as a collection, and each item in the collection is a data object containing information about the authentication source (prefix, name, description) accessible through the data object dot notation ($authsource.name). You can use additional Adaptive Tags to iterate through the collection and allow the user to select the appropriate choice, as shown below.

The example below (loginpage.jsp) displays a banner and a login form. The login form posts back to the page, which sets the appropriate headers to authenticate with the resource (runner_username, runner_password, runner_authentication_provider, and runner_portal_authentication_source). This page uses the pt:ensemble.authsourcedata tag, as well as several other Adaptive Tags to handle logic and display.

<%@ page import="java.net.*"%>
<%@page contentType="text/html;charset=UTF-8"%>

<%

    String username = request.getParameter( "username" );
String password = request.getParameter( "password" );
if(username != null && password != null)
{
response.addHeader( "runner_username", username);
response.addHeader( "runner_password", password);
}

    String authsource = request.getParameter( "authsource" );
if ( authsource != null )
{
response.addHeader( "runner_authentication_provider", "portal" );
response.addHeader( "runner_portal_authentication_source", authsource );
}

%>

<html>
<head>
<link rel='stylesheet' type='text/css' href='css/main.css'/>
</head>
<body>

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

<table class="banner" cellpadding="0" cellspacing="0">
<tr>
<td class="appLogo"></htm:td>
<td class="liquid"></htm:td>
</tr>
</table>

<br/>

<!-- Welcome message: -->

<font face="arial" size=2>
<pt:logic.value pt:value="$#3.ptmsgs_login"/><br>
<pt:logic.value pt:value="$#7.ptmsgs_login"/>
</font>

<br/>

<%
String errorValue = request.getHeader( "runner_error_last_error_message" );
if(errorValue != null)
{
out.println("<br>");
out.println("<font face=\"arial\" color=\"0000AA\" size=2>");
out.println("<pt:logic.value pt:value=\"$#8.ptmsgs_login\"/><br>");
out.println("</font>");
out.println("<font face=\"arial\" color=\"AA0000\" size=2>");
out.println("<b>");
out.println(errorValue);
out.println("</b>");
out.println("</font>");
out.println("<br>");
}
%>

<br/>

<pt:common.error>
<font face="arial" color="0000AA" size=2><pt:logic.value pt:value="$#9.ptmsgs_login"/><br>
</font>
<B><FONT color="red"><pt:logic.value pt:value="$#10.ptmsgs_login"/></FONT>:</B>
<pt:common.errortext/>
</P>
</pt:common.error>

<!-- Login form: -->

<FORM name="loginform" action="loginpage.jsp" method="POST">
<table>
<tr><!-- Username -->
   <td align="right">
       <font face="arial" size=2>
       <pt:logic.value pt:value="$#0.ptmsgs_login"/>
       </font>
   </td>
   <td align="left">
       <font face="arial" size=2>
       <!-- inputs and password inputs are of slightly different length in IE.  This can be fixed with CSS. -->
       <pt:core.html pt:tag="input" type="text" name="username" alt="$#0.ptmsgs_login" size="30" value="${param['username']}"/>
       </font>
   </td>
</tr>

        <tr><!-- Password -->
    <td align="right">
       <font face="arial" size=2>
       <pt:logic.value pt:value="$#1.ptmsgs_login"/>
       </font>
   </td>
   <td align="left">
       <font face="arial" size=2>
       <pt:core.html pt:tag="input" onkeypress="return submitform(event)"                   type="password" name="password" size="30" alt="$#1.ptmsgs_login" value="${param['password']}"/>
       </font>
   </td>
</tr>

        <!-- Auth sources -->
<pt:ensemble.authsourcedata pt:key="authsources"/>
<pt:logic.collectionlength pt:data="authsources" pt:key="authsourceslength"/>
<pt:logic.intexpr pt:expr="($authsourceslength)>0" pt:key="hasvalues"/>
<pt:logic.if pt:expr="$hasvalues">
 <pt:logic.iftrue>
   <pt:logic.intexpr pt:expr="($authsourceslength)>1" pt:key="hasmultvalues"/>
   <pt:logic.if pt:expr="$hasmultvalues">
     <pt:logic.iftrue>
       <tr><!--Authentication Source:-->
         <td align="right" width="40%" colspan="1">
           <font face="arial" size=2>
             <pt:logic.value pt:value="$#5.ptmsgs_login"/>
           </font>
         </td>
         <td align="left" width="40%" colspan="1">
           <select name="authsource" onkeypress="return submitform(event)" lang="en">
             <pt:logic.foreach pt:data="authsources" pt:var="auth">
               <pt:core.html pt:tag="option" value="$auth.prefix" alt="$auth.description"> <pt:logic.value pt:value="$auth.name"/></pt:core.html>
             </pt:logic.foreach>
           </select>
         </td>
       </tr>

              </pt:logic.iftrue>
     <pt:logic.iffalse>
       <!-- Hidden input for single auth source. -->
       <pt:logic.foreach pt:data="authsources" pt:var="auth">
         <pt:core.html pt:tag="input" type="hidden" name="authsource" alt="" value="$auth.prefix"/>
       </pt:logic.foreach>
     </pt:logic.iffalse>
     </pt:logic.if>
 </pt:logic.iftrue>
 <pt:logic.iffalse><!-- Otherwise no auth sources for this resource. --></pt:logic.iffalse>
</pt:logic.if>
 

        <tr><!-- Login -->
   <td align="right">
   </td>
   <td align="left">
       <pt:core.html pt:tag="input" type="submit" value="$#2.ptmsgs_login"/>
   </td>
</tr>

    </table>
</FORM>

<br>

<SCRIPT language="JavaScript">
function submitform(evt)
{
evt = (evt) ? evt : event;
var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);
if (charCode == 13 || charCode == 3)
{
document.loginform.submit();
}
return true;
}
</SCRIPT>

</span>
</body>
</html>

The login page can use the pt:ensemble.loginlink tag to retrieve the external URL prefix defined for the resource. For example, if the external URL prefix of the resource is http://www.ensemble.com/app/ and the desired page after login is http://www.ensemble.com/app/pages/mainpage.html, then the full login link would be made by adding pages/mainpage.html to the login link prefix as shown below.

<pt:ensemble.loginlink pt:level="4" pt:key="loginurlprefix"/>
var loginLink = "<pt:logic.value pt:value="$loginurlprefix"/>" + "pages/mainpage.html";

Post-Login Page

The post-login page is another interstitial page that can be used to display messages or gather input from the user.

The example below (interstitialpage.jsp) displays a user agreement that requires approval. This page uses Adaptive Tags to display errors and form elements.

<%@page contentType="text/html;charset=UTF-8"%>

<HTML>
<BODY>
<SPAN xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<FORM action="./processinterstitialpage.jsp" method="POST">
<P>

   <TABLE>
<TR><TD>
<CENTER><B><pt:logic.value pt:value="$#3.ptmsgs_samples"/></B></CENTER>
</TD></TR>
<TR><TD>
<TEXTAREA name="thetext" rows="15" cols="80">
Owner:
This web site belongs to Sample Company United States, Inc.  Sample Company may change or terminate this web site or any parts thereof.

Agreement:
Your use of this web site constitutes your agreement with Sample Company to operate under the auspices of, and to act in concordance with, these Terms and Conditions of use.  By clicking 'Agree' below, you are confirming your agreement, which will also be confirmed by merely accessing this web site beyond this page.

Continuing Agreement:
Sample Company may modify or alter these Usage Terms at any time.  Further usage of this web site after the terms have been modified confirms your agreement with the modified Usage Terms.

Use of Materials:
Sample Company owns all of the data on this web site or has secured permission from a third party to use the material.  Usage of this material in any way outside this web site is strictly prohibited.
</TEXTAREA>

   <pt:common.error>
<P>
<B><FONT color="red"><pt:logic.value pt:value="$#10.ptmsgs_login"/></FONT>:</B>
<pt:common.errortext/>
</P>
</pt:common.error>

   <P>
<pt:core.html pt:tag="input" type="checkbox" name="agreement" alt="$#0.ptmsgs_samples" value="agree"/><pt:logic.value pt:value="$#1.ptmsgs_samples"/>
&nbsp;&nbsp;&nbsp;&nbsp;
<pt:core.html pt:tag="input" type="submit" value="$#2.ptmsgs_samples"/>
</P>

   </TD></TR>
</TABLE>

</FORM>
</SPAN>
</BODY>
</HTML>

When the user clicks the submit button, the processing page (processinterstitialpage.jsp) sets the runner_post_interstitial_complete header to true, which directs the browser to the resource. If the user did not select Accept on the post-login page, a message is displayed including a link back to the agreement. This file also provides error text for the error page in case processing fails.  

<%@page contentType="text/html;charset=UTF-8"%>

<HTML>
<BODY>
<SPAN xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

<pt:common.error>
<P>
<B><FONT color="red"><pt:logic.value pt:value="$#10.ptmsgs_login"/></FONT>:</B>
<pt:common.errortext/>
</P>
</pt:common.error>

<%
if (request.getParameter( "agreement" ) != null)
{
out.println( "<P>Runner post-login interstitial page processing login completion error.  Contact your system administrator.</P>");
response.addHeader( "runner_post_interstitial_complete", "true");
session.invalidate();
} else
{
out.println( "<P>If you do not consent to the web site usage agreement, you will not be able to access any content.</P>");
out.println( "<P>Click <A href=\"./interstitialpage.jsp\">here</a> to view the usage agreement again, or ");
out.println( "you can use <A href=\"http://www.google.com\">Google</a> to find another web site.</P>");
}
%>

</SPAN>
</BODY>
</HTML>

Error Page

A custom error page can be displayed if there is an error in the login process. The pt:common.error, errortext and errorcodes tags allow you to insert Ensemble error information into your custom error page. Note: If these tags are included on a page, errors will no longer be displayed in the normal error location and will not be available after the page has been displayed.

By itself, the pt:common.errortext tag displays only the first error message, or the custom error message defined in the pt:text attribute. Other errors, as well as exception stack traces and extended error messages, will be ignored.

Combined with the pt:common.errorcodes tag and pt:logic tags, the pt:common.errortext tag can be used to display all error codes in memory. (If the errors have already been displayed, no error codes will be available.)  

The example below (errorpage.jsp) illustrates how to retrieve and display a collection of errors and how to replace system errors with a custom error message. This example uses pt:logic Adaptive Tags to display the error collection.

<%@page contentType="text/html;charset=UTF-8"%>

<HTML>
<head>
<link rel='stylesheet' type='text/css' href='css/main.css'/>
</head>

<BODY>
<SPAN xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

<table class="banner" cellpadding="0" cellspacing="0">
<tr>
<td class="appLogo"></htm:td>
<td class="liquid"></htm:td>
</tr>
</table>
<br/>

<P>
<pt:logic.value pt:value="$#11.ptmsgs_login"/>
</P>

<P>
<pt:common.errorcode pt:key="errorcodes"/>
<pt:logic.foreach pt:data="errorcodes" pt:var="code">
<pt:common.errortext/>
<br>
<pt:logic.value pt:value="$#12.ptmsgs_login"/><pt:logic.value pt:value="$code"/>
<br>

<!-- This is how you would override a specific error with a new message. -->
<!--
<pt:logic.intexpr pt:expr="($code)==2010" pt:key="isrequestedresource"/>
<pt:logic.if pt:expr="$isrequestedresource">
 <pt:logic.iftrue>
   <pt:common.errortext pt:text="The requested resource is not in the resource map. This is a custom error message."/>
 </pt:logic.iftrue>
 <pt:logic.iffalse>
   <pt:common.errortext/>
 </pt:logic.iffalse>
</pt:logic.if>
-->

</pt:logic.foreach>
</P>
<P>
<pt:logic.value pt:value="$#13.ptmsgs_login"/>
</P>

</SPAN>
</BODY>
</HTML>

Post-Logout Page

The post-logout page is displayed when the user is logged out of the resource. In most cases, this page simply displays a message that informs users that they have been logged out of the system.

The pt:ensemble.ssologout tag can be added to any proxied page to display a link that logs out of all resources and directs the browser to the post-logout page associated with the user's experience definition.