4.1 Identity Server Advance Configuration

4.1.1 Managing an Identity Server

The Identity Servers page is the starting point for managing Identity Servers. Most often, you use this page to stop and start servers, and to assign servers to Identity Server configurations. An Identity Server cannot operate until you have assigned it to an Identity Server configuration.

  1. In the Administration Console, click Devices > Identity Servers.

  2. On the Servers tab, you can perform the following functions by clicking the server’s check box, then clicking any of the following options:

    New Cluster: Creates a new cluster configuration. See Creating a Cluster Configuration.

    Start: Starts the selected server. (See Restarting the Identity Server.)

    Stop: Stops the selected server. (See Restarting the Identity Server.)

    Refresh: Refreshes the server list.

    Actions: Enables you to perform the following tasks:

    • Assign to Cluster: Enables you to assign a server to a cluster configuration. See Assigning an Identity Server to a Cluster Configuration for more information.

    • Remove from Cluster: Enables you to remove one or more servers from a configuration. See Removing a Server from a Cluster Configuration for more information.

    • Delete: Deletes the selected server.

      IMPORTANT:The system does not allow you to delete an Identity Server that is started. You must first stop the server, then delete it. This removes the configuration object from the configuration store on the Administration Console. To remove the server software from the machine where it was installed, you must run the uninstall script on the server machine.

    • Update Health from Server: Performs a health check for the device.

    • Export Configuration: Enables you to export the Identity Server configuration to another setup. See Section 25.6, Exporting the Configuration Data.

    • Import Configuration: Enables you to import the Identity Server configuration from another setup. See Section 25.7.3, Importing the Identity Server Configuration Data.

    This page also displays links in the following columns:

    Column

    Description

    Name

    Lists Identity Server and cluster configuration names.

    Status

    Lists the status of each configuration.

    Current: Indicates that the server is using the latest configuration data. If you change a configuration, the system displays an Update or Update All link.

    Update: A link to update an Identity Server’s configuration data without stopping the server.

    Update All: A link displayed for cluster configurations. This lets you update all the Identity Servers in a cluster to use the latest configuration data, with options to include logging and policy settings.

    For more information about the update process, see Updating an Identity Server Configuration.

    Health

    Lists the health of each configuration and each server.

    Alerts

    Displays the Alerts page, where you can monitor and acknowledge server alerts.

    Commands

    Displays the Command Status page.

    Statistics

    Displays the Server Statistics page and allows you to view the server statistics. See Section 18.1, Identity Server Statistics.

    Configuration

    Lists the Identity Server configuration to which this server belongs.

Updating an Identity Server Configuration

Whenever you change an Identity Server configuration, the system prompts you to update the configuration. An Update Servers status is displayed under the Status column on the Servers page. You must click Update Servers to update the configuration so that your changes take effect.

When you click this link, it sends a reconfigure command to all servers that use the configuration. The servers then begin the reconfiguration process. This process occurs without interruption of service to users who are currently logged in.

When you update a configuration, the system blocks inbound requests until the update is complete. The server checks for any current requests being processed. If there are such requests in process, the server waits five seconds and tests again. This process is repeated three times, waiting up to fifteen seconds for these requests to be serviced and cleared out. After this period of time, the update process begins. Any remaining requests might have errors.

During the update process, all settings are reloaded with the exception of the base URL. In most cases, user authentications are preserved; however, there are conditions during which some sessions are automatically timed out. These conditions are:

  • A user logged in via an authentication contract that is no longer valid. This occurs if an administrator removes a contract or changes the URI that is used to identify it.

  • A user logged in to a user store that is no longer valid. This occurs if you remove a user store or change its type. Changing the LDAP address to a different directory is not recommended, because the system does not detect the change.

  • A user received authentication from an identity provider that is no longer trusted. This occurs if you remove a trusted identity provider or if the metadata for the provider changed.

Additionally, if you remove a service provider from an identity provider, the identity provider removes the provided authentication to that service provider. This does not cause a timeout of the session.

Changes to the SAML and Liberty protocol profiles can result in the trusted provider having outdated metadata for the Identity Server being reconfigured. This necessitates an update at the other provider and might cause unexpected behavior until that occurs.

  1. In the Administration Console, click Devices > Identity Servers.

  2. Click Update or Update All.

    These options are only available when you have made changes that require a server update.

Restarting the Identity Server

Starting and stopping an Identity Server terminates active user sessions. These users receive a prompt to log in again unless you have configured session failover (see Configuring Session Failover).

  1. In the Administration Console, click Devices > Identity Servers, then select the Identity Server to stop.

  2. Click Stop.

  3. Wait for the Command Status to change from Pending to Complete.

  4. Select the Identity Server, then click Start.

  5. When the Command Status changes to Complete, click Refresh.

    The status icon of the Identity Server should turn green.

4.1.2 Editing Server Details

You can edit server details, such as the server name and port. You can also access the other server management tabs from this page.

  1. In the Administration Console, click Devices > Identity Servers, then click the server name.

  2. To edit the information, click Edit.

  3. Modify the following fields as necessary:

    Name: The name of the Identity Server. Names must be alphanumeric and can include spaces, hyphens, and underscores.

    Management IP Address: The IP address of the Identity Server. Changing server IP addresses is not recommended and causes the server to stop reporting. See Section 2.4, Changing the IP Address of Access Manager Devices.

    Port: The Identity Server port used for management.

    Location: The location of the Identity Server.

    Description: A description of the Identity Server.

  4. To save your changes, click OK. Otherwise, click Cancel.

4.1.3 Customizing The Identity Server

This section includes the following topics:

Customizing the Identity Server Login Page

You can create custom login pages that are displayed when the user authenticates to the Identity Server. There are a multitude of reasons for customizing the login page. You might want to remove the NetIQ branding and replace it with your company’s brands. You might need to authenticate users with non-default attributes (such as an e-mail address rather than a username). You also might be fronting several protected resources with an Access Gateway, and you need to create a unique login page for each resource.

When you customize the login page:

Using Custom Pages from Previous Releases: The process for customizing login pages was modified in Access Manager 3.1 SP1. This new process requires some modifications to login pages that have been customized for either 3.1 or 3.0.

Modifying the Target of the User Portal: If you want to control the target when users log directly into the Identity Server, see Specifying a Target.

Modifying Error Pages: Both the Identity Server and the Access Gateway return error pages to the user. For information about customizing these messages and pages, see the following:

Selecting the Login Page and Modifying It

You must be familiar with customizing JSP files to create a customized login page. You can use any of the following methods to produce the page:

  • If you only need to customize the credentials (for example, prompt the user for an e-mail address rather than a name), you can make most of the modifications in the Administration Console. You need to add some properties to a method, create a contract from that method, and modify the prompt in the login.jsp file. For configuration information, see Customizing the Default Login Page to Prompt for Different Credentials.

  • If you want to maintain the features of the 4.0 page and use its authentication cards but you want to remove the NetIQ branding, you need to modify the nidp.jsp file. The nidp.jsp file uses iframes, so the devices that your users use for authentication must also support iframes. For configuration information, see Customizing the nidp.jsp File.

  • If you don’t need the authentication cards and if the devices that your users use for authentication support iframes, you can start with the login.jsp file and customize it. For configuration information, see Modifying the login.jsp File.

  • If some of your users are using devices that don’t support iframes, you need to customize the 3.0 login page. For configuration information, see “Modifying the 3.0 Login Page” on page 950

NOTE:After you have created customized login pages, you need to back them up before doing an upgrade. The upgrade process overrides any custom changes made to JSP files that use the same filename as those included with the product.

During an upgrade, you can select to restore custom login pages, but NetIQ still recommends that you have your own backup of any customized files.

Customizing the Default Login Page to Prompt for Different Credentials

This section explains how to prompt the users for an identifier other than the user’s name. Figure 4-1 displays the default login page with the username prompt.

Figure 4-1 Modifying the Credential Prompts

This section explains how to modify the content of the login.jsp file. If you want to modify other aspects of this page, you need to select one of the other methods.

The instructions below explain how to create a method that sets up the appropriate query so that the user can be found in the user store with an identifier other than the username (the cn attribute). The instructions then explain how to create a contract that uses this method and how to modify the login.jsp page so that it prompts for the appropriate identifier such as an email address instead of a username.

  1. Create a method with the appropriate query:

    1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Methods.

    2. Click New, then specify a Display Name.

    3. In the drop-down menu for classes, select a class that is a username/password class.

    4. Leave the Identifies User option enabled, and configure the user store option according to your needs.

    5. In the Properties section, click New, then specify the following values:

      Property Name: Query

      Property Value: (&(objectclass=person)(mail=%Ecom_User_ID%))

      This property is defined so that it queries the user store for the attribute you want to use rather than the cn attribute (in this case, the mail attribute of the person class). The %Ecom_User_ID% variable is the default variable name on the login page. You can change this to %EMail_Address% if you also change the value in your custom login page.

      For more information about how to use this property, see Query Property.

    6. In the Properties section, click New, then specify the following values:

      Property Name: JSP

      Property Value: <filename>

      Replace <filename> with the name of the custom login.jsp page you are going to create so that the page prompts the user for an e-mail address rather than a username. This must be the filename without the JSP extension. For example, if you name your file email_login.jsp, then you would specify email_login for the property value.

    7. Click OK.

  2. Create a contract that uses this method:

    1. Click Contracts > New.

    2. Select the method you just created.

    3. Configure the other options to fit your requirements.

      For information about configuring the other options for a contract, see Section 5.1.4, Configuring Authentication Contracts.

    4. Click OK.

  3. Update the Identity Server.

  4. Copy the login.jsp file and rename it. The JSP files are located on the Identity Server in the following directory:

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  5. (Conditional) If you modified the %Ecom_User_ID% variable, find the string in the file and replace it with your variable.

  6. (Conditional) If you need to support only one language, modify the prompt in the login.jsp file:

    1. Find the following string in the file:

      <label><%=handler.getResource(JSPResDesc.USERNAME)%></label>
      
    2. Replace it with the string you want, for example:

      <label>Email Address:</label>
      
    3. Copy the modified file to each Identity Server in the cluster.

    4. Back up your customized file.

  7. (Conditional) If you need to localize the prompt for multiple languages, create a custom message properties file for the login prompt. (For more information about how to create a custom message properties file, see Customizing Messages.)

    The following steps assume you want to change the username prompt to an e-mail address prompt.

    1. Find the following definition in the com/novell/nidp/resource/jsp directory of the unzipped nidp.jar file.

      JSP.50=Username:
      
    2. Add this definition to your custom properties file and modify it so that it prompts the user for an e-mail address.

      JSP.50=Email Address:
      
    3. Translate the value and add this entry to your localized custom properties files.

    4. Copy the customized properties files to the WEB-INF/classes directory of each Identity Server in the cluster.

    5. Restart Tomcat on each Identity Server using one of the following commands:

      Linux Identity Server: Enter the following command:

      /etc/init.d/novell-idp restart

      rcnovell-idp restart

      Windows Identity Server: Enter the following commands:

      net stop Tomcat7 net start Tomcat7

  8. To view a sample custom page with these modifications, see Modified login.jsp File for Credential Prompts.

