This article describes how to make a login feature for your application, which uses database tables for authentication and authorization.....

I have made this loginmodule from examples of the AMIS adf training and i have made use of the DBLoginModule class which Frank Nimphius and Duncan Mills build.

First thing we need to build is the tables in the database.

Tables

The loginmodule uses three tables.
1 table for users: which we call AMIS_STAFF
1 table for roles: which we call ROLES
1 table for association between the AMIS_STAFF and the ROLES tables
So make the tables in your database. The picture bellow shows how you could make it.

Authorization

Before we configure the authorization of your webapplication we need to make a new application.

So build a new application.
- Call the new application: SecureWebApp
- Directory name: c:\projects\SecureWebApp
- Application Package Prefix: nl.amis.als.secureWebApp
- Application Template: Web Application[JSF, ADF BC]
(these are just my settings, change them if you like)

- ok now we have an application
- make a new jsp page and call it: login.jsp
- save the page in …..\public_html\security\pages
- the source of the page look like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Login</title>
  </head>
  <body style="font-family:sans-serif; background-color:rgb(214,231,255); color:rgb(0,0,255);">
 
    <form action="j_security_check" method="post">
              <table cellspacing="3" cellpadding="2" border="0" width="100%">
                <tr>
                  <td width="120">
                    <b style="whitespace:nowrap">Username</b>
                  </td>
                  <td>
                    <input type="text" name="j_username"/>
                  </td>
                </tr>
                <tr>
                  <td width="120">
                    <b>Password</b>
                  </td>
                  <td>
                    <input type="password" name="j_password"/>
                  </td>
                </tr>
                <tr>
                  <td></td>
                  <td>
                    <input type="submit" name="logon" value="Sign On"/>
                  </td>
                </tr>
    </table>
    </form>

    <p>
      (c) AMIS – (2002-2006) – <a href="http://www.amis.nl">http://www.amis.nl</a>
    </p>
 </body>
</html>

Now we have a login page. The next thing is to make the correct settings to use the page, the proper constraints and the roles.

Roles

Select the web.xml of your project and click rightmousebutton, select properties.
Select the Security Roles, add several roles, for example MANAGER, USER.
An important note is that the entered roles in your security roles, has to be exact the same as in the ROLES table we’ve made in the database.

Constraints

