Appboard/2.4/builder/system administration/login page/custom: Difference between revisions

imported>Jason.nicholls
imported>Jason.nicholls
 
(9 intermediate revisions by the same user not shown)
Line 4: Line 4:


This document provides some examples of modifying and producing completely custom login pages for AppBoard. For more general information about login pages and how to configure the system login page, refer to the [[appboard/2.4/builder/system_administration/login_page|Login Page]] documentation.
This document provides some examples of modifying and producing completely custom login pages for AppBoard. For more general information about login pages and how to configure the system login page, refer to the [[appboard/2.4/builder/system_administration/login_page|Login Page]] documentation.
The login page is the entry-point for users to AppBoard and must submit three critical pieces of information to the server:
# User Name
# Password
# Domain


By default the different login page styles shipped with AppBoard are simple HTML forms that allow the user to enter the required information, and then <tt>POST</tt> it to the server so the server can authenticate and establish a session.
By default the different login page styles shipped with AppBoard are simple HTML forms that allow the user to enter the required information, and then <tt>POST</tt> it to the server so the server can authenticate and establish a session.
Line 22: Line 16:




== Creating New Login Pages ==  
== Required Fields and Submission ==


Since the Login Page is an HTML page, it is relatively easy to create a new custom Login Page. A custom Login Page can be embedded in any existing HTML page. An HTML developer needs only to add the necessary form elements (and possibly JSP elements) to create an access point for enPortal/AppBoard. In order to add advanced features (error processing, pre-filling elements, minimum browser version detection, and so on) it is necessary to add JSP elements to the page. The standard system login page (<tt>[INSTALL_HOME]/server/webapps/enportal/login_pages/login.jsp</tt>) contains all of the programmatic functions necessary for the common login functions (obtaining the previous user/domain, displaying error messages, and so on).
The following fields are required to log into AppBoard:


* '''login''': set to ''yes''. Typically this is a hidden field
* '''userid''': This would be a visible field to allow a user to enter their user name.
* '''password''': This would be a visible password field to allow a user to enter their password.
* '''domainSelect''': Another text input to allow a user to enter their domain.


Perform the following steps to create a new custom login page:
The form is then <tt>POST</tt>ed to: <tt>/enportal/servlet/pd</tt>. Using <tt>GET</tt> is also possible but not recommended as all all requests are logged and get requests include all parameters, which means user passwords would also get logged.


# Create the directory: <tt>[INSTALL_HOME]/server/webapps/enportal/login_pages/custom/</tt>.
== Included Login Pages ==
# Copy the following file to the new custom directory: <tt>[INSTALL_HOME]/server/webapps/enportal/login_pages/login.jsp</tt>.
# [Optional] Rename the login.jsp file to a name that represents the purpose of the file.
# Modify the file as needed.


The login pages shipped with AppBoard all follow the same structure. A main <tt>login.jsp</tt> Java Server Page which performs browser version checking, auto-fills previous values, handles error responses, presents a HTML form for the user to complete. Along with the JSP there will be other supporting images and CSS resources.


