The Java EE 5 Tutorial

Example: Using Form-Based Authentication with a JSP Page

This example discusses how to use form-based authentication with a basic JSP page. With form-based authentication, you can customize the login screen and error pages that are presented to the web client for authentication of their user name and password. When a user submits their name and password, the server determines if the user name and password are those of an authorized user and, if authorized, sends the requested web resource. If the topic of authentication is new to you, please refer to the section Specifying an Authentication Mechanism.

In general, the following steps are necessary for adding form-based authentication to an unsecured JSP page, such as the one described in Web Modules. In the example application included with this tutorial, many of these steps have been completed for you and are listed here simply to show what needs to be done should you wish to create a similar application. The completed version of this example application can be found in the directory tut-install/javaeetutorial5/examples/web/hello1_formauth/.

    The following steps describe how to set up your system for running the example applications, describe the sample application, and provide the steps for compiling, packaging, deploying, and testing the example application.

  1. If you have not already done so, set up your system so that the Ant tool and/or NetBeans IDE will run properly. To do this, follow the instructions in Building the Examples. This step is necessary to set the properties that are specific to your installation of the Application Server and Java EE 5 Tutorial.

  2. If you have not already done so, add an authorized user to the Application Server. For this example, add users to the file realm of the Application Server and assign the user to the group user. This topic is discussed more in Adding Authorized Roles and Users.

  3. Create a web module as described in Web Modules. The subsequent steps discuss adding security to this basic application. The resulting application is found in the directory tut-install/javaeetutorial5/examples/web/hello1_formauth/.

  4. Create the login form and login error form pages. Files for the example application can be viewed at tut-install/javaeetutorial5/examples/web/hello1_formauth/web. These pages are discussed in Creating the Login Form and the Error Page.

  5. Create a web.xml deployment descriptor and add the appropriate security elements (the application on which this section is based did not originally require a deployment descriptor.) The deployment descriptor for the example application can be viewed at tut-install/javaeetutorial5/examples/hello1_formauth/web/WEB-INF. The security elements for the web.xml deployment descriptor are described in Specifying a Security Constraint.

  6. Map the role name defined for this resource (loginUser) to a group of users defined on the Application Server. For more information on how to do this, read Mapping Application Roles to Application Server Groups.

  7. Build, package, deploy, and run the web application by following the steps in Building, Packaging, and Deploying the Form-Based Authentication Example Using NetBeans IDE or Building, Packaging, and Deploying the Form-Based Authentication Example Using Ant.

  8. Test the web client, following the steps in Testing the Form-Based Authentication Web Client.

Creating a Web Client for Form-Based Authentication

The web client in this example is a standard JSP page, and annotations are not used in JSP pages because JSP pages are compiled as they are presented to the browser. Therefore, none of the code that adds form-based authentication to the example is included in the web client. The code for the JSP page used in this example, hello1_formauth/web/index.jsp, is exactly the same as the code used for the unsecured JSP page from the example application at tut-install/javaeetutorial5/examples/web/hello1/web/index.jsp.

The information that adds form-based authentication to this example is specified in the deployment descriptor. This information is discussed in Specifying a Security Constraint.

Creating the Login Form and the Error Page

When using form-based login mechanisms, you must specify a page that contains the form you want to use to obtain the user name and password, as well as which page to display if login authentication fails. This section discusses the login form and the error page used in this example. The section Specifying a Security Constraint shows how you specify these pages in the deployment descriptor.

The login page can be an HTML page, a JSP page, or a servlet, and it must return an HTML page containing a form that conforms to specific naming conventions (see the Java Servlet 2.5 specification for more information on these requirements). To do this, include the elements that accept user name and password information between <form></form> tags in your login page. The content of an HTML page, JSP page, or servlet for a login page should be coded as follows:

<form method=post action="j_security_check" >
    <input type="text"  name= "j_username" >
    <input type="password"  name= "j_password" >
</form>

The full code for the login page used in this example can be found at tut-install/javaeetutorial5/examples/web/hello1_formauth/web/logon.jsp. An example of the running login form page is shown later in Figure 30–6. Here is the code for this page:

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

<h2>Hello, please log in:</h2>
<br><br>
<form action="j_security_check" method=post>
    <p><strong>Please Enter Your User Name: </strong>
    <input type="text" name="j_username" size="25">
    <p><p><strong>Please Enter Your Password: </strong>
    <input type="password" size="15" name="j_password">
    <p><p>
    <input type="submit" value="Submit">
    <input type="reset" value="Reset">
</form>
</html>

The login error page is displayed if the user enters a user name and password combination that is not authorized to access the protected URI. For this example, the login error page can be found at tut-install/javaeetutorial5/examples/web/hello1_formauth/web/logonError.jsp. For this example, the login error page explains the reason for receiving the error page and provides a link that will allow the user to try again. Here is the code for this page:

