Sun Identity Manager Service Provider 8.1 Deployment

Chapter 7 Implementing Custom User Pages

The sample user pages follow the Model-View-Controller design pattern. The Apache Struts Action framework provides navigation between the pages, while the Struts/Tiles templating framework is used to create common look and feel for the application. For information about Struts, see http://struts.apache.org/.

The following diagram shows how a typical request is handled in the sample end-user pages.

How a Typical Request is Handled in Sample End-user Pages

Figure 7–1 Flow of a request made within the sample end-user pages.

Request Flow on the Sample End-User Pages

  1. The client requests a page. The servlet container invokes the authentication filter. The filter handles authentication and ensures that protected pages can only be accessed after successful authentication. If a client attempts to access a protected page without proper authentication, the filter redirects the client to the login page.

  2. The Struts ActionServlet receives the request and acts according to the directions in the Struts configuration file.

  3. For pages backed by Identity Manager forms, the Struts ActionServlet invokes the ProcessFormAction. The ProcessFormAction class is a Struts Action implementation and serves as an adapter to the forms engine. The action specifies the Identity Manager form class (page processor), the view handler, and the custom form.

  4. The Struts ActionServlet may redirect the client in case the ProcessFormAction returns an ActionForward other than “success”. When a page first displayed, the “success” forward is followed.

  5. The HTML content is generated with the help of the Tiles templating framework.

  6. The generated HTML is passed back to the ActionServlet.

  7. The authentication filter receives the content, but it does not alter it in any way.

  8. The generated HTML page is returned to the client.

Authentication and Authorization

The Service Provider Authentication/Authorization servlet filter serves as the default authentication system for the sample user pages. This filter ensures that protected pages can only be accessed after successful authentication. If a client attempts to access to a protected page without proper authentication, the filter would redirect the client to the login page.

Authentication is executed when the user clicks the login button on the login page. The filter attempts to authenticate the user by authenticating the user against the Service Provider directory with the provided credentials. During this process, the system verifies credentials and also determines whether the user’s profile has been locked due to multiple login attempt failures. If the profile is locked, then access is denied to the self-service pages and the appropriate error message is displayed.

Pages that require authentication can be accessed using a different path than pages that can be accessed anonymously. This protected path is a configuration option of the filter.

Because pages that require authentication are accessible using a different path than anonymous pages, protecting these pages are easy to configure in any access management system. The sample user pages do not depend on a particular type of authentication nor do they require the password anywhere but in the filter. The sample pages only require the user name for auditing purposes.

When authentication successfully completes, the filter puts the Constants.VAR_SUBJECT variable into the session with the user name as the value. To access pages that require authentication, the subject must be present in the session. When the user logs out of the self-service pages, the session is invalidated. The session timeout configured for the application defines how long the user can be inactive without being “logged out”.

Configuring the Filter

The $WSHOME/WEB-INF/web.xml file contains the definition the Service Provider Authentication/Authorization filter. This filter handles authentication and ensures that protected pages can only be accessed after successful authentication. If a client attempts to access to a protected page without proper authentication, the filter would redirect the client to the login page.

The Service Provider Authentication/Authorization filter defines the following parameters. Note that the parameters that specify a directory or page must include the path to the web application.

Name 

Default Value 

Description 

protected-pages-path 

/spe/user/protected 

The full path for pages that require authentication. Pages that do not require authentication should not be placed in this directory. 

login-page 

/spe/user/Login.do 

The full path to the login page where the user is redirected when attempting to access a protected page without proper authentication. 

profile-locked-page 

/spe/user/ProfileLocked.do 

The full path to the page that is displayed when a user attempts to login while the account is locked. 

profile-has-been-locked-page 

/spe/user/ProfileHasBeenLocked.do 

The full path to the page that is displayed when a user exceeds the maximum number of failed login attempts. 

preserve-query-string 

true 

Indicates whether to preserve the query string when a user is redirected to the login page. The allowed values are true or false. 

See Account and Password Policies for information about implementing lockout policies in Service Provider.

Specifying Protected and Public Pages

The protected-pages-path parameter in the web.xml file specifies the directory in which pages that need authentication must reside. Public pages must reside in a different location.