Customizing the nidp.jsp File

Figure 4-2 displays the default login page provided by Access Manager. Multiple JSPs are used to create the page.

Figure 4-2 The JSPs That Create the Login Page

You can use the nidp.jsp file to customize the header with the Access Manager product name and the NetIQ logo. The menus.jsp file controls the Authentication and User Login tabs. The login.jsp file controls the credential frame with username and password. The content.jsp file controls what is displayed on the page, including the available authentication cards.

The following sections explain how to modify the login page that these JSPs create:

Rebranding the Header
  1. Copy the nidp.jsp file and rename it. The JSP files are located on the Identity Server in the following directory:

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  2. Replace the header title that appears in the top frame (“NetIQ Access Manager” in Figure 4-2):

    1. Locate the following string at the top of the file.

      String hdrTitle = handler.getResource(JSPResDesc.PRODUCT);
      
    2. Replace the value with the title you want to appear. For example:

      String hdrTitle = "My Company";
      

      Ensure that to enclose your title value with double quotes.

  3. Replace the window title that appears in the browser title bar:

    1. Locate the following line that appears between the <head></head> tags:

      <title><%=handler.getResource(JSPResDesc.TITLE)%></title>;
      
    2. Replace the content between the <title> and </title> tags with the title you want to appear. For example:

      <title>My Company</title>;
      
  4. Replace the Access Manager logo on the left of the header (see Figure 4-1):

    1. Locate the following string:

      String hdrImage = "AMHeader_image.png";
      
    2. Replace the value in the quotes with the path and the filename of the image you want to use.

      For example, if you created a /custom_images directory in the images directory, the hdrImage string would have a value similar to the following:

      String hdrImage = "/custom_images/myapp.png"
      
    3. NOTE:Mobile login page customization is only supported in mobile / hand-held Web browsers that support CSS 3.0 specifications. If the browser does not support CSS 3.0 specification, the default logo and header of the normal window is displayed in smaller size.

      To customize the logo for a mobile view, create a new logo and name it logo_new.gif. The recommended size of the logo is 40x40 pixels.

  5. Replace the NetIQ logo on the right of the header (see Figure 4-2):

    1. Locate the following string:

      String hdrLogo = "AMHeader_logo.png";
      
    2. Replace the value of the hdrLogo string with the path and the filename of the image you want to use.

      For example, if you created a /custom_images directory in the images directory, the hdrLogo string would have a value similar to the following:

      String hdrLogo = "/custom_images/companylogo.png";
      
  6. To change the background image for the header (which allows for variable sizing of the page):

    1. Locate the following string:

      String hdrBgndImg = "AMHeader_background.png";
      
    2. Replace the value of the hdrBgndImg string with the path and the filename of the image you want to use. You can use a color or an image that can be repeated. The style is set to repeat it from left to right as the window expands.

      For example, if you created a /custom_images directory in the images directory, the hdrBgndImg string would have a value similar to the following:

      String hdrBgndImg = "/custom_images/mybackground.png";
      
    3. To customize the header for a mobile view, create a new header and name it banner_new.gif. The recommended size of the banner is 40x800 pixels.

  7. If your custom images or title do not appear in the header where you want them, you need to modify the style section.

    1. Locate the following lines:

      #header { background-image: url(<%= handler.getImage(hdrBgndImg,false)%>); background-repeat: repeat-x; }
      
      #logo { position: absolute; top: 0px; right: 0px; }
      
      #title { position: absolute; font-size: 1.2em; color: white; top: 13px; left: 55px; }
      
    2. Modify the top, left, and right values.

  8. To change the background colors on the page, modify the color values in the <style> section of the <head> element.

  9. If you need to create multiple custom login pages, repeat Step 1 through Step 8.

  10. Copy the custom login pages and the images they require to each Identity Server in the cluster.

  11. Continue with one of the following tasks:

Customizing the Card Display

The easiest method to control what appears in the Authentication Cards section is not by modifying the content.jsp file. It is by using the Show Card option that appears on the definition of each card. If this option is not selected, the card does not appear in the Authentication Cards section. Each contract has an associated card. For information about modifying the card options, see Section 5.1.4, Configuring Authentication Contracts.

Continue with one of the following:

Customizing the Credential Frame

The most common reason for modifying the login.jsp page is to prompt the users for an identifier other than the user’s name. To do this, you need to create a method that sets up the appropriate query so that the user can be found in the user store with an identifier other than the username. You then need to create a contract that uses this method. You also need to modify the prompt in the login.jsp page to match the identifier you are prompting for.

  1. Create a method with the appropriate query:

    1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Methods.

    2. Click New, then specify a Display Name.

    3. In the drop-down menu for classes, select a class that is a username/password class.

    4. Leave the Identifies User option enabled, and configure the user store option according to your needs.

    5. In the Properties section, click New, then specify the following values:

      Property Name: Query

      Property Value: (&(objectclass=person)(mail=%Ecom_User_ID%))

      This property is defined so that it queries the user store for the attribute you want to use rather than the cn attribute (in this case, the mail attribute of the person class). Change mail to the name of the attribute in your user store that you want to use for the user identifier.

      The %Ecom_User_ID% variable is the default variable name on the login page. You can change this to something like %EMail_Address% if you also change the value in your custom login page.

      For more information about how to use this property, see Query Property.

    6. In the Properties section, click New, then specify the following values:

      Property Name: JSP

      Property Value: <filename>

      Replace <filename> with the name of the custom login.jsp page you are going to create so that the page prompts the user for an e-mail address rather than a username. This must be the filename without the JSP extension. For example, if you name your file email_login.jsp, then you would specify email_login for the property value.

    7. Click OK.

  2. Create a contract that uses this method:

    1. Click Contracts > New.

    2. Select the method you just created.

    3. Configure the other options to fit your requirements.

      If you are creating multiple custom login pages with customized credentials, you might want to use the URI to hint at which custom login.jsp file is used with which custom nidp.jsp file. For example, the following URI values have the filename of the login page followed by the name of the custom nidp.jsp page:

      login1/custom1
      login2/custom2
      login3/custom3
      

      For information about configuring the other options for a contract, see Section 5.1.4, Configuring Authentication Contracts.

    4. Update the Identity Server.

  3. Copy the login.jsp file and rename it. The JSP files are located on the Identity Server in the following directory:

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  4. (Conditional) If you modified the %Ecom_User_ID% variable, find the string in the file and replace it with your variable.

  5. (Conditional) If you need to support only one language, modify the prompt in the login.jsp file:

    1. Find the following string in the file:

      <label><%=handler.getResource(JSPResDesc.USERNAME)%></label>
      
    2. Replace it with the string you want, for example:

      <label>Email Address:</label>
      
    3. Copy the modified file to each Identity Server in the cluster.

    4. Back up your customized file.

  6. (Conditional) If you need to localize the prompt for multiple languages, create a custom message properties file for the login prompt. (For more information about how to create a custom message properties file, see Customizing Messages.)

    The following steps assume you want to change the username prompt to an e-mail address prompt.

    1. Find the following definition in the com/novell/nidp/resource/jsp directory of the unzipped nidp.jar file.

      JSP.50=Username:
      
    2. Add this definition to your custom properties file and modify it so that it prompts the user for an e-mail address.

      JSP.50=Email Address:
      
    3. Translate the value and add this entry to your localized custom properties files.

    4. Copy the customized properties files to the WEB-INF/classes directory of each Identity Server in the cluster.

    5. Restart each Identity Server using one of the following commands:

      Linux Identity Server: Enter one of the following command:

      /etc/init.d/novell-idp restart

      rcnovell-idp restart

      Windows Identity Server: Enter the following commands:

      net stop Tomcat7 net start Tomcat7

  7. To view a sample custom page with these modifications, see Custom nidp.jsp File with Custom Credentials.

  8. To specify which customized nidp.jsp to display with the contract, you must modify the main.jsp file. Continue with Adding Logic to the main.jsp File.

Customizing the nidp.jsp File to Customize Error Message

The Identity Server publishes a generic error message for error code during SAML failure such as request denied or Invalid Name ID Policy and so on. You can customize the NIDP jsp file available at /opt/novell/nids/lib/webapp/jsp and write an appropriate error message for either redirection or to inform the user about the issue with an appropriate message. Perform the following steps to customize error message.

NOTE:In the following example the specified code snippet is for simulating InvalidNameIDPolicy error for SAML 2.0.

  1. Generate an error condition with for example, Invalid Name ID Policy.

  2. Customized the nidp.jsp file and add the following code for redirection.

    com.novell.nidp.ui.MenuHandler redirectMenuHandler;
            com.novell.nidp.NIDPMessage redirectMessage;
        String redirectCause;
    
            redirectMenuHandler = new MenuHandler(request, response);
            redirectMessage = redirectMenuHandler.getMessage(true);
            if (redirectMessage != null && redirectMessage instanceof
    com.novell.nidp.NIDPError) {
            redirectCause = ((com.novell.nidp.NIDPError)
    redirectMessage).getNIDPExceptionMsg();
            System.out.println("************** redirectCause" + redirectCause);
            if (redirectCause != null && 
    redirectCause.indexOf("InvalidNameIDPolicy") != -1) {
            response.sendRedirect("http://www.novell.com"); 
                return;
            }
        }
    
  3. Restart the Identity Server by using the rcnovell-idp restart command.

  4. Verify that when failure occurs, SAML shows the following message in the authentication response.

    <samlp:Status><samlp:StatusCode
    Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><samlp:StatusCode
    Value="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"/></samlp:StatusCode>
    

    Due to customized nidp.jsp file, SAML redirects to specified location.

  5. Rerun the failure and verify that instead of displaying 300101008, nidp page redirects to the specified www.novell.com location.

Modifying the login.jsp File