Select the web.xml of your project and click rightmousebutton, select properties.
Select Security Contraints, make a new constraint.
Select the new made constraint and add an Url Pattern. An example: /faces/pages/*.
The constraint is made, now we need to add roles to the constraint.
Select the Auhtorization tab and select the roles which use the constraint.

Login configuration

Select the web.xml of your project and click rightmousebutton, select properties.
Select the Login Configuration: Form-Based Authentication 
Enter the next settings:
Login page: /faces/security/pages/login.jsp
Error page: /faces/security/pages/login.jsp

Authentication

Install jar file
We need to download a loginmodule, which we add a java class.
The file is available at a blog about a login configuration with an pl/sql procedure: http://technology.amis.nl/blog/?p=1462 or direct from: http://technology.amis.nl/wp-content/uploads/images/JaasSecureWebApp.zip
The file we needed is: jaasdatabaseloginmodule.zip
Download the file
Unzip the file and run the project, the project should look like this:

Ok now we are making a new java class in: oracle.sample.dbloginmodule.DBTableLM
The name of the file is: ALSDBTableLoginModule
The result should look like this:
 

Now we open the DBTableLoginModule.java file and copy paste all code into: ALS DBTableLoginModule.
The code we just pasted into our new class will be adjusted to our preferences.
First the need to adjust the class name: public class DBTableLoginModule implements DBLoginModule into: public class ALSDBTableLoginModule implements DBLoginModule.
The file should be correct at this point (so no file errors should occur if you run the file).
The performDbAuthentication is the only thing we adjust in the java class, the code of the method is as follow:
 
  protected boolean performDbAuthentication(String username, char[] password)
  {
    boolean success = false;
    Connection conn = null;
    Statement stmt = null;
    ResultSet rset = null;
    ArrayList _dbauth = new ArrayList();

    String _sqlStatement = "select roles.ROLENAME, amis_staff.USERNAME FROM roles LEFT JOIN userrole ON roles.ID = userrole.ROLE LEFT JOIN amis_staff ON userrole.EMPLOYEE = amis_staff.ID WHERE amis_staff.USERNAME = ‘" + username + "’ AND amis_staff.PASSWORD = ‘" + new String(password) + "’";

    try
    {
      try
      {
        //database connection from the data-sources.xml file
        Context ic;
        try
        {
          ic = new InitialContext();
          DataSource dataSource = (DataSource) ic.lookup(_data_source_name);
          conn = dataSource.getConnection();
        }
        catch (NamingException e)
        {
           System.err.println(e.getMessage());
        }

        stmt = conn.createStatement();
        rset = stmt.executeQuery(_sqlStatement);
  
        while (rset.next())
        {
          success = true; 
          String rolename = rset.getString(1);
          String user = rset.getString(2);
                                      
          _dbauth.add(new DBRolePrincipal(rolename));
          _dbauth.add(new DBUserPrincipal(user));
          _authPrincipals=(Principal[]) _dbauth.toArray(new Principal[_dbauth.size()]);

        }

         rset = stmt.executeQuery(_sqlStatement);
         if(!rset.next())
         {
           FacesContext facesContext = FacesContext.getCurrentInstance();
           FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,"Your username and/or password is incorrect! ",null);
           facesContext.addMessage("messages",message);
         }
     }
     catch (SQLException e)
     {
        System.err.println(e.getMessage());
     }
     finally
     {
        rset.close();
        stmt.close();
        conn.close();
     }
    }
    catch (SQLException e)
    {
     System.err.println(e.getMessage());
    }                   
    return success;
  }

Compile the project
Select DBLoginModule.deploy, rightmousebutton and click deploy to JAR file.
The jar has to be used in the library of the project.
Copy the jar file to the jdev\lib map of your jdeveloper installation. For example: C:\Program Files\jdevstudiobase10133\jdev\lib. 
The jar file is ready to use, only we have to make is available in the OC4J container.
So open the application.xml file, located in JDEV_HOME\jdev\system\oracle.j2ee.10.1.3.41.57 \embedded-oc4j\config map.
Replace: <jazn provider="XML"/> by:

<jazn provider="XML"> 
           <property name="custom.loginmodule.provider" value="true"/> 
           <property name="role.mapping.dynamic" value="true"/>
</jazn>

And add: <library path="C:\Program Files\jdevstudiobase10133\jdev\lib\DBLoginModule.jar"/>
 
Configure system-jazn-data.xml

Let’s open the system-jazn-data.xml file in an editor. The file is located in the JDEV_HOME\jdev\system\oracle.j2ee.10.1.3.41.57 \embedded-oc4j\config map.
In the file we add the next lines:
    <application>
      <name>current-workspace-app</name>
     <login-modules>
        <login-module>
          <class>oracle.sample.dbloginmodule.DBTableLM.ALSDBTableLoginModule</class>
          <control-flag>required</control-flag>
          <options>
             <option>
                <name>addAllRoles</name>
                <value>true</value>
             </option>
             <option>
              <name>debug</name>
              <value>true</value>
            </option>
            <option>
              <name>data_source_name</name>
              <value>jdbc/OracleDSSecurity</value>
            </option>
            <option>
              <name>log_level</name>
              <value>ALL</value>
            </option>
          </options>
        </login-module>
      </login-modules>
    </application>

These settings we use to make the ALSDBTableLoginModule class available to the application.

Configure data-source.xml

Let’s open the data-source.xml file in an editor. The file is located in the JDEV_HOME\jdev\system\oracle.j2ee.10.1.3.41.57 \embedded-oc4j\config map.
In the file we add the next lines:
<managed-data-source name="OracleDSSecurity" connection-pool-name="Security Pool" jndi-name="jdbc/OracleDSSecurity"/>

<connection-pool name="Security Pool">
<connection-factory factory-class="oracle.jdbc.pool.OracleDataSource" user="als" password="als" url="jdbc:oracle:thin:@localhost:1521:xe"/>
</connection-pool>
 

User is the database user, and the password is the user’s password.
The url is the url of the database.
These settings we’ve made, are necessary to make a database connection.
 

We are now able to login.