The following pages are provided in the $WSHOME/spe/user/protected directory by default.

Other customized files may be added to this directory.

See Specifying an Action Path for more information about implementing authentication with the default authentication filter.

Integrating with Access Manager

The AuthFilter can also be configured to work in an environment with an access management solution, such as the Sun Java System Access Manager. In these environments, Service Provider is not responsible for logging in the user because the access management solution is used to protect the end user pages.

The normal login process places the user name into the HTTP session. But when the normal process is not used, Service Provider requires the access management solution to put the username in a configured HTTP header before forwarding the HTTP request.

Two configuration attributes in the SPEUserPages configuration object control how the Service Provider end user pages work in this environment.

See SPEUserPages Configuration Object for more information.

For Sun Java System Access Manager, to ensure that the header is set, edit the AMAgent.properties file to include entries similar to the following:

com.sun.identity.agents.config.profile.attribute.fetch.mode = HTTP_HEADER
com.sun.identity.agents.config.profile.attribute.mapping[uid] = HEADER_speuid

Assuming users login with the uid attribute, the Access Manager Policy Agent will store the uid value in the HEADER_idmuid HTTP header before forwarding requests to the Service Provider User Interface pages.

Integrating with Other Access Management Systems

You can use a third-party access management access system to perform the authentication/authorization instead of the provided filter and still leverage the self-service features of the sample pages. The integration is the easiest if the access management system can provide the name of the authenticated user in the HTTP request header. In this case, steps similar to the Integration with Access Manager can be followed.

If providing the name of the authenticated user in the HTTP request header is not possible, then the following guidelines should be followed to enhance or replace the provided filter:

Struts Configuration File

Apache Struts drives the navigation between the sample User Interface pages. The Struts configuration file ($WSHOME/WEB-INF/spe/config/struts-config.xml ) defines all the navigation rules in the form of Struts action definitions. Action definitions typically contain path, type, and parameter attributes. Many definitions also contain one or more forward elements that indicate which page should be displayed next.

Specifying an Action Path

Pages that require authentication must specify the protected path in the path attribute of the appropriate action definition. For example, the following action definition for the ChangePassword page includes the same path specified in the protected-pages-path parameter in the web.xml file.

<action path="/spe/user/protected/ChangePassword" type="com.sun.idm.idmx.web.SelfServiceProcessFormAction" ...>

The login page does not require the user to be authenticated, so the path of the corresponding action does not include the protected directory:

<action path="/spe/user/Login" type="com.sun.idm.idmx.web.ProcessFormAction" ...>

Specifying an Action Type

The type parameter defines the class that performs the action. Some of the default actions refer to a Struts-defined subclass of the org.apache.struts.action.Action class. The following subclasses are provided with the sample user pages.

Class Name 

Description 

ProcessFormAction 

Allows access to the Identity Manager forms engine. This action can take a view handler class, a form name, and a page processor class (in that order) as parameters. See Specifying an Action Type for more information.

SelfServiceProcessFormAction 

A subclass of ProcessFormAction that is used for self-service operations, such as changing passwords or user IDs. 

RelayAction 

Redirects the client to a page after the user has acknowledged a successful operation result, such as a successful password change. Since all confirmation pages use a single content tile (OperationResult.jsp), an action forward name is set in a hidden field when the content tile is generated. See OperationResult Relay Definition for more information.

LogoutAction 

Invalidates the current user session. 

Specifying Action Parameters

The parameter attribute defines arguments that are passed to the class specified in the type attribute. If the type attribute is ProcessFormAction or SelfServiceProcessFormAction class, then the value may contain the following options, none of which are mandatory. The options must be specified in the order listed and be separated by commas.

  1. The viewer class, such as IDMXUser or IDMXLookupUsername.

  2. The form name or ID.

  3. The page processor class.

    Each of these options are described below.

    If the action type is a class other than ProcessFormAction or SelfServiceProcessFormAction, then the value specified in the parameter attribute must match the requirements of the class.

  4. The string secure.

    This parameter is optional. If it is specified, the server always processes page requests using HTTPS.