{{Tip|A sample custom Login Page is provided, under /companyX/login.jsp}}
=== Example: Basic Login Page ===
For a detailed example of a Login Page, refer to the default login.jsp page provided with enPortal. As stated above, the easiest method to create a new custom Login Page is to copy/rename the page (to re-use the JSP/Javascript functions) and update the HTML layout/display of the new Login Page. This section provides some details for a basic example of a custom Login Page.
The following example provides only the necessary HTML login form.
{{Note|The following example assumes that the page is located on the same host as the enPortal server. If not, then the action
field must contain the full URL of the enPortal server.}}
<code>[java,N]
<html>
<head>
<title>Basic Enportal Login page</title>
</head>
<body>
<P>Basic enPortal Login Page</P>
<form name="loginForm" method=post action="/enportal/servlet/pd">
<input name="login" type="hidden" value="yes">
<table border="1" >
<tr><td>UserID:</td> <td><input type="text" name="userid" size="12" maxlength="15"></td></tr>
<tr><td>Pwd:</td> <td><input type="text" name="password" size="12" maxlength="15"></td></tr>
<tr><td>Domain:</td> <td> <input type="text" name="domainSelect" size="12" maxlength="80"></td></tr>
<tr><td colspan="2" align="center"> <input type="submit" value=”login”></td></tr>
</table>
</form>
</body>
</html>
</code>
=== Login Page Elements ===
All Login Pages must contain certain elements. This section describes the necessary and optional elements of Login Pages for custom Login Page authors. The following table outlines the Login Page elements:
{|class="wikitable" border="1" style="background-color:#eeeeee;"
!Login Element
!Class
!Description
|-
|Login Form
|Required
|HTML Login form which provides entry into the enPortal system.
|-
|Browser Type Checking
|Optional
|Servlet/Javascript to determine minimum browser requirements.
|-
|Auto-Fill UserID and Domain
|Optional
|Functions to pre-fill the user and domain fields of the login form with most recent values.
|-
|Error Message
|Optional
|JSP/Javascript functions to read and display any error messages returned from Login process.
|}
=== Login Form ===
The login page must contain an HTML form with the parameters described in the following table:
{|class="wikitable" border="1" style="background-color:#eeeeee;"
!Parameter
!Value
|-
|Form method
|POST
|-
|Form action
|/enportal/servlet/pd (assuming this is on the same HTTP server, otherwise the full URL of the enPortal server plus this path must be listed as the action)
|-
|Hidden input
|<input name="login" type="hidden" value="yes">
|-
|UserID field
|name=”userid”
|-
|Password field
|name="password"
|-
|Domain field
|name=”domainSelect”
|}


=== Browser Type Checking ===


=== Browser Type Checking ===
If a client does not meed the minimum browser requirements the login page will redirect the client to <tt>/enportal/enPortalInvalidBrowser.jsp</tt>.
Optionally, the login form can utilize the built-in browser type and version checking that exists in the Presentation Toolkit. A client that does not meet the minimum browser requirements can be redirected to another page. By default, the login.jsp page redirects to an <tt>enPortalInvalidBrowser.jsp</tt> page. This page accesses the minimum IE and Netscape version information that is stored in the enPortal server. Custom Login Page authors also may wish to access this information in order to perform the appropriate
checking and redirection. The following JSP scriptlet retrieves the minimum versions required. This can be used in a JavaScript function to redirect to another page, if the browser does not meet the minimum standards:


This works in three parts with the default login pages. The first is to load the Edge JspConfigBean:


  <jsp:useBean id="JspConfigBean" scope="application" class="com.edgetech.util.config.JspConfig">
  <jsp:useBean id="JspConfigBean" scope="application" class="com.edgetech.util.config.JspConfig">
  <% config.getServletContext().setAttribute("JspConfigBean", JspConfigBean); %>
  <% config.getServletContext().setAttribute("JspConfigBean", JspConfigBean); %>
  </jsp:useBean>
  </jsp:useBean>
  <%
 
Then the default minimum versions are retrieved by the JSP:
 
  // get minimum versions from the Portal server
  float minIEVersion = JspConfigBean.getMinIEVersion();
  float minIEVersion = JspConfigBean.getMinIEVersion();
  float minNetscapeVersion = JspConfigBean.getMinNetscapeVersion();
  float minNetscapeVersion = JspConfigBean.getMinNetscapeVersion();
  %>
  float minChromeVersion = JspConfigBean.getMinChromeVersion();
 
And finally a check is performed to determine whether to redirect:


if ( ! ((isChrome && version < <%=minChromeVersion%>) || (isNav && version < <%=minNetscapeVersion%>) || (isIE && version < <%=minIEVersion%>)) ) {
...
} else {
    // The user is trying to use an unsupported version of IE or netscape.
    rootWindow.location.replace("<%=JSPUtilities.out(URLUtil.getPortalContext(), true)%>/enPortalInvalidBrowser.jsp");
}
Depending on the deployment it may be useful to remove this check, or make this check more explicit due to standard operating environment and/or applications used within the organization.


The above fields are included in the baseline login.jsp file.


=== Auto-fill ''User Name'' and ''Domain'' Fields ===