<html>
<head>
    <title>Login Error</title>
</head>
<body>
    <c:url var="url" value="/index.jsp"/>
    <h2>Invalid user name or password.</h2>

    <p>Please enter a user name or password that is authorized to access this 
    application. For this application, this means a user that has been created in the 
    <code>file</code> realm and has been assigned to the <em>group</em> of 
    <code>user</code>.  Click here to <a href="${url}">Try Again</a></p>
</body>
</html>

Specifying a Security Constraint

This example takes a very simple JSP page-based web application and adds form-based security to this application. The JSP page is exactly the same as the JSP page used in the example described in Web Modules. All security for this example is declared in the deployment descriptor for the application. A security constraint is defined in the deployment descriptor that tells the server to send a login form to collect user data, verify that the user is authorized to access the application, and, if so, display the JSP page to the user.

If this client were a web service endpoint and not a JSP page, you could use annotations to declare security roles and to specify which roles were allowed access to which methods. However, there is no resource injection in JSP pages, so you cannot use annotations and must use the equivalent deployment descriptor elements.

Deployment descriptor elements are described in Declaring Security Requirements in a Deployment Descriptor.

The following sample code shows the deployment descriptor used in this example of form-based login authentication, which can be found in tut-install/javaeetutorial5/examples/web/hello1_formauth/web/WEB-INF/web.xml.