Viewer Classes

The following viewer classes may be specified if the type attribute is ProcessFormAction or SelfServiceProcessFormAction class:

Forms

The form argument may contain a form defined in Identity Manager. If no form is specified, viewer class uses the default form.

Page Processors

The default page processor is com.waveset.ui.util.GenericEditForm class. The IDMXUserForm class, a subclass of GenericEditForm , is a custom page processor that allows sending email notifications. Email notifications can be enabled or disabled for each in the sample end user pages. In turn, the IDMXUserForm has the following subclasses:

Subclass 

Description 

ChangeAuthenticationAnswersForm 

If email notification is enabled and the authentication answers have been successfully updated, then an email is sent to the user using the “Service Provider End-User Authentication Answers Updated” template. The class also records an appropriate audit event. 

ChangeNotificationsForm 

If email notification is enabled and the notification address has been successfully updated, then emails are sent to both the old and the new address using “Service Provider End-User Change Notifications” and “Service Provider End-User Change Notifications Old Address” template respectively. The class also records an appropriate audit event. 

ChangePasswordForm 

If email notification is enabled and the password has been successfully changed, then an email is sent to the user using the “Service Provider End-User Change Password” template. The class also records an appropriate audit event. 

ChangeUserIdForm 

If email notification is enabled and the user name has been successfully changed, then an email is sent to the user using the “Service Provider End-User Change User Id” template. The class also records an appropriate audit event. 

EnrollmentForm 

If email notification is enabled and registration has been successfully completed, then an email is sent to the user using the template “Service Provider End-User Registration Template”. 

ResetPasswordForm 

If the password.reset-mode attribute in the SPEUserPages object is set to self, then when the user answers all the required authentication questions, the password is reset with this class.

The following table lists the additional subclasses of GenericEditForm.

Subclass 

Description 

UserQuestionForm 

This page processor class is used when the user forgets his password and attempts to login using authentication questions. If email notification is enabled and authentication questions has been successfully answered, then an email is sent to the user using the template “ 

LoginForm 

LoginForm adds the errors the AuthFilter encountered to the login page. 

In the following example, a view handler and a custom form are specified, but no page processor class is set. (The default GenericEditForm class processes this page.)

<action path="/spe/user/ForgotUsername"
type="com.sun.idm.idmx.web.ProcessFormAction"
parameter="IDMXLookupUsername,#ID#UserForm:IDMXForgotUsernameForm,">

The following example shows an action with a view handler (IDMXUserQuestion ) and a page processor (UserQuestionForm) specified, but no form name was given. The view handler will use the default form:

<action path="/spe/user/LoginWithQuestions"
type="com.sun.idm.idmx.web.ProcessFormAction"
parameter="IDMXUserQuestion,,com.sun.idm.idmx.web.UserQuestionForm">

Secure Connections

The secure parameter forces the server to use HTTPS regardless of the last action's response. Add this parameter as the fourth parameter to force the action to use HTTPS:

<action path="/spe/user/Login" type="com.sun.idm.idmx.web.ProcessFormAction"
parameter="IDMXNoop,#ID#UserForm:IDMXLoginForm,com.sun.idm.idmx.web.LoginForm,secure">
        <forward name="success" path=".page.Login"/>
        <forward name="post" path="/spe/user/Login.do" />
        <forward name="next" path="/spe/user/protected/Home.do?newView=true" />
        <forward name="cancel" path="/spe/user/Login.do" />
</action>

If your servers do not use port 80 for HTTP or port 443 for HTTPS, modify WEB-INF/web.xml to include the following context parameters:

<context-param>
    <param-name>listenPort_http</param-name>
    <param-value>7001</param-value>
</context-param>

<context-param>
    <param-name>listenPort_https</param-name>
    <param-value>7002</param-value>
</context-param>

The above code sample tells Struts to use port 7001 for HTTP and port 7002 for HTTPS.

Assigning Navigation Logic

The forward elements in the action definitions tie the sample pages together. The following table lists the most commonly used forward definitions:

Name 

Description 

success 

Specifies the page to display if there is no error processing the action. 

post 

Posts the form to the specified location. 

next 