=== Auto-fill of the User ID and Domain Fields ===
{{Note|1=Modern browsers often will auto-fill forms on behalf of the user already making this section redundant. Also realize that even if the JSP auto-fill code is disabled the browser may still auto-fill forms. In the case of the browser auto-filling form fields it is necessary to modify the form inputs and specify the <tt>autocomplete="off"</tt> attribute.}}
Instead of providing a blank login form, it is possible to retrieve information about the last login from a client. The Login Page author can then pre-fill the login form with user and domain information. This information is obtained by a cookie that is set on the client browser that stores the user ID and Domain of the User (not the password). The name of the User cookie is enPortal_userid and the name of the Domain cookie is enPortal_domainid. While it is possible to retrieve this information in a number of methods, the default Login Page uses a utility class provided in enPortal’s Java API (com.edgetech.eportal.dispatch.DispatchUtilities). The following JSP scriptlet illustrates the use of this class for retrieval of the User and Domain fields. First, it checks for the User and Domain passed in on the request. If they are not present (possibly from an error or redirection), then the strings are set to null. Finally, the strings are normalized via the toHTMLString function. This code is present in the loginCommon.jsp file:


If a user has previously logged into AppBoard then it's possible for the server to retrieve the users ''User Name'' and ''Domain'' last used via cookies stored in the browser. This is implemented in the default JSP pages by first loading some utilities:


  <%@ page import="com.edgetech.eportal.util.*" %>
  <%@ page import="com.edgetech.eportal.util.*" %>
  <%@ page import="com.edgetech.eportal.dispatch.DispatchUtilities" %>
  <%@ page import="com.edgetech.eportal.dispatch.DispatchUtilities" %>
  <%@ page import="com.edgetech.eportal.web.JSPUtilities" %>
  <%@ page import="com.edgetech.eportal.web.JSPUtilities" %>
<%
 
Then doing some lookups and setting default values for the user and domain:
 
  // Lookup the UserID/Domain values from the cookie to pre-fill the login form
  // Lookup the UserID/Domain values from the cookie to pre-fill the login form
  String user = DispatchUtilities.getRequestAccessor().getUserName(request);
  String user = DispatchUtilities.getRequestAccessor().getUserName(request);
  String domain = DispatchUtilities.getRequestAccessor().getDomainName(request);
  String domain = DispatchUtilities.getRequestAccessor().getDomainName(request);
  if ( (domain == null) || domain.equals("null") ) {
  if ( (domain == null) || domain.equals("null") ) {
domain = "";
    domain = "";
  }
  }
  if ( (user == null) || user.equals("null") ) {
  if ( (user == null) || user.equals("null") ) {
user = "";
    user = "";
  }
  }
  user = JSPUtilities.toHTMLString(user);
  user = JSPUtilities.toHTMLString(user);
  domain = JSPUtilities.toHTMLString(domain);
  domain = JSPUtilities.toHTMLString(domain);
%>


=== Handling Errors ===


=== Error Message Display ===
In the event of an un-successful login attempt it should be indicated to the user. The JSP handles this by checking for error conditions on loading:
Authors creating custom Login Pages will most likely want to add code that processes login error messages. When a User unsuccessfully logs in, the enPortal process dispatcher returns a message, which can be displayed to the User. For example, if the User typed in an incorrect password, an error message would be returned. The dispatcher redirects the User back to the Login Page assigned to that Domain. In order for the User to see the error message, the Login Page must have code that looks for the error message. Otherwise, the Login Page will simply re-appear upon an unsuccessful login attempt. The request parameter error is populated by the text message of the error when an error occurs during login. This example shows a snippet of JSP code to check for the error message, and then some JavaScript code that pops up a message. The JavaScript code assumes that there is a form named loginForm. The JavaScript function error_checks() should be called on load of the page (in the body tag, using onLoad=‘error_checks()’ ):


String error_Text = request.getParameter("error");
if (error_Text == null)
{
    error_Text = (String) request.getAttribute("error");
}
if (error_Text == null)
{
    error_Text = "";
}