The login.jsp file gives you just the credential frame with the login prompts in an iframe. It has no branding header. If you use this page, you are responsible for writing the HTML code for the header and the branding.

  1. Copy the login.jsp file and rename it. The JSP files are located on the Identity Server in the following directory:

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  2. Add the custom branding and any other content you require to the file.

  3. To modify the credentials, see Customizing the Credential Frame.

  4. Repeat Step 1 through Step 3 for each resource that requires unique branding.

  5. Copy the files to each Identity Server in the cluster.

  6. Back up your customized files.

  7. (Optional) To view a sample custom page with these modifications, see Custom 3.1 login.jsp File.

  8. Continue with Using Properties to Specify the Login Page.

Configuring the Identity Server to Use Custom Login Pages

There are two ways to configure the Identity Server to use a custom login page. You can use properties or you can modify the main.jsp file. Which method you can use depends upon your modifications.

  • You can use properties if you created your custom page from the 3.1 login.jsp page or have modified a 3.0 custom page to work on 3.1. See Using Properties to Specify the Login Page.

  • If you created your custom page from the nidp.jsp file, you cannot use properties to specify the main custom page for authentication. You must modify the main.jsp file. See Adding Logic to the main.jsp File.

Using Properties to Specify the Login Page

For each resource that needs a unique login page, you need to create an authentication method and add the JSP and MainJSP properties to the method. You then need to create a contract for each method.

The following steps assume that the custom login page is called custom1.jsp.

  1. Create a method for a custom login page:

    1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Methods.

    2. Select one of the following actions:

      • If you have create a method for a Query property to be used with your custom login page, click the name of the method.

      • If you didn’t modify the credentials on the login page, click New, specify a display name, select a password class, and configure a user store.

    3. In the Properties section, click New, then specify the following:

      Property Name: MainJSP

      Property Value: true

      This property indicates that you want to use a custom login page with this method. It also indicates that the custom login page contains the prompts for user credentials.

      Property names and values are case sensitive.

    4. Click OK.

    5. (Conditional) If the Properties section does not contain a JSP property, click New, specify the following:

      Property Name: JSP

      Property Value: custom1

      The property value for the JSP property is the name of the custom login file without the JSP extension. Replace custom1 with the name of your custom login file. This property determines which login page is displayed when this method is used. The filename cannot contain nidp as part of its name.

    6. Click OK.

      For more information about setting property values, see Specifying Common Class Properties.

    7. (Conditional) If you created multiple custom login pages, repeat Step 1.b through Step 1.e for each page.

  2. For each method that you modified for a custom login page, create a contract:

    1. Click Contracts, then click New.

    2. Fill in the fields to fit the needs of the resource, but ensure that to assign the custom method as the method for the contract.

    3. Click Next, configure a card for the contract, then click Finish.

  3. Update the Identity Server.

  4. For each resource that you have created a custom login page, assign that resource to use the contract that is configured to display the appropriate login page:

    1. Click Devices > Access Gateways > Edit > [Reverse Proxy Name] > [Proxy Service Name] > Protected Resources.

    2. For each protected resource that you have created a custom contract for, select the protected resource, then configure it to use the custom contract.

  5. Update the Access Gateway.

  6. (Conditional) If the custom page does not display correctly, see Troubleshooting Tips for Custom Login Pages.

Adding Logic to the main.jsp File

You can modify the main.jsp file and use the contract URI to specify the login page to display. The Identity Server must be running 3.1 SP1 or later to use this feature. Be aware of the following:

  • The main.jsp file cannot be renamed, so any modifications you make to this file can be lost whenever you upgrade the Identity Server. During the upgrade, you must select to restore custom files or you must restore your modified file after the upgrade. If this is the only JSP file that you modified that uses an Identity Server name, it is probably best to manually restore this file after an upgrade.

  • Modifying the main.jsp file requires knowledge of JSP programming and if/else statements.

Modifying the main.jsp file allows you to have the following type of configuration:

  • You can create multiple customized nidp.jsp pages. For example: custom1.jsp, custom2.jsp, and custom3.jsp.

  • You can create multiple customized login.jsp pages that request different login credentials. For example:

    login1.jsp: Configured to request username and password.

    login2.jsp: Configured to request username, email, and password.

    login3.jsp: Configured to request email and password.

With this type of configuration, you must create three different authentication contracts with an authentication method with a JSP property defined for each of them. These contracts require the types of values listed in the table below. The URI is defined so that it reflects the custom login.jsp and the custom nidp.jps that are used by the contract.

Contract

Configuration Details

Contract1

URI

login1/custom1

 

Method1

Configured with the following JSP property:

Property Name: JSP

Property Value: login1

This method does not need a query property unless you are using an attribute other than the cn attribute for the username.

Contract2

URI

login2/custom2

 

Method2

Configured with the following two properties:

Property Name: JSP

Property Value: login2

Property Name: Query

Property Value: (&(objectclass=person)(mail=%Ecom_User_ID%))

Contract3

URI

login3/custom3

 

Method3

Configured with the following two properties:

Property Name: JSP

Property Value: login3

Property Name: Query

Property Value: (&(objectclass=person) (mail=%Ecom_User_ID%))