Specifies the action to take after a successful form posting,. 

cancel 

Specifies the action to take if a user clicks a cancel button on a form. 

SPEUserPages Configuration Object

The following table lists the major attributes in the SPEUserPages configuration object. Edit this object to change when to send notification emails, how to handle password resets, or integrate the user pages with Access Manager or similar product.

Attribute 

Description 

enrollment 

Controls enrollment options. This attribute contains the following subattributes: 

  • validation.enabled— If true, the validation page is displayed and the user must verify his relationship with the provider. The default is true.

  • privacypolicy— If true, the user must accept the privacy policy before completing the registration. The default is true.

lookup-attributes 

A list of attributes that are used to retrieve a user’s ID or password. By default, the user’s homephone and email attributes are used, but any attribute defined as an Identity System User Attribute in the schema map for the resource may be used.

This attribute contains the following subattributes: 

  • name— The name of the attribute to use to look up the user.

  • title— The message key of the title to display for the lookup user form.

  • required— A boolean indicating whether the attribute is required in the lookup user form.

notification 

Indicates when an e-mail notification should be sent to the user. This attribute contains the following subattributes. The possible values for these subattributes are true and false.

The notification values are 

  • emailchange

  • lockout

  • passwordchange

  • questionchange

  • recovery

  • registration

  • useridchange

password 

Specifies how password resets should be handled. This attribute contains the password-reset subattribute, which must be set to one of the following values:.

  • self— The user can reset his or her password if all the challenge questions have been answered correctly

  • notification— The user is sent a temporary password to the notification address if all the challenge questions have been answered correctly.

sso-assume-authenticated 

If set to true, the AuthFilter will not redirect to a login page. However, for auditing purposes, the filter requires a user name to associate with each request. Normally, this username is stored on the HTTP session by the login pages. However, since the login pages are not used in an SSO environment, the username is pulled from an HTTP header attribute.

sso-user-name-http-header-attr 

Specifies the name of the HTTP header attribute to use. 

The following table lists the default values of the notification attribute and its corresponding email template. The email templates can be edited from the Identity Manager Administration Interface, but the preferred method of changing the subject and body of the email is to modify the messages in the IDMXMessages.properties file to the desired text.

Notification Value 

Email Template 

emailchange 

Service Provider End-User Change Notifications 

Service Provider End-User Change Notifications Old Address 

lockout 

Service Provider End-User Profile Locked 

passwordchange 

Service Provider End-User Change Password 

passwordreset 

Service Provider End-User Password Reset 

questionchange 

Service Provider End-User Authentication Answers Updated 

recovery 

Service Provider End-User Username Recovery 

registration 

Service Provider End-User Registration Template 

useridchange 

Service Provider End-User Change User Id 


Note –

For the emailchange option, notification is sent to both the new and old e-mail addresses.


Using Apache Struts to Create User Pages

The Service Provider User Interface pages are constructed using the Tiles component of the Apache Struts Framework.

One approach to separating layout from content is the use of dynamic JSP includes. The Tiles framework uses a more advanced form of the JSP include action. In a Tiles application, the layout template usually defines the position of a header, menu, body content, and footer. Other pages are then included to fill each of these positions. Tiles makes using template layouts easier through the use of a simple tag library.

Technically, a tile is a rectangular region in a JSP. A tile may be assembled from other tiles, creating a tree-like hierarchy. A tile can accept variable information at runtime in the form of attributes, making it parameterizable. Tile attributes are defined when inserting the tile and are visible within the tile only. They are not visible in subtiles or to a page enclosing the tile.

Layout Template

In Service Provider, the primary layout template is defined in $WSHOME/spe/user/common/layouts/page.jsp .

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<html:html>
   <head>
      <title><bean:write name="title" filter="off"/></title>
      <html:base/>
   </head>
   <body>
      <tiles:insert name="masthead"/>
      <tiles:insert name="navbar"/>
      <tiles:insert name="subnavbar"/>
      <tiles:insert name="content"/>
      </body>
</html:html>

This simple layout template indicates that the body of the page is built from four tiles: masthead, navbar, subnavbar, and content. Each tile corresponds to a JSP file in the $WSHOME/spe/user/common/tiles directory.