<code>[java,N]
Once the page loads there is a javascript call made to <tt>error_checks</tt>. This actually performs a number of checks including the minimum browser checks. If anything is in error then <tt>setErrorState</tt> is called to modify the style of the page to indicate an error condition.
<JSP Code>.
<% String error_Text = request.getParameter("error");
if (error_Text == null)
{
error_Text = (String) request.getAttribute("error");
} %>
<JavaScript code>….
function error_checks(myForm) {
// find top-level browser window where portal reside.
var rootWindow = cleanUpEnportalWindows(self);


var errorText = "<%=JSPUtilities.toHTMLString(error_Text)%>";
var errorTextEncoded = "<%=EnportalURLEncoder.encode(error_Text)%>";


// If browser is valid,
== Examples ==
  if ( ! ((isNav && version < <%=minNetscapeVersion%>) || (isIE && version < <%=minIEVersion%>)) ) {


// If we are activated in a page that is not the portal rootWindow
=== Custom Logo ===
if ( rootWindow == null)
        {  //this is to prevent IE problem when in Explorer and other channels that generate multiple portal rquests into different iframes that result in multiple login windows.  When this happens with an alert, then the window cannot be closed and user end up with two login pages, one in the root window and the other in the open window.
        }
        else if ( rootWindow != self ) {
var pageToLoad = location.protocol+"//"+location.host+"<%=JSPUtilities.out(URLUtil.getFullPDURI(), true)%>";


// pass along any error messages
The most common minimum change to the shipped login pages is to simply change the Edge logo:
if ( errorText != "" ) {
pageToLoad = pageToLoad + "?error=" + errorTextEncoded;
}


// Reload the root window.
# First make a new copy of an existing login page to start modifying.
rootWindow.location.replace(pageToLoad);
# All shipped login pages use a logo in the following location: <tt>images/logo.png</tt>.
# Create a new logo. The simplest way to go is to view the default logo to check the dimensions, and create a new image with the same dimensions with your new logo.
# Replace the logo.png with your new logo.
# Set the system login page to use your new login page.


} else {
// We are already displayed in the proper window (an portal root window)
// Notify user of any errors,
if ( errorText != "" ) {
setErrorState( true );
}


// and automate login form focus
=== Minimal Login Page ===
if ( myForm && myForm.userid) {
myForm.userid.focus();
myForm.password.value = "";
}
}


} else {
The most basic login page is a HTML form without using JSP, javascript, or images and styling. Of course this doesn't handle error checking or browser detection etc... but serves as an example of the minimum needed to write a completely custom login page:
// The user is trying to use an unsupported version of IE or netscape.
rootWindow.location.replace("<%=JSPUtilities.out(URLUtil.getPortalContext(), true)%>/enPortalInvalidBrowser.jsp");
}


}
<code>[html,N]
</code>
<html>
  <head>
    <title>Minimal Login Page</title>
  </head>
  <body>
    <h1>Minimal Login Page</h1>


    <form name="loginForm" method=post action="/enportal/servlet/pd">
      <input name="login" type="hidden" value="yes">


=== Hard-coding a Default Domain ===
      <table>
AppBoard/enPortal requires three elements for a User to successfully log in to the system: Username, Password, and Domain.  In some cases, all of the Users may be in a single Domain, and it may be a nuisance for the User to have to enter the Domain in order to log in.  In this case, you can pre-fill a Domain name in the login form, or even hide the field completely and just have the Login Page auto-submit the hard-coded value for everyone who submits a login request.
        <tr><td>User Name:</td> <td><input type="text" name="userid" size="28" maxlength="80"></td></tr>
 
        <tr><td>Password:</td> <td><input type="password" name="password" size="28" maxlength="80"></td></tr>
 
        <tr><td>Domain:</td> <td> <input type="text" name="domainSelect" size="28" maxlength="80"></td></tr>
Perform the following steps to hard-code a value in the Domain field in the login form:
        <tr><td colspan="2" align="center"> <input type="submit" value=”login”></td></tr>
# Open the Login Page jsp file for editing in a text editor.
      </table>
# Search for the following text in the login page:
    </form>
#* <tt><input type="text" id="domain" value="<%=domain%>" name="domainSelect"</tt>
  </body>
# Change "value=" to a hard-coded value.
  </html>
#* Example: <tt><input type="text" id="domain" value="CustomerName" name="domainSelect"</tt>
</code>
 
 
The above will force the default Domain to be “CustomerName” instead of whatever domain was last accessed (<%=domain%>).  To hide the field completely from view, change the input type from "text" to "hidden". You will want to hide the "Domain" label for the field also.
 