<!-- FORM-BASED LOGIN AUTHENTICATION EXAMPLE -->
<?xml version="1.0" encoding="UTF-8"?>
 <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>hello1_formauth</display-name>
       <servlet>
             <display-name>index</display-name>
            <servlet-name>index</servlet-name>
            <jsp-file>/index.jsp</jsp-file>
      </servlet>
     <security-constraint>
             <display-name>SecurityConstraint</display-name>
            <web-resource-collection>
                  <web-resource-name>WRCollection</web-resource-name>
                 <url-pattern>/*</url-pattern>
         </web-resource-collection>
            <auth-constraint>
                  <role-name>loginUser</role-name>
            </auth-constraint>
            <user-data-constraint>
                <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
       </security-constraint>
      <login-config>
            <auth-method>FORM</auth-method>
         <form-login-config>
                  <form-login-page>/logon.jsp</form-login-page>
                 <form-error-page>/logonError.jsp</form-error-page>
          </form-login-config>
     </login-config>
     <security-role>
        <role-name>loginUser</role-name>
    </security-role>
</web-app>

More description of the elements that declare security in a deployment descriptor can be found in Specifying Security Constraints.

Protecting Passwords with SSL

Passwords are not protected for confidentiality with HTTP basic or form-based authentication, meaning that passwords sent between a client and a server on an unprotected session can be viewed and intercepted by third parties. To overcome this limitation, you can run these authentication protocols over an SSL-protected session and ensure that all message content is protected for confidentiality.

A <transport-guarantee> element indicates whether or not the protected resources should travel over protected transport. For simplicity, this example does not require protected transport, but in a real world application, you would want to set this value to CONFIDENTIAL to ensure that the user name and password are not observed during transmission. When running on protected transport, you can run the application over the secure SSL protocol, https, and specify the secure port where your SSL connector is created (the default for the Application Server is 8181). If you do not specify the HTTPS protocol, the server will automatically redirect the application to the secure port.

Adding Authorized Roles and Users

To authenticate a user and allow that user access to protected resources on the Application Server, you must link the roles defined in the application to the users defined for the Application Server.

When an application is deployed, the application-specific security roles are mapped to security identities in the runtime environment, such as principals (identities assigned to users as a result of authentication) or groups. Based on this mapping, a user who has been assigned a certain security role has associated access rights to a web application deployed onto a server.

As shown in the deployment descriptor for this example application, the security constraint specifies that users assigned to the role of loginUser are authorized to access any of the files in the hello1_formauth application. In this example, when a resource that is constrained by this same security constraint is accessed, for example, hello1_formauth/web/index.jsp, the Application Server sends the login form, receives the login information, and checks to see if the user is in a group that has been mapped to the role of loginUser. If the user name and password are those of an authorized user, access to the resource is granted to the requester.

    To set up users for this example application, follow these steps:

  1. Using the Admin Console, create a user in the file realm of the Application Server and assign that user to the group user. Make sure to note the user name and password that you enter in this step so that you can use it for testing the application later (these fields are case-sensitive). If you need help with the steps required to accomplish this task, read Managing Users and Groups on the Application Server for more information.

  2. Map the application security role of loginUser to the group of user that has been configured on the Application Server. For more information on how to do this mapping, read Mapping Application Roles to Application Server Groups.

Mapping Application Roles to Application Server Groups

Map the role of loginUser defined in the application to the group of user defined on the Application Server by adding a security-role-mapping element to the sun-web.xml runtime deployment descriptor file. To deploy a WAR on the Application Server, the WAR file must contain a runtime deployment descriptor. The runtime deployment descriptor is an XML file that contains information such as the context root of the web application and the mapping of the portable names of an application’s resources to the Application Server’s resources.

The runtime deployment descriptor for this example, tut-install/javaeetutorial5/examples/web/hello1_formauth/web/WEB-INF/sun-web.xml, looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC 
"-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" 
"http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app>
    <context-root>/hello1_formauth
</context-root>
    <security-role-mapping>
        <role-name>loginUser</role-name>
        <group-name>user</group-name>
    </security-role-mapping>
</sun-web-app>

Building, Packaging, and Deploying the Form-Based Authentication Example Using NetBeans IDE

    To build, package, and deploy this application using NetBeans IDE, follow these steps:

  1. Follow the instructions in Building the Examples if you have not already done so. This step is necessary to provide the Ant targets with the location of your tutorial and Application Server installations.

  2. Add users to the file realm of the Application Server as described in Adding Authorized Roles and Users if you have not already done so.

  3. Open the project in NetBeans IDE by selecting File->Open Project.

  4. Browse to the tut-install/javaeetutorial5/examples/web/hello1_formauth/ directory.

  5. Make sure that Open as Main Project is selected.

  6. Select Open Project.

  7. If you are prompted to regenerate the build-impl.xml file, select the Regenerate button.

  8. Right-click hello1_formauth in the Projects pane, then select Clean and Build.

  9. Right-click hello1_formauth in the Projects pane, then select Undeploy and Deploy.

  10. Follow the steps in Testing the Form-Based Authentication Web Client.

Building, Packaging, and Deploying the Form-Based Authentication Example Using Ant

    To build, package, and deploy this application using the Ant tool, follow these steps:

  1. Follow the instructions in Building the Examples if you have not already done so. This step is necessary to provide the Ant targets with the location of your tutorial and Application Server installations.

  2. Add users to the file realm of the Application Server as described in Adding Authorized Roles and Users if you have not already done so.

  3. From a terminal window or command prompt, change to the tut-install/javaeetutorial5/examples/web/hello1_formauth/ directory.

  4. Enter the following command at the terminal window or command prompt:


    ant
    

    This target will spawn any necessary compilations, copy files to the tut-install/javaeetutorial5/examples/web/hello1_formauth/build/ directory, create the WAR file, and copy it to the tut-installjavaeetutorial5/examples/web/hello1_formauth/dist/ directory.

  5. Deploy the WAR named hello1_formauth.war onto the Application Server using Ant by entering the following command at the terminal window or command prompt:


    ant deploy
    
  6. Follow the steps in Testing the Form-Based Authentication Web Client.

Testing the Form-Based Authentication Web Client

    To run the web client, follow these steps:

  1. Open a web browser.

  2. Enter the following URL in your web browser:

    http://localhost:8080/hello1_formauth

    Note –

    If you set the transport guarantee to CONFIDENTIAL as discussed in Protecting Passwords with SSL, you must load the application in a web browser using https for the protocol, the HTTPS port that you specified during installation for the port (by default this port is 8181), and the context name for the application you wish to run. For the form-based authentication example, you could run the example using the following URL: https://localhost:8181/hello1_formauth.


    The login form displays in the browser, as shown in Figure 30–6.

  3. Enter a user name and password combination that corresponds to a user that has already been created in the file realm of the Application Server and has been assigned to the group of user, as discussed in Adding Authorized Roles and Users.

  4. Click the Submit button. Form-based authentication is case-sensitive for both the user name and password, so enter the user name and password exactly as defined for the Application Server.

    If you entered My_Name as the name and My_Pwd for the password, the server returns the requested resource if all of the following conditions are met:

    • There is a user defined for the Application Server with the user name of My_Name.

    • The user with the user name of My_Name has a password of My_Pwd defined for the Application Server.

    • The user My_Name with the password My_Pwd is assigned to the group of user on the Application Server.

    • The role of loginUser, as defined for the application, is mapped to the group of user, as defined for the Application Server.

      When these conditions are met, and the server has authenticated the user, the application will display as shown in Figure 30–7.

  5. Enter your name and click the Submit button. Because you have already been authorized, the name you enter in this step does not have any limitations. You have unlimited access to the application now.

    The application responds by saying “Hello” to you, as shown in Figure 30–8.

Figure 30–6 Form-Based Login Page

Screen shot of form-based login page showing text fields
for user name and password

Figure 30–7 Running Web Application

Screen shot of running form-based web application with
text field for user to type name

Figure 30–8 The Running Form-Based Authentication Example

Screen shot of running form-based web application showing
response


Note –

For repetitive testing of this example, you may need to close and reopen your browser. You should also run the ant clean and ant undeploy commands to ensure a fresh build if using the Ant tool, or select Clean and Build then Undeploy and Deploy if using NetBeans IDE.