Tiles Definitions

A JSP template system uses one template for the layout and another for the fill-in components. Tiles calls these layout files “definitions”. To avoid creating an extra file just to specify the layout, Tiles allow the layout definitions to be stored as a JavaBean. For Service Provider, these definitions are declared in the following XML configuration files, located in the $WSHOME/WEB-INF/spe/config directory:

These definitions files are specified in the deployment descriptor file, $WSHOME/WEB-INF/web.xml:

<init-param>
   <param-name>definitions-config</param-name>
   <param-value>/WEB-INF/spe/config/tiles-tab-defs.xml,
                /WEB-INF/spe/config/tiles-nav-defs.xml,
                /WEB-INF/spe/config/tiles-page-defs.xml</param-value>
</init-param>

The following example shows the base definition for a Service Provider page, as defined in tiles-page-defs.xml:

<definition name=".page.Base" path="spe/user/common/layouts/page.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizePageTitles">
   <put name="page_title_key" value="${page_title_key}" />
   <put name="masthead" value="spe/user/common/tiles/masthead.jsp" />
   <put name="navbar"   value="${navbar}" />
   <put name="left_nav" value="spe/user/common/tiles/left_nav.jsp" />
   <put name="content"  value="${content}" />
   <put name="footer"   value="spe/user/common/tiles/footer.jsp" />
</definition>

The attributes passed into this definition may consist of message resource bundle keys, like page_title_key, or references (directly or indirectly) to other tiles inserted on the page.

A tile definition may include a controller class. This class may access tile attributes from the context before the tile is rendered. In Service Provider, the controller class looks up the appropriate page title or subtitle from the message resource bundle based on the key passed as a tile attribute. The Struts framework uses a locale-specific resource bundle, if it exists.

Adding a New Page

The following example extends the Base definition and uses a custom JSP named my_page.jsp to render the content tile. It renders content appropriate for the for a JSP named my_page.jsp:

<definition name=".page.MyPage" extends=".page.Base">
   <put name="page_title_key" value="message.my_page_title" />
   <put name="navbar" value=".nav_bar.MyPage" />
   <put name="content" value="/pages/my_page.jsp" />
</definition>

The rendered page consists of content from the masthead, navbar and content tiles. The content tile contains the output from my_page.jsp. (Even though the Base page tile definition contains references to the left-hand and “footer” tiles, these do not appear on the rendered page because they are not included in the page.jsp layout template.) The localized title string will be rendered in the browser’s title bar.

The definition name (.page.MyPage) can be referenced in a Struts ActionForward in the same manner as a regular file URI. Slashes can be used in a definition name, but by best practice convention, a period is used as a delimiter to distinguish the tiles definitions from file URIs, such as "/spe/user/Login.do".

Updating the Navigation Bar

Once you have defined a new page to be added to the Service Provider User Interface, you must add a button to the navigation bar so that users can access the new page.

The navigation and subnavigation bars are implemented with tab-style buttons created from tiles. The JSP for a tab button outputs an HTML fragment consisting of a single table cell. The cell contains the localized text and optional hyperlink for the tab.

The following example lists the base definition for an unselected navigation button:

<definition name=".nav_tab.Base"       path="spe/user/common/tiles/nav_tab.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizeButtonLabel">
   <put name="button_link" value="${button_link}" />
   <put name="button_label_key" value="${button_label_key}" />
   <put name="link_class" value="Tab1Lnk" />
</definition>

The first two attributes are the message resource bundle keys associated with the text displayed within the button and the URI of the hyperlink for that text. The remaining attributes are the style sheet classes that give the button its appearance.

The base definition for a selected navigation button requires different style sheet classes. These classes must specify a different background color to indicate the tab has been selected and deactivate the hyperlink in the button text.

The following example lists the base definition for a selected navigation button:

<definition name=".nav_tab_selected.Base"       path="spe/user/common/tiles/nav_tab_selected.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizeButtonLabel">
   <put name="button_label_key" value="${button_label_key}" />
   <put name="text_class" value="Tab1SelTxtNew" />
   <put name="button_class" value="Tab1TblSelTd" />