== Implementing a Custom Login Page ==
=== Setting a Default Domain ===


Once you have created a custom Login Page, implement the new Login Page by completing the following:
For implementations with a single Domain for all users the Domain field may add confusion so can be set to a particular value and even hidden.
# Place the Login Page in the appropriate location on the server.
#* <tt>[INSTALL_HOME]/webapps/enportal/login_pages/custom/[<i>loginpagename</i>].jsp</tt>
# Assign the Login Page to the system or individual Domain(s).
#* To assign to the entire system:
#** Log in to enPortal/Appboard as the administrator.
#** Go to the enPortal admin URL: <tt>http://<<i>hostname</i>>:<<i>port</i>>/enportal/home#</tt>.
#** Mouse over "Advanced" and select "Explore System".
#** Right-click "Explorer" and select "System Login Page".
#** Enter the relative path/name of the Login Page to use.
#*** Example: <tt>custom/myloginpage.jsp</tt>
#* To specifying a default Login Page for a Domain:
#** Select the Domain for which you would like to specify a default Login Page.
#** Log in to enPortal/Appboard as the administrator.
#** Go to the enPortal admin URL: <tt>http://<<i>hostname</i>>:<<i>port</i>>/enportal/home#</tt>.
#** Click the "Users" tab.
#** Right-click the Domain name and select "Edit".
#** Under "Default Login Page", enter the relative path/name of the Login Page to use.
#*** Example: <tt>custom/myloginpage.jsp</tt>
#** Click "Save".


# First make a new copy of an existing login page to start modifying.
# Edit <tt>login.jsp</tt>
## find the line line with: <tt><input type="text" id="domain" ...</tt>
## modify the <tt>value</tt> from a JSP variable to the desired value, such as:
##: <tt><input type="text" id="domain" value="'''myDomain'''" ...</tt>
# Set the system login page to use your new login page.


{{Note|If a Login Page is assigned to a Domain, a User in that Domain will need to log in and log out once to that Domain to set the cookie that will provide that custom Login Page the next time that User logs in.}}
In addition, if this field should be completely hidden then change the <tt>type</tt> attribute from <tt>text</tt> to <tt>hidden</tt>. In this case though some additional HTML and/or CSS changes may be necessary to improve the aesthetic of the form.

Latest revision as of 10:24, 17 July 2014

Overview

This document provides some examples of modifying and producing completely custom login pages for AppBoard. For more general information about login pages and how to configure the system login page, refer to the Login Page documentation.

By default the different login page styles shipped with AppBoard are simple HTML forms that allow the user to enter the required information, and then POST it to the server so the server can authenticate and establish a session.

Typical customizations are:

  • simply changing the logo graphic
  • various styling changes (colours, fonts, etc...)
  • addition of notices or terms & conditions
  • hiding the Domain field for single-domain implementations
  • making the Domain field a drop-down


Required Fields and Submission

The following fields are required to log into AppBoard:

  • login: set to yes. Typically this is a hidden field
  • userid: This would be a visible field to allow a user to enter their user name.
  • password: This would be a visible password field to allow a user to enter their password.
  • domainSelect: Another text input to allow a user to enter their domain.

The form is then POSTed to: /enportal/servlet/pd. Using GET is also possible but not recommended as all all requests are logged and get requests include all parameters, which means user passwords would also get logged.

Included Login Pages

The login pages shipped with AppBoard all follow the same structure. A main login.jsp Java Server Page which performs browser version checking, auto-fills previous values, handles error responses, presents a HTML form for the user to complete. Along with the JSP there will be other supporting images and CSS resources.


Browser Type Checking

If a client does not meed the minimum browser requirements the login page will redirect the client to /enportal/enPortalInvalidBrowser.jsp.

This works in three parts with the default login pages. The first is to load the Edge JspConfigBean:

<jsp:useBean id="JspConfigBean" scope="application" class="com.edgetech.util.config.JspConfig">
<% config.getServletContext().setAttribute("JspConfigBean", JspConfigBean); %>
</jsp:useBean>

Then the default minimum versions are retrieved by the JSP:

// get minimum versions from the Portal server
float minIEVersion = JspConfigBean.getMinIEVersion();
float minNetscapeVersion = JspConfigBean.getMinNetscapeVersion();
float minChromeVersion = JspConfigBean.getMinChromeVersion();