The following procedure explains how to configure Access Manager to display these custom login pages with custom credentials.

  1. Create a unique method for each custom login.jps file:

    1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Methods.

    2. Click New, then configure the following fields:

      Display name: Specify a name for the method. You might want to use a name that indicates which login page is assigned to this method.

      Class: Select a name/password class.

      Configure the other fields to match your requirements.

    3. In the Properties section, add a Query property if the page uses custom credentials.

      For example, to add an email address to the login prompts, add the following property:

      Property Name: Query

      Property Value: (&(objectclass=person)(mail=%Ecom_User_ID%))

      If you are creating a method for Contract 1 in the example above (which prompts for a username and password), you do not need to add a query property unless you are using an attribute other than the cn attribute for the username.

    4. In the Properties section, add a JSP property to specify which login.jsp file to use with this method.

      For example:

      Property Name: JSP

      Property Value: login2

    5. Click Finish.

    6. If you have created more than one custom login.jsp file, repeat Step 1.b through Step 1.e for each page.

      To configure the scenario described in this section, repeat these steps for three login pages.

  2. Create a unique contract URI:

    1. In the Administration Console, click Contracts.

    2. Click New, then configure the following fields:

      Display name: Specify a name for the contract. You might want to use a name that indicates which login page is assigned to this contract.

      URI: Specify a value that uniquely identifies the contract from all other contracts. No spaces can exist in the URI field. You might want to use a name that indicates the custom login page and custom credential page, such as login1/custom1.

      Methods and Available Methods: Select the authentication method you configured in Step 1.

    3. Configure the other fields to meet your network requirements, then click Next.

    4. Configure the authentication card, then click Finish.

    5. (Conditional) If you have created multiple custom login pages, repeat Step 2.b through Step 2.d for each page.

      To configure the scenario described in this section, repeat these steps for /login2/custom2 and /login3/custom3.

    6. Click OK, then update the Identity Server.

  3. Modify the main.jsp file:

    1. Open the main.jsp file. The file is located in the following directory:

      Linux: /opt/novell/nids/lib/webapp/jsp

      Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp \jsp

    2. Near the top of the file, add the following line:

      String strContractURI = hand.getContractURI();
      

      This sets the strContractURI variable to the value of the contract URI that is being used for authentication. These lines should look similar to the following:

      <%
          ContentHandler hand = new ContentHandler(request,response);
          String strContractURI = hand.getContractURI();
      
          // Is there a JSP defined on a class definition or a method 
          // definition that should be displayed as the main jsp here?
          if (handler.contractDefinesMainJSP())
          {
      %>
      
    3. After the if statement, add an else if statement for each contract URI you have created. For example:

      <% }
      else if(strContractURI != null && strContractURI.equals("login1/custom1"))
          {
      %>
           <%@ include file="custom1.jsp" %>
      
      <%  }
      else if(strContractURI != null && strContractURI.equals("login2/custom2"))
          {
      %>
              <%@ include file="custom2.jsp" %>
      
      <% }
      else if(strContractURI != null && strContractURI.equals("login3/custom3"))
          {
      %>
              <%@ include file="custom3.jsp" %>
      

      These else if statements set up three contracts for customized login pages:

      • The first else if statement specifies the URI of the login1 contract and configures it to display the custom1.jsp page for authentication.

      • The second else if statement specifies the URI of the login2 contract and configures it to display the custom2.jsp page for authentication.

      • The third else if statement specifies the URI of the login3 contract and configures it to display the custom3.jsp page for authentication.

      Your file should look similar to the following:

      <%@ page language="java" %>
      <%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
      <%@ page import="com.novell.nidp.*" %>
      <%@ page import="com.novell.nidp.resource.jsp.*" %>
      <%@ page import="com.novell.nidp.ui.*" %>
      <%@ page import="com.novell.nidp.common.util.*" %>
      <%@ page import="com.novell.nidp.liberty.wsf.idsis.apservice.schema.*" %>
      
      <%
          ContentHandler hand = new ContentHandler(request,response);
          String strContractURI = hand.getContractURI();
      
          // Is there a JSP defined on a class definition 
          // or a method definition that should be displayed 
          // as the main jsp here?
          if (hand.contractDefinesMainJSP())
          {
      %>
              <%@ include file="mainRedirect.jsp" %>
      <%  }
          else if(strContractURI != null && strContractURI.equals("login1/custom1"))
          {
      %>
           <%@ include file="custom1.jsp" %>
      
      <%  }
      else if(strContractURI != null && strContractURI.equals("login2/custom2"))
          {
      %>
              <%@ include file="custom2.jsp" %>
      
      else if(strContractURI != null && strContractURI.equals("login3/custom3"))
          {
      %>
              <%@ include file="custom3.jsp" %>
      
      <%  }    // This is the jsp used by default
          else
          {
      %>
              <%@ include file="nidp.jsp" %>
      <%  }  %>
      
    4. Copy the modified main.jsp file to each Identity Server in your cluster.

  4. Back up your customized files.

  5. For each resource that you have created a custom login page for, assign that resource to use the contract that is configured to display the appropriate login page:

    1. Click Devices > Access Gateways > Edit > [Reverse Proxy Name] > [Proxy Service Name] > Protected Resources.

    2. For each protected resource that you have created a custom contract for, select the protected resource, then configure it to use the custom contract.

    3. Update the Access Gateway.

  6. (Conditional) If the custom page does not display correctly, see Troubleshooting Tips for Custom Login Pages.

Troubleshooting Tips for Custom Login Pages

If your custom login page does not display or generates an error message, use the following procedure to discover the root cause:

  1. Set the Application option of Component File Logger Levels to debug, update the Identity Server, attempt to log in, then view the log file.

    Check for Unable to Compile errors in the log file. If your custom page does not compile, a blank page is displayed.

  2. If you receive an Unable to Find File error, verify the value of the JSP property. Ensure that the value does not contain the JSP extension as part of the filename.

  3. If you see pages that you have deleted or pages where your modifications have not been implemented:

    1. Open the new custom file with a text editor to ensure it has a newer date than the compiled file.

      If this does not solve the problem, continue with Step 3.b.

    2. Delete the nidp directory in the Tomcat work directory on each Identity Server. This forces a recompile the JSP pages.

      Linux: /opt/novell/nam/idp/work/Catalina/localhosts/nidp

      Windows Server 2008: \Program Files (x86)\Novell\Tomcat\work\Catalina \localhosts\nidp

    3. Restart Tomcat on each Identity Server.

Customizing the Identity Server Logout

You can also use the following methods to modify the Identity Server logout page:

To customize the logout page when the user logs out of an Access Gateway protected resource, see Customizing Logout Requests. When you have both Liberty and SAML 2.0 sessions running on the Identity Server and you log out of the Access Gateway, the logoutsuccess.jsp page is not executed with the customization you have made to the logout page. For information about the workaround, see Logging Out of Sessions to the Access Gateway and SAML Connectors when Branding Exists in the Customized Logout Page.

NOTE:After customizing a JSP file, you need to sanitize the JSP file to prevent XSS attacks. See, Section 8.7, Preventing Cross-site Scripting Attacks.

Rebranding the Logout Page

The branding in the header of the logout page is controlled by the branding of the nidp.jsp file. If you have modified this file for a customized login, the same branding appears in the logout page. For information about how to modify nidp.jsp for logos, titles, and colors, see Rebranding the Header.

IMPORTANT:Save a copy of your modified nidp.jsp file. Every time you upgrade your Identity Server, you need to restore this file.

Replacing the Logout Page with a Custom Page

You can create your own logout page and configure the Identity Server to use it. To do this, you need to modify the logoutSuccess.jsp file on the Identity Server. It is located in the following directory:

Linux: /opt/novell/nids/lib/webapp/jsp

Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

The logoutSuccess.jsp file is called in a frame from the nidp.jsp file. You can modify the file to display what you want or you can modify it to redirect the user to your custom page. One way to provide redirection is to replace the information in the <body> element of the file with something similar to the following:

<body> 
      <script language="JavaScript"> 
        top.location.href='http://<hostname/path>'; 
      </script>     
</body>

Replace the <hostname/path> string with the location of your customized logout page.

IMPORTANT:Save a copy of your modified logoutSuccess.jsp file. Every time you upgrade your Identity Server, you will need to restore this file.

Configuring for Local Rather Than Global Logout

By default, when the Identity Server receives a logout request, the Identity Server logs the user out of any identity providers and service providers to which the user has authenticated. If you want to modify this behavior so that the logout request logs the user out of just the Identity Server and leaves the user authenticated to identity providers and service providers, you need to add the following query string to the logout URL:

?local=true

The logout URL has the following format:

<Base_URL>/app/logout

Replace <Base_URL> with the base URL of your Identity Server. If the base URL of your Identity Server was https://hhb1.provo.novell.com:8443/nidp, your local logout URL would be the following:

https://hhb1.provo.novell.com:8443/nidp/app/logout?local=true

To modify the logout.jsp file so that it performs a local logout:

  1. At the Identity Server, open the logout.jsp file.

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  2. Find the following line in the file:

    <form method="post" target="_top" action="<%= request.getContextPath() %>/app/logout">
    
  3. To the /app/logout string, add ?local=true. This modified line should look similar to the following:

    <form method="post" target="_top" action="<%= request.getContextPath() %>/app/logout?local=true">
    
  4. Save the file.

  5. Copy the file to each Identity Server in the cluster.

  6. Back up this file.

Customizing Logout Pages to Redirect Based on Parameters

The Identity Server logout page can be customized to redirect to URLs based on parameters specified in the logoutSuccess.jsp file. To customize the logoutSuccess.jsp file to redirect to URLs, perform the following steps:

  1. At the Identity Server, open the logoutSuccess.jsp file:

    Linux: /opt/novell/nids/lib/webapp/jsp

    Windows: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

  2. Add the following as the last line in the logoutSuccess.jsp file:

    <%out.println("UIHandler-param: " + uh.getLogoutQueryStringParam("test"));%>

    Here test indicates name of the parameter.

  3. Restart the Identity Server.

  4. Specify a parameter with the logout URL. For example: https://www.idp.com:8443/nidp/app/logout?test=NetIQ.

    The logout page displays UIHandler-param: NetIQ in the logout page.

Customizing Identity Server Messages

NOTE:After customizing a JSP file, you need to sanitize the JSP file to prevent XSS attacks. See, Section 8.7, Preventing Cross-site Scripting Attacks.

Customizing Messages

  1. To customize the error pages, determine whether you need one custom file or multiple files:

    • If you do not need to support multiple languages, you can create one custom file for all your customized messages.

    • If you need to support multiple languages, you need to create a custom file for each language you want to customize.

  2. Create the custom properties file and name it:

    To support one language, name the file nidp_custom_resources.properties.

    To support multiple languages, create a nidp_custom_resources_<le_cy>.properties file for each supported language. Replace <le_cy> with the standard convention for Java Resource Bundles for the language or the language and country. For example:

    nidp_custom_resources_en_US.properties
    nidp_custom_resources_fr.properties
    nidp_custom_resources_es.properties
    

    If you want to support a custom messages for a language and a country and for just the language, you must create two files. For example:

    nidp_custom_resources_es_VE.properties
    nidp_custom_resources_es.properties
    
  3. Copy the nidp.jar file to a working area. This file is located in the following directory:

    Linux: /opt/novell/nids/lib/webapp/WEB-INF/lib

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\WEB-INF\lib

  4. Unzip the nidp.jar file in your working directory.

  5. In your working directory, locate the .properties files in the following directories.

    com/novell/nidp/resource/strings
    com/novell/nidp/resource/logging
    com/novell/nidp/resource/jsp
    com/novell/nidp/resource/jcc
    com/novell/nidp/resource/noxlate
    com/novell/nidp/liberty/wsf/idsis/ppservice/model
    com/novell/nidp/liberty/wsf/idsis/epservice/model
    com/novell/nidp/liberty/wsf/idsis/opservice/model
    com/novell/nidp/liberty/wsf/idsis/apservice/model
    com/novell/nidp/liberty/wsf/interaction
    com/novell/nidp/liberty/wsf/idsis/ssservice/model
    com/novell/nidp/servlets/handler/identityeditor
    com/novell/nidp/servlets/handler/identityaccesseditor
    com/novell/nidp/liberty/wsf/idsis/model
    com/novell/nidp/liberty/wsf/idsis/authority/ldap/attribute/plugins/resources
    com/novell/nidp/liberty/wsf/idsis/ldapservice/model
    

    The properties files that have been localized contain the messages that end users might see. The properties files that have not been localized contain messages that the end users should not see.

  6. Locate the messages you want to customize and copy them to your custom file.

    All the messages you want to customize are placed in this file, even though they come from different properties files. Your file should look similar to the following if you selected to customize messages from the nidp_resources_en_US.properties file and the SSModelResources_en_US.properties file. For example:

    NIDPMAIN.100=An Identity Provider response was received that failed to authenticate this session.
    NIDPMAIN.101=A request for identity federation could not be completed.
    NIDPMAIN.102=A request for identity federation termination could not be completed.
    
    SS.WKSLdapCreds = LDAP Credentials
    SS.WKSELdapCredsUserName = LDAP User Name
    SS.WKSELdapCredsUserDN = LDAP User DN
    SS.WKSELdapCredsUserPassword = LDAP Password
    SS.WKSX509Creds = X509 Credentials
    
  7. (Conditional) If you are supporting multiple languages, copy the messages to each custom language file.

  8. Replace the messages in the file with your custom messages.

    Replace the string after the equals (=) sign with your translated or customized message.

    If you are using double-byte characters, the characters need to be in Unicode, hexadecimal format with a \u prefix. For example: \u5c71.

  9. Save the file.

  10. Copy the custom properties file to the following directory on all Identity Servers in the cluster:

    Linux: /opt/novell/nam/idp/webapps/nidp/WEB-INF/classes

    Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\WEB-INF\classes

  11. (Optional) To enable messages about the loading of the custom properties files, enable debug logging:

    1. In the Administration Console, click Devices > Identity Servers > Edit > Logging.

    2. In the Component File Logger Levels section, select Debug level for Application.

    3. Click OK, then update the Identity Server.

  12. Restart Tomcat.

    • Linux Identity Server: Enter one of the following commands:

      /etc/init.d/novell-idp restart

      rcnovell-idp restart

    • Windows Identity Server: Enter the following commands:

      net stop Tomcat7

      net start Tomcat7

  13. (Optional) To verify the loading of the custom properties files:

    1. View the log file by clicking Auditing > General Logging.

    2. Search for messages similar to the following in the catalina.out or stdout.log file:

      The named Custom Properties File was loaded and will be used:
      
      Custom Properties File successfully loaded! Name: <Custom Properties FileName> 
      
      An error occurred loading a specific Custom Properties File. Loading of other Custom Properties Files will continue.
      
      <Error Description>, Attempting to load Custom Properties File! Name: <Custom Properties FileName>
      
      The locale specifier in the Custom Properties File filename could not be successfully parsed into a valid locale. Loading of other Custom Properties Files will continue.
      
      Custom Properties File load failed. Could not determine correct locale! Name: <Custom Properties FileName>
      
      A general error occurred loading Custom Properties Files. Loading will stop and all un-loaded Custom Properties Files will not be loaded.
      
      <Error Description>, Attempting to load Custom Properties Files!
      

To create custom error pages for the Access Gateway, see Customizing Error Messages and Error Pages on Access Gateway.

Customizing the Branding of the Error Page

The error page (err.jsp) is returned when the Identity Server encounters an error with the following message:

Error: Unable to authenticate, (300101014-esp-01E79F6000B87D4E8)

The file is located in the following directory.

Linux: /opt/novell/nids/lib/webapp/jsp

Windows Server 2008: \Program Files (x86)\Novell\Tomcat\webapps\nidp\jsp

IMPORTANT:After you have customized this page, you need to ensure you back up this page before doing an upgrade. The upgrade process overrides any custom changes made to the err.jsp page.

For information about customizing the error message, see Customizing Messages.

You can customize the following items:

Customizing the Titles

The window title appears in the browser title bar. To replace this text, open the err.jsp file and locate the following text that appears between the <head></head> tags:

<title><%=handler.getResource(JSPResDesc.TITLE)%></title>

Replace the content between the <title> and </title> tags with the title you want to appear. For example:

<title>My Company</title>

The display title is the title that appears in the top frame of the page. Locate the following text that appears in the <body> of the page:

<div id="title"><%=handler.getResource(JSPResDesc.PRODUCT)%></div>

Replace the content between the <div id="title"> and </div> with the title you want to appear. For example:

<div id="title">My Company</div>
Customizing the Images

To replace the header image, open the err.jsp file and locate the following text in the body of the file.

<div><img src="/nesp/images/AccessMan_Login_Head.png"></div>

Replace the value of the src attribute with the path and filename of the image you want to use.

To replace the Novell logo image, locate the following text in the body of the file.

<div id="logo"><img src="/nesp/images/AccessMan31_Nlogo.png"></div>

Replace the value of the src attribute with the path and filename of the image you want to use.

Customizing the Colors

To change the background colors on the page, modify the color values in the <style> section of the <head>.

Customizing Tooltip Text for Authentication Contracts

The strings that the users see when they mouse over the cards for authentication contracts can be customized. If you need to support only one language, modify the text in the Administration Console.

  1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Contracts.

  2. Click the name of a contract, then click Authentication Card.

  3. Replace the English text in the Text option with the required language, then click OK.

  4. Repeat Step 2 and Step 3 for each contract in the list.

  5. Click OK, then update the Identity Server.

If you need to support multiple languages, you need to localize the tooltips. The nidsCardText attribute of the nidsAuthLocalContract object needs to be changed to a resource ID. The following procedure explains how to do this in the Administration Console. You can also use an LDAP browser.

  1. In the Administration Console, click Devices > Identity Servers > Edit > Local > Contracts.

  2. Click the name of a contract, then click Authentication Card.

  3. Replace the text in the Text option with a resource ID.

    For example, replace Name/Password - Form with CUSTOM_NamePwdFormToolTip.

  4. Click OK.

  5. Repeat Step 2 through Step 4 for each contract in the list.

  6. Click OK, then update the Identity Server.

  7. Use custom string resource files to define the localized strings:

    1. Change to the WEB-INF/classes directory.

    2. For each supported language, create a properties file. For example:

      nidp_custom_resources_fr.properties
      nidp_custom_resources_es.properties
      

      If you have already created these files for custom messages (see Customizing Messages), use the existing files.

    3. For each resource ID you have created, add an entry that contains the resource ID and the text you want displayed for that language. For example:

      CUSTOM_NamePwdFormToolTip=Forma de Nombre/Clave
      
    4. Repeat Step 7.c for each supported language file.

  8. Restart Tomcat.

    • Linux Identity Server: Enter one of the following commands:

      /etc/init.d/novell-idp restart

      rcnovell-idp restart

    • Windows Identity Server: Enter the following commands:

      net stop Tomcat7 net start Tomcat7

Sample Custom Login Pages

NOTE:After customizing a JSP file, you need to sanitize the JSP file to prevent XSS attacks. See, Section 8.7, Preventing Cross-site Scripting Attacks.

Modifying the File

The following 4.0 login.jsp file has been modified to display line numbers. The lines that require modifications have been highlighted, and a few extra spaces have been added to allow for a better display of the text.

1. <%@ page language="java" %>
2. <%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
3. <%@ page import="com.novell.nidp.common.provider.*" %>
4. <%@ page import="java.util.*" %> 5. <%@ page import="java.net.*" %>
6. <%@ page import="com.novell.nidp.*" %>
7. <%@ page import="com.novell.nidp.servlets.*" %>
8. <%@ page import="com.novell.nidp.resource.*" %>
9. <%@ page import="com.novell.nidp.resource.jsp.*" %>
10.<%@ page import="com.novell.nidp.common.xml.w3c.*" %>
11.<% 12.    response.setHeader("Pragma", "No-cache"); 13.    response.setHeader("Cache-Control", "no-cache"); 14. 15.    Locale locale = request.getLocale(); 16.    String strLanguageCode = locale.getLanguage(); 17.     String strImageDirectory = NIDPResourceManager.getInstance().getImage Directory(locale); 18.    NIDPResource resource = NIDPResourceManager.getInstance().get (JSPResDesc.getInstance(), locale);
19.%>
20.
21.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//<%=strLanguage Code%>">
22.<html lang="<%=strLanguageCode%>">
23.    <head>
24.    <link rel="stylesheet" href="<%= request.getContextPath() %>/images/hf_style.css" type="text/css">
25.    <style type="text/css" media="screen"><!--
26.      #headimage    { position: relative; top: 0px; left: 0px; z-index: 1}
27.      #title    { position: relative; top: 40px; left: 5px; color: white; z-index: 4}
28.      #locallabel    { position: relative; top: 78px; left: 10px; z-index: 4}
29.      #login       { text-align: center }
30.         --></style>
31.    <META HTTP-EQUIV="Content-Language" CONTENT="<%=strLanguageCode%>">
32.    <title><%=resource.getString0(JSPResDesc.LOGIN_TITLE)%></title>
33.    <meta http-equiv="content-type" content="text/html;charset=utf-8">
34.    <script type="text/javascript" src="<%= request.getContextPath() %>/images/showhide_2.js"></script>
35.    <script language="JavaScript">
36.
37.      var i = 0;
38.      function imageSubmit()
39.      {
40.          if (i == 0)
41.          {
42.             i = 1;
43.             document.IDPLogin.submit();
44.          }
45.  
46.          return false;
47.      }
48.  </script>
49.    </head>
50.    <body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" rightmargin="0" onLoad="document.IDPLogin.Ecom_User_ID.focus();" >
51.        <form name="IDPLogin" enctype="application/x-www-form-urlencoded" method="POST" action="<%= (String) request.getAttribute("url") %>" AUTOCOMPLETE="off">
52.        <table style="margin-top: 6em" width="100%" border="0" cellspacing="0" cellpadding="0">
53.        <tr>
54.            <td width="50%" height="80 px">&nbsp;</td>
55.        <td colspan="2"> 56.            <div id="title"><b><%=resource.getString0(JSPResDesc. LOGIN_TITLE)%></b></div>
57.        <div id="locallabel"><b><%=resource.getString0(JSPResDesc. LOCAL_LOGIN)%></b></div>
58.        <div id="headimage"><img src="<%= request.getContextPath() %>/images/Odyssey_LoginHead.gif" alt="" height="80" width="550" border="0"></div>
59.                    </td>
60.        <td width="100%">&nbsp;</td>
61.        </tr>
62.        <tr>
63.            <td width="50%">&nbsp;</td>
64.        <td style="background-color: #efeee9; padding: 10px" colspan="2">
65.<%
66.    String err = (String) request.getAttribute(NIDPConstants.ATTR _LOGIN_ERROR);
67.    if (err != null)
68.    {
69. %>
70.        <div><label><%=err%></label></div>
71. <%  } 
72.     73    // Determine if this login page is being used for account identification 74.    // purposes 75.    String id = (String) request.getAttribute("identify"); 76.    if (id != null && id.equals("true")) 77.    { 78. %> 79.        <div><%=resource.getString0(JSPResDesc.IDENTIFY)%></div> 80. <%  } %>
81.          <span id="login2" style="display: block;">
82.            <table>
83.              <tr>
84.                <td nowrap="nowrap">
85.                  <div>
86.                    <label style="width: 100px"><%=resource.getString0 (JSPResDesc.USERNAME)%></label></label>
87.                  </div>
88.                </td>
89.                <td width="100%" nowrap="nowrap">
90.                  <div>
91.                    <input type="text" class="smalltext" name="Ecom_User_ID" size="30">
92.                  </div>
93.                </td>
94.              </tr>
95.              <tr>
96.                <td nowrap="nowrap">
97.                  <div>
98.                    <label><%=resource.getString0(JSPResDesc.PASSWORD)%></label>
99.                  </div>            
100.                </td>              
101.                <td style="white-space: nowrap">
102.                  <div>
103.                    <input type="password" class="smalltext" name="Ecom_ Password" size="30">&nbsp;&nbsp;
104.                    <input alt="<%=resource.getString0(JSPResDesc.LOGIN)%>" border="0" name="loginButton2" src="<%= request.getContextPath() %>/images/<%=strImageDirectory%>/btnlogin_<%=strImageDirectory%>.gif" type="image" value="Login" onClick="return imageSubmit()">
105.                  </div>            
106.                </td>              
107.              </tr> 108.<% 109.  String prov = (String) request.getAttribute("provision"); 110.  if (prov != null) 111.  { 112.%> 113.              <tr> 114.                <td colspan=2> 115.                  <div> 116.                    <label><a href="<%=prov%>"><%=resource.getString0 (JSPResDesc.CREATE_ACCT)%></a></label> 117.                  </div>             118.                </td>               119.              </tr> 120.<%      } %>
121.            </table>
122.          </span>
123.        </td>
124.        <td width="100%">&nbsp;</td>
125.      </tr> 126. <% 127.  DisplayableProvider[] list = (DisplayableProvider[]) request.get Attribute("providers"); 128.     if (list != null && list.length > 0) 129.     { 130.%> 131.      <tr> 132.        <td width="50%"></td> 133.        <td style="background-color: #efeeec; padding-left: 10px; padding-bottom: 10px"colspan="2"> 134.          <div style="margin-left: -10px; background: url(<%= request.getContextPath() %>/images/dotline_bg.gif) repeat-x">&nbsp;</div> 135.          <div><b><%=resource.getString0(JSPResDesc.FEDERATED_LOGIN)%></b></div> 136.<% 137.    for (int i = 0; i < list.length; i++) 138.    { 139.%> 140.          <a style="padding: 5px" href="<%=list[i].getAuthenticationUrl (request.getContextPath())%>"> 141.<% 142.        if (list[i].hasIcon()) 143.        {          144.%> 145.          <img border=0 class="margin4" alt="<%=XMLUtil.stringToHTML String(list[i].getDisplayName())%>" src="<%=XMLUtil.stringToHTMLString (list[i].getIcon(request))%>" align="absmiddle"></a> 146.<% 147.          } 148.        else  149.        { 150.%>                             151.          <%=XMLUtil.stringToHTMLString(list[i].getDisplayName())%></a> 152.<% 153.        } 154.     155.     } %> 156.        </td> 157.        <td width="100%"></td> 158.      </tr> 159.<%  } %>        
160.        <tr>
161.            <td width="50%"></td>
162.        <td style="background-color: #E6D88C; padding-left: 10px"><img style="padding-right: 200px" src="<%= request.getContextPath() %>/images/LAP_interoperable_logo_100.gif" align="absmiddle" border="0"></td>
163.        <td style="background-color: #E6D88C; padding-right: 10px" align="right" width="100">
164. 165.<% 166.  String cancel = (String) request.getAttribute("cancel"); 167.  if (cancel != null) 168.  { 169.%> 170.                      <input alt="<%=resource.getString0(JSPResDesc. CANCEL)%>" border="0" name="Cancel" src="<%= request.getContextPath() %>/images/<%=strImageDirectory%>/btncancel_<%=strImageDirectory%>.gif" type="image" value="Cancel" tabindex="4"> 171.<%    } 172.      else  173.      {  174.%> 175.            &nbsp; 176.<%    }   %>         
177.        </td>
178.            <td width="100%"></td>
179.        </tr>
180.<%
181.  if (NIDPCripple.isCripple())
182.  {
183.%>        
184.        <tr>
185.               <td colspan=4 width="100%" align="center"><%=NIDPCripple. getCrippleAdvertisement(locale)%></td>
186.        </tr>
187.<%
188.  }
189.%>      
190.         </table>
191.        </form>
192.    </body>
193.</html>

Sample Modified File

The following file shows all the changes that allow 4.0 login.jsp to compile on a 4.0 SP1 Identity Server. The deleted lines have been replaced with returns, so you can line this file up with the original to see the modifications.

<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="com.novell.nidp.common.provider.*" %>
<%@ page import="java.util.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.servlets.*" %>
<%@ page import="com.novell.nidp.resource.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.common.xml.w3c.*" %>
<%
ContentHandler handler = new ContentHandler(request,response);
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//<%=handler.getLanguageCode()%>">
<html lang="<%=handler.getLanguageCode()%>">
    <head>
    <link rel="stylesheet" href="<%= request.getContextPath() %>/images/hf_style.css" type="text/css">
    <style type="text/css" media="screen"><!--
      #headimage    { position: relative; top: 0px; left: 0px; z-index: 1}
      #title    { position: relative; top: 40px; left: 5px; color: white; z-index: 4}
      #locallabel    { position: relative; top: 78px; left: 10px; z-index: 4}
      #login       { text-align: center }
         --></style>
    <META HTTP-EQUIV="Content-Language" CONTENT="<%=handler.getLanguageCode()%>">
    <title><%=handler.getResource(JSPResDesc.TITLE)%></title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <script type="text/javascript" src="<%= request.getContextPath() %>/images/showhide_2.js"></script>
    <script language="JavaScript">

      var i = 0;
      function imageSubmit()
      {
          if (i == 0)
          {
             i = 1;
             document.IDPLogin.submit();
          }
  
          return false;
      }
  </script>
    </head>
    <body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" rightmargin="0" onLoad="document.IDPLogin.Ecom_User_ID.focus();" >
        <form name="IDPLogin" enctype="application/x-www-form-urlencoded" method="POST" action="<%= (String) request.getAttribute("url") %>" AUTOCOMPLETE="off">
        <table style="margin-top: 6em" width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td width="50%" height="80 px">&nbsp;</td>
        <td colspan="2">
            <div id="title"><b><%=handler.getResource(JSPResDesc.TITLE)%></b></div>
        <div id="locallabel"><b><%=handler.getResource(JSPResDesc.PRODUCT)%></b></div>
        <div id="headimage"><img src="<%= request.getContextPath() %>/images/Odyssey_LoginHead.gif" alt="" height="80" width="550" border="0"></div>
                    </td>
        <td width="100%">&nbsp;</td>
        </tr>
        <tr>
            <td width="50%">&nbsp;</td>
        <td style="background-color: #efeee9; padding: 10px" colspan="2">
<%
    String err = (String) request.getAttribute(NIDPConstants.ATTR_LOGIN_ERROR);
    if (err != null)
    {
%>
        <div><label><%=err%></label></div>
<%  } 
    


%>
          <span id="login2" style="display: block;">
            <table>
              <tr>
                <td nowrap="nowrap">
                  <div>
                    <label style="width: 100px"><%=handler.getResource(JSPResDesc.USERNAME)%></label></label>
                  </div>
                </td>
                <td width="100%" nowrap="nowrap">
                  <div>
                    <input type="text" class="smalltext" name="Ecom_User_ID" size="30">
                  </div>
                </td>
              </tr>
              <tr>
                <td nowrap="nowrap">
                  <div>
                    <label><%=handler.getResource(JSPResDesc.PASSWORD)%></label>
                  </div>            
                </td>              
                <td style="white-space: nowrap">
                  <div>
                    <input type="password" class="smalltext" name="Ecom_Password" size="30">&nbsp;&nbsp;
                    <input alt="<%=handler.getResource(JSPResDesc.LOGIN)%>" border="0" name="loginButton2" src="<%=handler.getImage("btnlogin.gif",true)%>" type="image" value="Login" onClick="return imageSubmit()">
                  </div>            
                </td>              
              </tr>





            </table>
          </span>
        </td>
        <td width="100%">&nbsp;</td>
      </tr>


        
        <tr>
            <td width="50%"></td>
        <td style="background-color: #E6D88C; padding-left: 10px"><img style="padding-right: 200px" src="<%= request.getContextPath() %>/images/LAP_interoperable_logo_100.gif" align="absmiddle" border="0"></td>
        <td style="background-color: #E6D88C; padding-right: 10px" align="right" width="100">


        
        </td>
            <td width="100%"></td>
        </tr>
<%
  if (NIDPCripple.isCripple())
  {
%>        
        <tr>
               <td colspan=4 width="100%" align="center"><%=NIDPCripple.getCrippleAdvertisement(request.getLocale())%></td>
        </tr>
<%
  }
%>      
        </table>
        </form>
    </body>
</html>

Modified login.jsp File for Credential Prompts

The following code is a modified version of the 3.1 login.jsp file. It has been modified to add a prompt for the user’s email address.

Such a JSP file must be used with a contract that uses a method that defines the query for the new attribute. The method also needs to define which login file has been modified to display the prompt. For more information about this process, see Customizing the Default Login Page to Prompt for Different Credentials.

The sample code contains the following the text for the prompt:

<td align=left>
   <label>Email Address:</label>
</td>

It also adds an input element for the query variable:

<td align=left>
   <input type="text" class="smalltext" name="Ecom_User_Mail" size="30">
</td>

These elements are both part of the new <tr> element that has been added to the file. These lines are marked in bold in the following sample file.

<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.servlets.*" %>
<%@ page import="com.novell.nidp.resource.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%
    ContentHandler handler = new ContentHandler(request,response);
    String target = (String) request.getAttribute("target");
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//<%=handler.getLanguageCode()%>">
<html lang="<%=handler.getLanguageCode()%>">
  <head>
        <META HTTP-EQUIV="Content-Language" CONTENT="<%=handler.getLanguageCode()%>">
      <meta http-equiv="content-type" content="text/html;charset=utf-8">

    <style type="text/css" media="screen">    
      td label       { font-size: 0.85em ; padding-right: 0.2em; }
      label     { font-size: 0.77em; padding-right: 0.2em; }
         input { font-family: sans-serif; }
      .instructions   { color: #4d6d8b; font-size: 0.8em; margin: 0 10px 10px 0 }
    </style>

       <script type="text/javascript" src="<%= handler.getImage("showhide_2.js",false)%>"></script>
      <script language="JavaScript">
      var i = 0;
      function imageSubmit()
      {
            if (i == 0)
            {  
              i = 1;
              document.IDPLogin.submit();
            }
  
            return false;
      }
    </script>
      </head>
  <body style="background-color: <%=handler.getBGColor()%>" marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" rightmargin="0" onLoad="document.IDPLogin.Ecom_User_ID.focus();" >
        <form name="IDPLogin" enctype="application/x-www-form-urlencoded" method="POST" action="<%= (String) request.getAttribute("url") %>" AUTOCOMPLETE="off">
      <input type="hidden" name="option" value="credential">
<% if (target != null) { %>
      <input type="hidden" name="target" value="<%=target%>">
<% } %>
          <table border=0 style="margin-top: 1em" width="100%" cellspacing="0" cellpadding="0">
            <tr>
            <td style="padding: 0px">
            <table border=0>
              <tr>
                <td align=left>
                  <label><%=handler.getResource(JSPResDesc.USERNAME)%></label>
                </td>
                <td align=left>
                  <input type="text" class="smalltext" name="Ecom_User_ID" size="30">
                </td>
              </tr>
              <tr>
                <td align=left>
                  <label>Email Address:</label>
                </td>
                <td align=left>
                  <input type="text" class="smalltext" name="Ecom_User_Mail" size="30">
                </td>
              </tr>
               <tr>
                <td align=left>
                  <label><%=handler.getResource(JSPResDesc.PASSWORD)%></label>            
                </td>              
                <td align=left>
                  <input type="password" class="smalltext" name="Ecom_Password" size="30">
                </td>              
              </tr>
              <tr>
                <td align=right colspan=2 style="white-space: nowrap">
                  <input alt="<%=handler.getResource(JSPResDesc.LOGIN)%>" border="0" name="loginButton2" src="<%= handler.getImage("btnlogin.gif",true)%>" type="image" value="Login" onClick="return imageSubmit()">
                </td>              
              </tr>
            </table>
          </td>
        </tr>
<%
    String err = (String) request.getAttribute(NIDPConstants.ATTR_LOGIN_ERROR);
    if (err != null)
    {
%>
            <td style="padding: 10px">
            <div class="instructions"><%=err%></div>
            </td>
                    </tr>
<%  } %>
<%
  if (NIDPCripple.isCripple())
  {
%>        
            <tr>
                   <td width="100%" align="center"><%=NIDPCripple.getCrippleAdvertisement(request.getLocale())%></td>
            </tr>
<%
  }
%>      
          </table>
          </form>
      </body>
</html>

Custom nidp.jsp File with Custom Credentials

To create a custom nidp.jsp file that uses custom credentials, you need to modify the nidp.jsp file, create a method and contract for the file, and modify the main.jsp file. For instructions, see Customizing the nidp.jsp File and Adding Logic to the main.jsp File.

Figure 4-3 illustrates the login page that the following custom nidp.jsp file and main.jsp file create.

Figure 4-3 Custom Branding with Custom Credential Prompts

The credential frame uses the same modifications in the sample from Modified login.jsp File for Credential Prompts. The following sections provide the other required sample files to create this login page and information about the required method and contract:

The Modified nidp.jsp File

The background, menu, and border colors are set to black. These colors are specified in the following lines in the sample file:

    // Background color
    String bgcolor   = "#000000";

    // Menu color
    String menucolor   = "#000000";

    // Border color
    String bcolor   = "#000000";

Figure 4-4 illustrates the image (images2.jpeg) that this custom page uses for the header background image:

Figure 4-4 Background Image

This image is the repeatable image that allows the header to be resized. This image is specified in the following lines in the file:

 // The header background image that gets repeated
    String hdrBgndImg  = "/custom_images/images2.jpeg";

Figure 4-5 illustrates the image (images3.jpeg) that this custom page uses for the product logo that appears on left of the header frame.

Figure 4-5 Header Image

Figure 4-6 illustrates the image (hhbimages.jpeg) that this custom page uses to replace the Novell company logo on the right of the header frame.

Figure 4-6 Company Logo

The following lines define what appears as the title for the browser window:

<title>HHB WORLD</title>

The following line defines the header title value:

String hdrTitle     = "Enter MY WORLD";

Its position is controlled by the following line in the file:

 #title { position: absolute; font-size: 1.2em; color: white; top: 18px; left: 85px; }

The top position has been modified from 13px to 18px and the left position has been modified from 55px to 85px. The other lines in this section control the position of the other items in the header.

The lines that have been modified are marked in bold in the following file.

<%
    ContentHandler handler = new ContentHandler(request,response);

    // Background color
    String bgcolor   = "#000000";

    // Menu color
    String menucolor   = "#000000";

    // Border color
    String bcolor   = "#000000";

    // The header background image that gets repeated
    String hdrBgndImg  = "/custom_images/images2.jpeg";

    String hdrImage  = "/custom_images/images3.jpeg";

    String hdrLogo      = "/custom_images/hhbimages.jpeg";

    String hdrTitle     = "Enter MY WORLD";

    String query     =  request.getQueryString();
    if (query != null && query.length() > 0)
        query = "&" + query;
    else query = "";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//Dtd HTML 4.0 transitional//<%=handler.getLanguageCode()%>">
<html lang="<%=handler.getLanguageCode()%>">
    <head>
        <title>HHB WORLD</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <link href="<%= handler.getImage("hf_menu.css",false)%>" rel="stylesheet"> 
        <link href="<%= handler.getImage("HF_message.css",false)%>" rel="stylesheet"> 
        <link href="<%= handler.getImage("HF_obj_list_table.css",false)%>" rel="stylesheet"> 
    <style>
    * { margin: 0; padding: 0; }
        #header    { background-image: url(<%= handler.getImage(hdrBgndImg,false)%>); background-repeat: repeat-x; }
        #logo      { position: absolute; top: 0px; right: 0px;  }       
        #title         { position: absolute; font-size: 1.2em; color: white; top: 18px; left: 85px; }
    #subtitle    { position: relative; font-size: .9em; color: black; white-space: nowrap; top: 0px; left: 0px; text-align: right; }
    #mcontent     { position: relative; padding: 5px; background-color: <%=bgcolor%>; }  
    #content      { width: 100%; border: 0; margin: 0; padding: 0; overflow: none; height: 376px; background-color: <%=bgcolor%>;}
    #logoutbut    { position: absolute; top: 25px; right: 35px;  }      
    #helpbutlogin  { position: absolute; color: yellow; top: 25px; right: 10px; }
    #loggingbut    { position: absolute; color: blue; top: 25px; right: 65px;  }

    .NLtab .tab1s    { background-color: <%=menucolor%>; padding-left: 3px; padding-right: 8px; text-align: center; white-space: nowrap;   }
    .NLtab .tab1s a   { text-decoration: none; }
    .NLtab span.tab1s { padding:5; color: white; font-size: 0.9em; font-weight: bold; line-height: 17px; background-color: transparent; background-image: none; text-decoration: none; }
    .NLtab .tab1u   { background-color: <%=bgcolor%>; padding-left: 3px; padding-right: 3px; text-align: center; white-space: nowrap; border-left: 1px solid <%=bcolor%>; border-right: 1px solid <%=bcolor%>; border-top: 1px solid <%=bcolor%>;          }
    .NLtab span.tab1u { border: none; padding:5; color: black; font-size: 0.8em; font-weight: bold; line-height: 17px; text-decoration: none; background-color: transparent;  }

    .NLtab tr.subtab td  {  color: white; padding: 2px }
    .NLtab tr.subtab a  { font-size: .8em; color: white; text-decoration: none; padding: 2px 5px 2px 5px}

    .selx  { border: 1px solid rgb(239, 238, 236); font-size: 1em; font-weight: bolder; background-repeat: repeat-x; background-position: 0pt bottom;}
    .unselx  { border: 0px; font-size: .9em; font-weight: normal; background-image: none; }
        </style>

        <script>
         var g_curCard = null;     // initial displayed card
     var g_cardContainer = null;   // div that holds all the authentication cards
     var g_curSubtab = null;   // subtab currently displayed
     var g_curTab = null;     // tab currently displayed

         var menuItem = 0;
             function showHide(i)
             {
                 document.getElementById('menu1').style.display='none';
                 document.getElementById('menu2').style.display='none';
                 document.getElementById('submenu1').style.display='none';
                 document.getElementById('submenu2').style.display='none';
                 document.getElementById('menu' + i).style.display='block';
                 document.getElementById('submenu' + i).style.display='block';
         if (i == 1)
             switchContentPage("<%= handler.getJSP("content")%>");
         else 
             switchContentPage("<%= handler.getJSP("IdentityEditor")%>");
             }

     function switchContentPage(newSrc)
     {
           parent.document.getElementById("content").src = newSrc;
     }  

     function onloadhandler()
     {
         g_cardContainer = document.getElementById("cardcontainer");
         g_curSubtab     = document.getElementById("loginsubtab");
         g_curTab        = document.getElementById("authtab");
         g_curCard       = document.getElementById("selectedCard0");
     }  

      function showhideTab(divid)
     {
         var element1 = document.getElementById(divid);  
      
         if(element1.style.display == "none")
         {
             element1.style.display = "block";
         g_curTab.style.display = "none";
          
             g_curTab = element1;
         }
     }

     function subtabchange(divid)
      {
         var element1 = document.getElementById(divid);
         var element2 = g_curSubtab;
         element1.className = "selx";
         if (element1.id != element2.id)
         {
             element2.className = "unselx";
         }
         g_curSubtab = element1;  
     }
      
     function showHelp()
      {
         var helpURL = "login.html";
                 if (g_curSubtab.id == "fedsubtab")
             helpURL = "<%=handler.getHelp("federations.html")%>";

                 else if (g_curSubtab.id == "myprofile")
         helpURL = "<%=handler.getHelp("myprofile.html")%>";

                 else if (g_curSubtab.id == "sharing")
          helpURL = "<%=handler.getHelp("sharing.html")%>";

                 else if (g_curSubtab.id == "loginsubtab")
         helpURL = "<%=handler.getHelp("userlogin.html")%>";

                 else if (g_curSubtab.id == "newcardsubtab")
         helpURL = "<%=handler.getHelp("newcard.html")%>";

               else if (g_curSubtab.id == "logTicketsubtab")
             helpURL = "<%=handler.getHelp("logticket.html")%>";

             var w;
             w = window.open(helpURL, "nidsPopupHelp", "toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=500");
             if (w != null)
             {
              w.focus();
             }
     }
        </script>
    </head>

    <body onload="onloadhandler()">
        <table width=100% border=0 cellpadding=0 cellspacing=0 bgcolor=<%=bgcolor%> >
            <tr>
        <td>
            <table cellspacing=0 width=100% border=0>
            <tr>
            <td width=100%>   
                <div id="header"><img src="<%=handler.getImage(hdrImage,false)%>"></div>   
                <div id="logo"><img src="<%=handler.getImage(hdrLogo,false)%>"></div>   
                <div id="title"><%=hdrTitle%></div>
            </td>
        </tr>
        </table>
        </td>
    </tr>
    <tr>
        <td>
            <table cellspacing=5 width=100%>
            <tr>
            <td>
                <%@ include file="menus.jsp" %>
            </td>
        </tr>
        </table>
        </td>
    </tr>
    <tr>
        <td>
            <table cellspacing=0 border=0 width=100%>
            <tr>
            <td>
                         <iframe scrolling=no id="content" src="<%=handler.addCardParm(handler.getJSP(handler.isJSPMsg() ? handler.getJSPMessage().getJSP() : NIDPConstants.JSP_CONTENT)) + query%>" frameborder=0></iframe>
            </td>
        </tr>
        </table>
        </td>
    </tr>
    </table>
    </body>
</html>
The Modified main.jsp File

The following sample file has two types of modifications. The following line has been added so that the URI of the contract can be read and used as a condition for selecting the login page to display:

String strContractURI = hand.getContractURI();

The following lines define the login page to use when the URI of the contract is set to login/custom.

else if(strContractURI != null && strContractURI.equals("login/custom"))
    {
%>
     <%@ include file="custom.jsp" %>

<%  }

The lines that have been added are marked in bold in the following file.

<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%@ page import="com.novell.nidp.common.util.*" %>
<%@ page import="com.novell.nidp.liberty.wsf.idsis.apservice.schema.*" %>

<%
    ContentHandler hand = new ContentHandler(request,response);
    String strContractURI = hand.getContractURI();

    // Is there a JSP defined on a class definition or a method definition 
    // that should be displayed as the main jsp here?
    if (hand.contractDefinesMainJSP())
    {
%>

        <%@ include file="mainRedirect.jsp" %>
<%  }

else if(strContractURI != null && strContractURI.equals("login/custom"))
    {
%>
     <%@ include file="custom.jsp" %>

<%  }

    // This is the jsp used by default
    else
    {
%>
        <%@ include file="nidp.jsp" %>
<%  }  %>
The Method and the Contract

After modifying the two files, you still need to create a method and a contract. The method needs to use a name/password class and have the following properties defined:

  • Query property values:

    Property Name: Query

    Property Value: (&(objectclass=person)(mail=%Ecom_User_Mail%))

  • JSP property values:

    Property Name: JSP

    Property Value: <filename>

    Replace <filename> with the name of your login page that modifies the credential prompts. Do not include the JSP extension in the value.

You then need to create a contract that uses this method and assign it to a protected resource.

Custom 3.1 login.jsp File

To create this type of page, you need to start with the login.jsp file that ships with Access Manager 3.1 and then add the required code for a header. Figure 4-7 illustrates such a page.

Figure 4-7 Custom Page Derived from the 3.1 login.jsp File

To create this page, see the following sections:

The Modified login.jsp File

This custom page does not modify the credential frame. The lines that define the window title (HHB CUSTOM LOGIN), the page header title (IT’S A NEW WORLD), and the image (hhbimages.png) are marked in bold in the following sample file.

<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.servlets.*" %>
<%@ page import="com.novell.nidp.resource.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%
    ContentHandler handler = new ContentHandler(request,response);
    String target = (String)request.getAttribute("target");
    String hdrImage = "/custom_images/hhbimages.jpeg";

 %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//<%=handler.getLanguageCode()%>">
<html lang="<%=handler.getLanguageCode()%>">
   <head>
            <title>HHB CUSTOM LOGIN </title>
      <META HTTP-EQUIV="Content-Language" CONTENT="<%=handler.getLanguageCode()%>">
      <meta http-equiv="content-type" content="text/html;charset=utf-8">
             


      <style type="text/css" media="screen">
         

         td label       { font-size: 0.85em ; padding-right: 0.2em; }
         label       { font-size: 0.77em; padding-right: 0.2em; }
            input { font-family: sans-serif; }
         .instructions  { color: #4d6d8b; font-size: 0.8em; margin: 0 10px 10px 0 }
      </style>

      <script type="text/javascript" src="<%= handler.getImage("showhide_2.js",false)%>"></script>
      <script language="JavaScript">
         var i = 0;
         function imageSubmit()
         {
             if (i == 0)
             {
                i = 1;
                document.IDPLogin.submit();
             }
  
             return false;
         }
      </script>
      </head>
   <body text="lightcyan" style="background-color:Black" marginwidth="300" marginheight="100" leftmargin="350" topmargin="0" rightmargin="0" onLoad="document.IDPLogin.Ecom_User_ID.focus();" >
   <br>
         <h1><u>       IT'S A NEW WORLD</u></h1>
        
       <form name="IDPLogin" enctype="application/x-www-form-urlencoded" method="POST" action="<%= (String) request.getAttribute("url") %>" AUTOCOMPLETE="off">
         <input type="hidden" name="option" value="credential">
<% if (target != null) { %>
         <input type="hidden" name="target" value="<%=target%>">
<% } %>
            <table border=0 style="margin-top: 1em" width="20" cellspacing="0" cellpadding="0">
                               <tr>
                                   <div id="headimage"><img src="<%=handler.getImage(hdrImage,false)%>" alt="" height="80" width="150" border="0"></div>
                                             </tr>
                                        <tr>
                          
                                       <td style="padding: 0px">
                  <table border=0>
                  <br><br>

                     <tr>
                        <td align=center>
                           <label><%=handler.getResource(JSPResDesc.USERNAME)%></label>
                        </td>
                        <td align=center>
                           <input type="text" class="smalltext" name="Ecom_User_ID" size="30">
                        </td>
                     </tr>
                     <tr>
                        <td align=center>
                           <label><%=handler.getResource(JSPResDesc.PASSWORD)%></label>                  
                        </td>                   
                        <td align=center>
                           <input type="password" class="smalltext" name="Ecom_Password" size="30">
                        </td>
                     </tr>
                     <tr>
                        <td align=right colspan=2 style="white-space: nowrap">
                           <input alt="<%=handler.getResource(JSPResDesc.LOGIN)%>" border="0" name="loginButton2" src="<%= handler.getImage("btnlogin.gif",true)%>" type="image" value="Login" onClick="return imageSubmit()">
                        </td>                   
                     </tr>
                  </table>
               </td>
            </tr>
<%
    String err = (String) request.getAttribute(NIDPConstants.ATTR_LOGIN_ERROR);
    if (err != null)
    {
%>
               <td style="padding: 10px">
                  <div class="instructions"><%=err%></div>
               </td>
                     </tr>
<%  } %>
<%
   if (NIDPCripple.isCripple())
   {
%>        
               <tr>
                     <td width="100%" align="center"><%=NIDPCripple.getCrippleAdvertisement(request.getLocale())%></td>
               </tr>
<%
   }
%>
            </table>
         </form>
      </body>
</html>
The Method and the Contract

After modifying the file, you still need to create a method and a contract. The method needs to use a name/password class and have the following properties defined:

  • JSP property values:

    Property Name: JSP

    Property Value: <filename>

    Replace <filename> with the name of your custom login page. Do not include the JSP extension in the value.

  • MainJSP property values:

    Property Name: MainJSP

    Property Value: true

You then need to create a contract that uses this method and assign it to a protected resource.

Custom login.jsp File

To create this type of page, you need to start with the login.jsp file that shipped with Access Manager 4.0. This file needs to be modified to run on Access Manager 3.1.x. For instructions, see Modifying the File.

Figure 4-8 illustrates a page that has been modified to remove the Novell branding and logo. It has also been modified to prompt the user for an e-mail address in addition to a username and password.

Figure 4-8 Custom Page Derived from the 3.0 login.jsp File

To create this page, see the following sections:

Modifying the File

The bold lines in the following sample file are the lines that have been modified to change the branding and the login prompts.

<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="com.novell.nidp.common.provider.*" %>
<%@ page import="java.util.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.servlets.*" %>
<%@ page import="com.novell.nidp.resource.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.common.xml.w3c.*" %>
<%
    ContentHandler handler = new ContentHandler(request,response);
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//<%=handler.getLanguageCode()%>">
<html lang="<%=handler.getLanguageCode()%>">
    <head>
    <link rel="stylesheet" href="<%= request.getContextPath() %>/images/hf_style.css" type="text/css">
    <style type="text/css" media="screen"><!--
      #headimage    { position: relative; top: 0px; left: 0px; z-index: 1}
      #title    { position: relative; top: 40px; left: 5px; color: white; z-index: 4}
      #locallabel    { position: relative; top: 78px; left: 10px; z-index: 4}
      #login       { text-align: center }
         --></style>
    <META HTTP-EQUIV="Content-Language" CONTENT="<%=handler.getLanguageCode()%>">
    <title>MY WORLD</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <script type="text/javascript" src="<%= request.getContextPath() %>/images/showhide_2.js"></script>
    <script language="JavaScript">

      var i = 0;
      function imageSubmit()
      {
          if (i == 0)
          {
             i = 1;
             document.IDPLogin.submit();
          }
  
          return false;
      }
  </script>
    </head>
    <body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" rightmargin="0" onLoad="document.IDPLogin.Ecom_User_ID.focus();" >
        <form name="IDPLogin" enctype="application/x-www-form-urlencoded" method="POST" action="<%= (String) request.getAttribute("url") %>" AUTOCOMPLETE="off">
        <table style="margin-top: 6em" width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td width="50%" height="80 px">&nbsp;</td>
        <td colspan="2">
            <div id="title"><b>HHB Partner</b></div>
        <div id="locallabel"><b>My Company</b></div>
        <div id="headimage"><img src="<%= request.getContextPath() %>/images/Odyssey_Head.gif" alt="" height="80" width="550" border="0"></div>
                    </td>
        <td width="100%">&nbsp;</td>
        </tr>
        <tr>
            <td width="50%">&nbsp;</td>
        <td style="background-color: #efeee9; padding: 10px" colspan="2">
<%
    String err = (String) request.getAttribute(NIDPConstants.ATTR_LOGIN_ERROR);
    if (err != null)
    {
%>
        <div><label><%=err%></label></div>
<%  } 
    
    // Determine if this login page is being used for account identification
    // purposes
 %>
          <span id="login2" style="display: block;">
            <table>
              <tr>
                <td nowrap="nowrap">
                  <div>
                    <label style="width: 100px"><%=handler.getResource(JSPResDesc.USERNAME)%></label></label>
                  </div>
                </td>
                <td width="100%" nowrap="nowrap">
                  <div>
                    <input type="text" class="smalltext" name="Ecom_User_ID" size="30">
                  </div>
                </td>
              </tr>
              <tr>
                <td nowrap="nowrap">
                  <div>
                    <label style="width: 100px">Email Address:</label></label>
                  </div>
                </td>
                <td width="100%" nowrap="nowrap">
                  <div>
                    <input type="text" class="smalltext" name="Ecom_User_Mail" size="30">
                  </div>
                </td>
              </tr>

              <tr>
                <td nowrap="nowrap">
                  <div>
                    <label><%=handler.getResource(JSPResDesc.PASSWORD)%></label>
                  </div>            
                </td>              
                <td style="white-space: nowrap">
                  <div>
                    <input type="password" class="smalltext" name="Ecom_Password" size="30">&nbsp;&nbsp;
                    <input alt="<%=handler.getResource(JSPResDesc.LOGIN)%>" border="0" name="loginButton2" src="<%=handler.getImage("btnlogin.gif",true)%>"
 type="image" value="Login" onClick="return imageSubmit()">
                  </div>            
                </td>              
              </tr>
            </table>
          </span>
        </td>
        <td width="100%">&nbsp;</td>
      </tr>
    
        <tr>
            <td width="50%"></td>
        <td style="background-color: #E6D88C; padding-left: 10px"><img style="padding-right: 200px" src="<%= request.getContextPath() %>/images/LAP_interoperable_logo_100.gif" align="absmiddle" border="0"></td>
        <td style="background-color: #E6D88C; padding-right: 10px" align="right" width="100">

         
        </td>
            <td width="100%"></td>
        </tr>
<%
  if (NIDPCripple.isCripple())
  {
%>        
        <tr>
               <td colspan=4 width="100%" align="center"><%=NIDPCripple.getCrippleAdvertisement(request.getLocale())%></td>
        </tr>
<%
  }
%>      
        </table>
        </form>
    </body>
</html>
The Method and the Contract

After modifying the file, you still need to create a method and a contract. The method needs to use a name/password class and have the following properties defined:

  • Query property values:

    Property Name: Query

    Property Value: (&(objectclass=person)(mail=%Ecom_User_Mail%))

  • JSP property values:

    Property Name: JSP

    Property Value: <filename>

    Replace <filename> with the name of your custom login page. Do not include the JSP extension in the value.

  • MainJSP property values:

    Property Name: MainJSP

    Property Value: true

You then need to create a contract that uses this method and assign it to a protected resource.