</definition>

To create the definitions for the new button in each state, extending the base definitions as follows:

<definition name=".nav_tab_selected.MyPage"
       extends=".nav_tab_selected.Base">
   <put name="button_text" value="My Page" />
</definition>
<definition name=".nav_tab.MyPage" extends=".nav_tab.Base">
   <put name="button_link" value="/spe/user/MyPage.do" />
   <put name="button_text" value="My Page" />
</definition>

The individual button tiles can be combined together into a new tile for the navigation bar itself. To do this, pass a list of button tiles to the following base navigation bar definition:

<definition name=".nav_bar.Base"
       path="spe/user/common/tiles/nav_bar.jsp">
   <put name="div_class" value="Tab1Div" />
   <put name="context_class" value="Tab1TblNew" />
</definition>

Use the following example to define a list of buttons that will appear in the navigation bar for the new page:

<definition name=".nav_bar.MyPage" extends=".nav_bar.Base">
   <putList name="tab_list" >
      <add value=".nav_tab.Home" />
      <add value=".nav_tab.Profile" />
      <add value=".nav_tab_selected.MyPage" />
   </putList>
</definition>

The JSP that renders the navigation bar (spe/user/common/tiles/nav_bar.jsp ) loops through this list of buttons and includes the appropriate tile, passing attributes specific to that button. (The attributes can include the hyperlink, button text, style class, etc.).

To force the new button to appear in the navigation bar on other pages, you must add the (non-selected) definition to each page-specific navigation bar definition. For example, to add our new button to the navigation bar on the home page:

<definition name=".nav_bar.Home" extends=".nav_bar.Base">
   <putList name="tab_list" >
      <add value=".nav_tab_selected.Home" />
      <add value=".nav_tab.Profile" />
      <add value=".nav_tab.MyPage" />
   </putList>
</definition>

Tag Library

The following custom tags may be used in the user pages:

counter— A counter that is incremented by one every time the tag is called during a request. This tag is only used in the masthead, navigation bar, and the navigation button tiles. You may specify the value attribute to set the initial value of the counter. For example, to reset the counter, counter value=”1”.

generateForm— Displays the content produced by the page processor. This tag may be used in content-based tiles, such as those used in Form.jsp.

Tracing Struts Messages

Messages from Struts can be logged by enabling the Identity Manager trace feature and specifying trace levels for the org.apache.struts package, or any of its subclasses/subpackages. Struts logging does not allow configuring the names of specific methods that should be logged, and this level of configuration will be ignored.

Changing the Appearance of Service Provider End User Pages

The Apache Struts Action framework provides navigation between the pages, while the Struts/Tiles templating framework is used to create common look and feel for the application.

Modifying the Layout

The Service Provider User Interface pages implement the Apache Struts Action framework and Tiles to control page layout. The file $WSHOME/spe/user/common/layouts/page.jsp is used as a template when pages are rendered, with various regions of the page corresponding to the output of individual JSPs or tiles. The default page template consists of four tiles:

Adding a new tile, for example a “footer” at the bottom of the page, is accomplished by defining the tile in $WSHOME/WEB-INF/spe/config/tiles-page-defs.xml and then inserting the tile in page.jsp:

<body class="DefBdy" onload=’checkFirst( );’>
   <tiles:insert attribute="masthead" ignore="true"/>
   <tiles:insert attribute="navbar" ignore="true"/>
   <tiles:insert attribute="subnavbar" ignore="true"/>
   <tiles:insert attribute="content"/>
   <tiles:insert attribute=”footer” ignore=”true”/>
</body>

Placement of the tile on the rendered page can be controlled via HTML markup in the page template and/or via CSS. A template tile for a page footer is located at $WSHOME/spe/user/common/tiles/footer.jsp.

Another page which users will frequently want to modify is the login page. This page consists of a single tile, content, whose source JSP is $WSHOME/spe/user/Login.jsp. The actual HTML <FORM> is generated as an Identity Manager form, but it is wrapped in content from Login.jsp.

The page.jsp file includes three CSS stylesheet files:

The first two stylesheets are the system defaults and should not be modified, as they may be rewritten during upgrades. The customStyle.css stylesheet is empty and is intended for user custom CSS styles. These files are all located in $WSHOME/spe/user/common/layouts/styles/.

The Service Provider User pages are designed so that rebranding the page can be accomplished by modifying CSS styles, rather than JSPs. For example, the product name logo (Java System Identity Manager Service Provider) image in the masthead is specified by the following CSS definition:

td.MstTdTtlProdNam {
   background: url(../images/ProductName.png) no-repeat 10px 30px;
   padding:10px 10px 0px 10px;
   vertical-align:top;
   white-space:nowrap;
   height: 75px;
   width: 520px;
}

You can override this definition in customStyle.css to point to a different image file or specify a different location. For more information about using CSS to change user interface elements in Identity Manager, see Deployment Guide.

Internationalization and Localization

Service Provider uses a standard Java message resource bundle for display strings in the UI. This resource bundle is normally included in the idmspe.jar file and must be extracted if you plan to customize message strings for display in the default en_US locale.

$ cd $WSHOME/WEB-INF/classes
$ jar xvf ../lib/idmspe.jar com/sun/idm/idmx/msgcat/IDMXMessages.properties

The format of the resource bundle is the standard key =value format. In the example page.title.home=Home , page.title.home is the key and Home is the value associated with the key. The value string may be parameterized as standard java.text.MessageFormat strings.

There are two types of message keys in the resource bundle: those used by Struts/Tiles and those used by the Identity Manager forms engine. Keys recognized by Struts/Tiles will NOT be recognized by the Identity Manager forms engine, and vice versa.

Struts/Tiles message keys use the “dot notation” format, such as page.title.home. Message keys for the Identity Manager forms engine and for email notification templates must contain an underscore character and no spaces, such as IDMX_login_field_username. For more information on using the Identity Manager forms engine keys, see Deployment Guide.

For locales other than en_US, the resource bundle file contains the same key values as the default file and appropriate value string translations. For example, the message resource bundle strings for the fr_FR locale would go in $WSHOME/WEB-INF/classes/com/sun/idm/idmx/msgcat/IDMXMessages_fr_FR.properties .

Localization and Email Templates

Message bundle keys may also be used in email templates. The default Service Provider End-User email templates are stored in the repository and have IDs similar to #ID#EmailTemplate:SPEEndUserChangePassword . Message bundle keys may be specified for the email subject and body of the message:

<!-- The template used when user changes their password. -->
<EmailTemplate id=’#ID#EmailTemplate:SPEEndUserChangePassword’
name=’Service Provider End-User Change Password’ 
displayName=’UI_EMAILTEMPLATE_SPE_END_USER_CHANGE_PASSWORD’
smtpHost=’$(smtpHost)’ fromAddress=’admin@example.com’>

   <subject>IDMX_change_password_email_subject</subject>
   <body>IDMX_change_password_email_body</body>
   <MemberObjectGroups>
      <ObjectRef type=’ObjectGroup’ name=’All’/>
   </MemberObjectGroups>
</EmailTemplate>

Note that message bundle keys used in email templates MUST contain an underscore character to be recognized as a message key.

Localizing Strings in the Navigation Bars and Page Titles

Strings that appear in the horizontal navigation bars and browser title are handled by the Struts framework and are referred to by message keys in the resource bundle which use the “dot notation” naming convention.

For example, to change the subnavigation tab for “Password” (under the “My Profile” tab) to use the string “My Password” we must first look up the message bundle key. This is defined in $WSHOME/WEB-INF/spe/config/tiles-tab-defs.xml :

<!-- Unselected sub-navigation tab for changing the user’s password -->
<definition name=".subnav_tab.Password" extends=".subnav_tab.Base">
   <put name="button_link" value="/spe/user/protected/ChangePassword.do?newView=true" />
   <put name="button_label_key" value="nav.tab.label.password" />
</definition>

In this case, the message bundle key nav.tab.label.password is used for the (en_US) string “Password” which will appear as the tab label text. See above for how to extract and modify the message resource bundle file.