And finally a check is performed to determine whether to redirect:

if ( ! ((isChrome && version < <%=minChromeVersion%>) || (isNav && version < <%=minNetscapeVersion%>) || (isIE && version < <%=minIEVersion%>)) ) {
...
} else {
    // The user is trying to use an unsupported version of IE or netscape.
    rootWindow.location.replace("<%=JSPUtilities.out(URLUtil.getPortalContext(), true)%>/enPortalInvalidBrowser.jsp");
}

Depending on the deployment it may be useful to remove this check, or make this check more explicit due to standard operating environment and/or applications used within the organization.


Auto-fill User Name and Domain Fields

Template-note.png
Modern browsers often will auto-fill forms on behalf of the user already making this section redundant. Also realize that even if the JSP auto-fill code is disabled the browser may still auto-fill forms. In the case of the browser auto-filling form fields it is necessary to modify the form inputs and specify the autocomplete="off" attribute.

If a user has previously logged into AppBoard then it's possible for the server to retrieve the users User Name and Domain last used via cookies stored in the browser. This is implemented in the default JSP pages by first loading some utilities:

<%@ page import="com.edgetech.eportal.util.*" %>
<%@ page import="com.edgetech.eportal.dispatch.DispatchUtilities" %>
<%@ page import="com.edgetech.eportal.web.JSPUtilities" %>

Then doing some lookups and setting default values for the user and domain:

// Lookup the UserID/Domain values from the cookie to pre-fill the login form
String user = DispatchUtilities.getRequestAccessor().getUserName(request);
String domain = DispatchUtilities.getRequestAccessor().getDomainName(request);
if ( (domain == null) || domain.equals("null") ) {
    domain = "";
}
if ( (user == null) || user.equals("null") ) {
    user = "";
}
user = JSPUtilities.toHTMLString(user);
domain = JSPUtilities.toHTMLString(domain);

Handling Errors

In the event of an un-successful login attempt it should be indicated to the user. The JSP handles this by checking for error conditions on loading:

String error_Text = request.getParameter("error");
if (error_Text == null)
{
    error_Text = (String) request.getAttribute("error");
}
if (error_Text == null)
{
    error_Text = "";
}

Once the page loads there is a javascript call made to error_checks. This actually performs a number of checks including the minimum browser checks. If anything is in error then setErrorState is called to modify the style of the page to indicate an error condition.


Examples

The most common minimum change to the shipped login pages is to simply change the Edge logo:

  1. First make a new copy of an existing login page to start modifying.
  2. All shipped login pages use a logo in the following location: images/logo.png.
  3. Create a new logo. The simplest way to go is to view the default logo to check the dimensions, and create a new image with the same dimensions with your new logo.
  4. Replace the logo.png with your new logo.
  5. Set the system login page to use your new login page.


Minimal Login Page

The most basic login page is a HTML form without using JSP, javascript, or images and styling. Of course this doesn't handle error checking or browser detection etc... but serves as an example of the minimum needed to write a completely custom login page:

[html,N]

<html>
  <head>
    <title>Minimal Login Page</title>
  </head>
  <body>

Minimal Login Page

    <form name="loginForm" method=post action="/enportal/servlet/pd">
      <input name="login" type="hidden" value="yes">
User Name: <input type="text" name="userid" size="28" maxlength="80">
Password: <input type="password" name="password" size="28" maxlength="80">
Domain: <input type="text" name="domainSelect" size="28" maxlength="80">
<input type="submit" value=”login”>
    </form>
  </body>
</html>

Setting a Default Domain

For implementations with a single Domain for all users the Domain field may add confusion so can be set to a particular value and even hidden.

  1. First make a new copy of an existing login page to start modifying.
  2. Edit login.jsp
    1. find the line line with: <input type="text" id="domain" ...
    2. modify the value from a JSP variable to the desired value, such as:
      <input type="text" id="domain" value="myDomain" ...
  3. Set the system login page to use your new login page.

In addition, if this field should be completely hidden then change the type attribute from text to hidden. In this case though some additional HTML and/or CSS changes may be necessary to improve the aesthetic of the form.