Note that the above Tile definition extends a definition called .subnav_tab.Base , which is defined as follows:

<!-- Base type for unselected sub-navigation tabs -->
<definition name=".subnav_tab.Base" path="/spe/user/common/tiles/subnav_tab.jsp" 
controllerClass="com.sun.idm.idmx.web.LocalizeButtonLabel">
   <put name="button_link" value="${button_link}" />
   <put name="button_label_key" value="${button_label_key}" />
   <put name="link_class" value="Tab2Lnk" />
</definition>

We are passing the parameter ${button_label_key} a specific value of “nav.tab.label.password” in the .subnav_tab.Password definition. The base tile definition has a controller class associated with it called com.sun.idm.idmx.web.LocalizeButtonLabel . The purpose of this controller class is to take the value of parameters passed to it, like button_label_key, look them up in the message bundle and put the resulting string back into the Tiles context so that they may be referred to in the rendering Tile. The JSP which renders an unselected subnavigation bar tab, subnav_tab.jsp, looks like:

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<%@ taglib uri="/tags/spe" prefix="spe" %>
<tiles:useAttribute name="button_link"/>
<tiles:useAttribute name="button_text"/>
<tiles:useAttribute name="link_class"/>
<td><a href="<%=request.getContextPath()+button_link%>" tabindex="<spe:counter/>" 
class="<%=link_class%>"><%=button_text%></a></td>

Note that the controller puts the message bundle string back into the Tiles context as the attribute button_text.

A similar technique is used to define the strings which will appear as titles and subtitles on pages which are simple Struts forms (as opposed to a “form” created by the Identity Manager forms engine). An example of a Struts form is the OperationResult page. This page displays the results of an operation like changing a user’s password or notification address. A controller class called com.sun.idm.idmx.web.LocalizePageTitles is associated with the base tile definition for this page. This controller class may be passed message bundle keys for the page title:

<!-- Page showing success message after a user resets the password. -->
<definition name=".page.ResetPasswordSuccess" extends=".page.OperationResultNoAuth">
   <put name="forward_id" value="ResetPasswordSuccess" />
   <put name="page_title_key" value="page.title.password_reset_success" />
   <put name="page_subtitle_key" value="page.subtitle.password_reset_success" />
</definition>

OperationResult Relay Definition

When a user resets a password or changes the user ID in Service Provider, the results of the operation are displayed to the user. Instead of creating a separate JSP for each successful operation, it is desirable to have a generic OperationResult page that contains the following:

The title and subtitle strings are inserted into the page $WSHOME/spe/user/OperationResult.jsp . We would also like to be able to pass a key from the tile definition to look up the appropriate action forward for the user’s final destination.

<put name="forward_id" value="ResetPasswordSuccess" />

When the .page.ResetPasswordSuccess tile is rendered, the forward_id parameter is added to the form as a hidden field with name dispatch.

When the user acknowledges the result by clicking the OK button, the following action is executed:

<!-- Set action forward mapping to final destination forward -->
<action path="/spe/user/OperationResult" name="resultForm"
      type="com.sun.idm.idmx.web.RelayAction" scope="request"
      validate="false">
   <forward name="ForgotUsernameSuccess" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
   <forward name="PasswordEmailed" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
   <forward name="ResetPasswordSuccess" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
   <forward name="ProfileLocked" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
   <forward name="ProfileHasBeenLocked" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
   <forward name="EnrollSuccess" path="/spe/user/Login.do?newView=true" 
      redirect="true"/>
</action>

The com.sun.idm.idmx.web.RelayAction class looks up the dispatch request parameter value in the above definition and forwards to the associated URI. In our case, ResetPasswordSuccess maps to the URI ”/.m”/spe/user/Login.do?newView=true”.

Error Handling

In general, errors from which the user can recover, such as form validation errors, are displayed on the edit form so the user can correct the data and resubmit the form.

Errors encountered during processing are generally not recoverable and must be handled differently. A generic error action forward, spe/user/Error.do , is used to display a message that the user should report the error to their local administrator. The JSP supporting this action, $WSHOME/spe/user/Error.jsp , will also include any exception stack trace information in the rendered page source as an HTML comment.