Configuring Web application security in WebSphere Application Server Community Edition V2.0

Configure security for Web applications deployed in IBM® WebSphere® Application Server Community Edition V2.0, a free-to-use Java™ EE 5 certified application server based on Apache Geronimo 2.0.1. This article will get you familiar with the various security realms provided by Community Edition so you can determine and implement the best, most appropriate level of security for your Web applications.

Share:

Vamsavardhana Reddy Chillakuru (vamsic007@in.ibm.com), Advisory Software Engineer, EMC

Vamsavardhana Reddy Chillakuru , a.k.a Vamsi, is an Advisory Software Engineer at IBM India Software Labs in Bangalore, India. He is a committer, a member of the Apache Geronimo Project Management Committee, and is part of the IBM WebSphere Application Server Community Edition Level 3 Support Team. He received his Bachelor of Statistics (Hons.) and Master of Statistics degrees from Indian Statistical Institute, Kolkata, India in the years 1994 and 1996 respectively.


developerWorks Contributing author
        level

Manu T. George (mageorge@in.ibm.com), Staff Software Engineer, IBM

Manu T. George is a Staff Software Engineer at IBM India Software Labs in Bangalore, India. He is a committer on Apache OpenEJB project, and is a part of the IBM WebSphere Application Server Community Edition Level 3 Support Team. He received his Bachelor of Technology in Applied Electronics from the College of Engineering Trivandrum in the year 2001.


developerWorks Contributing author
        level

25 September 2007

Also available in Chinese

Introduction

IBM WebSphere Application Server Community Edition V2.0 (hereafter referred to as Community Edition) is a free-to-use Java Platform, Enterprise Edition 5.0 (Java EE 5) certified application server based on Apache Geronimo 2.0.1. Community Edition uses Java Authentication and Authorization Service (JAAS) login modules for user authentication in Web applications, and Java Authorization Contract for Containers (JACC) for authorization.

Download Community Edition V2.0 now!
IBM WebSphere Application Server Community Edition V2.0 is free to use and deploy. Download it now to get started.

Community Edition readily provides implementations of login modules that enable you to store authentication credentials in a variety of data stores, such as simple text files, databases (like IBM DB2® or Cloudscape™), or LDAP servers (like Apache Directory Server or IBM Tivoli® Directory Server). To access these data stores, you need to create and appropriately configure security realms. This article will show you what is required to create the security realms provided by Community Edition and how to use them to configure Web application security. You will also learn how to enable auditing, lockout on repeated unsuccessful login attempts, and how to store user credentials for later use by the application.

This article requires WebSphere Application Server Community Edition V2.0 or later. Security realms based on login module implementations that either use digital certificates or are user implemented are beyond the scope of this article.

What are JAAS and JACC?

The Java Authentication and Authorization Service (JAAS) implements a Java version of the standard Pluggable Authentication Module (PAM) framework. JAAS simplifies Java security development by putting an abstraction layer between the application and the underlying authentication mechanisms, thereby enabling applications to be independent from the authentication mechanism. New or updated authentication mechanisms can be plugged in without requiring modifications to the application. Applications initiate authentication by instantiating a LoginContext object, which in turn references a configuration that determines the authentication mechanisms or LoginModules to be used in performing the authentication. If authentication is successful, the subject is updated by a LoginModule with relevant principals and credentials.

The Java Authorization Contract for Containers (JACC) specification (JSR-115) defines new java.security.Permission classes to satisfy the Java EE 5 authorization model. JACC enables authorization decisions based on these permission classes.

See Resources for more information on both JAAS and JACC.

The administrative console

The standard administrative console provides a convenient, user friendly way to administer many components and aspects of Community Edition. Several portlets are provided to perform a variety of administration tasks, such as the Security Realms portlet, Applications portlets, DB Manager portlet, and the Database Pools portlet. These portlets will be referred to throughout this article. The admin console also provides portlets that let an administrator monitor or view the status of the server, such as the Information, JVM and DB Info portlets. Once Community Edition is started, you can access the admin console at http://localhost:8080/console. The default login is system with a password of manager.

Security Realms portlet

The Security Realms portlet enables you to add new security realms and edit existing security realms. It also has a usage link that provides information on how applications can be configured to authenticate against the security realm. This article uses the Security Realms portlet to add these new realms:

To launch the Security Realms portlet, select the Security Realms link under the Security heading in the Console Navigation pane (Figure 1).

Figure 1. Console Navigation
Figure 1. Console Navigation

Notice the three links in the Security Realms portlet:

  • The edit action link is for editing an existing security realm.
  • The usage action link is for showing how this security realm can be used in your Java EE application.
  • Add new security realm is for creating a new security realm.

You will use these links in the following sections to create and edit security realms, as well as to view the usage of the security realms that you create.

Applications portlets

There are several Applications portlets, listed under the Applications heading in the Console Navigation pane (Figure 1). These portlets enable you to deploy new Web, EJB, and Java EE applications, plus application clients, Java EE Connectors, and more. You can also start, stop, and uninstall existing applications, connectors, and so on.

This article uses the Deploy New portlet to deploy the included sample Web applications. Click Deploy New under the Applications heading in the Console Navigation pane to launch the portlet (Figure 2).

Figure 2. Deploy New portlet
Figure 2. Deploy New portlet

The Web App WARs portlet (launched by clicking Web App WARs in the Console Navigation pane) lists all the WARs deployed in Community Edition. Use this portlet (Figure 3) to start, stop, restart, or uninstall any of these applications. The Web App WARs portlet also provides a URL that contains the context root to access the running Web application.

Figure 3. Web App WARs portlet
Figure 3. Web App WARs portlet

DB Manager portlet

The DB Manager portlet (Figure 4) enables you to access the Derby database server embedded in Community Edition. Launch and load the DB Manager portlet by clicking the DB Manager link under the Embedded DB heading in the Console Navigation pane (Figure 1).

Figure 4. DB Manager portlet
Figure 4. DB Manager portlet

Using the DB Manager, you can:

  • Create a new embedded Derby database.
  • Delete an existing embedded Derby database.
  • Run SQL queries against an existing Derby database.

You will perform each of these tasks when you create a database realm later in this article.

Database Pools portlet

Launch the Database Pools portlet (Figure 5) by clicking Database Pools under the Services heading in the Console Navigation pane.

Figure 5. Database Pools portlet
Figure 5. Database Pools portlet

Figure 5 shows two database pools, each with links to edit, delete, and get the usage of the pool. The portlet also has links for creating a new database pool Using the Geronimo database pool wizard, as well as for importing existing pools from Weblogic 8.1 and JBoss 4. Later in this article, you will see how to create a database pool using the Geronimo database pool wizard.

Security realms

A security realm, as the name suggests, corresponds to a realm or scope of data to which the authentication information belongs; that is, the domain to which the authentication information applies. Security realms are used for securing access to resources. For example, access to the Community Edition admin console is secured by means of a properties file realm named geronimo-admin. In Community Edition, a security realm is a composition of one or more login modules.

The next sections discuss security realms that can be created using the PropertiesFileLoginModule, SQLLoginModule, and LDAPLoginModule implementations provided by Community Edition:

Properties file realm

A security realm based on PropertiesFileLoginModule is generally referred to as a properties file realm. This is the simplest of security realms provided by Community Edition. Authentication information can be managed using a text editor. The underlying data store that is used by a properties file realm consists of (no prizes for guessing) two properties files. Creating and using a properties file realm consists of the following tasks:

  1. Create properties files

    A properties file realm uses two properties files: one for the user authentication data, referred to as the users properties file, and another for the grouping data, referred to as the groups properties file. Listings 1 and 2 show the contents of dw_users.properties file and dw_groups.properties file, respectively, which are used in this article. Be aware that the usernames used in the groups properties file must also exist in the users properties file. Also, a user may belong to zero or more groups.

    Listing 1. dw_users.properties
    #This is a comment line
    #Entries are in the format username=password and only one entry per line
    #We have five users namely dwadmin, dwuser1, dwuser2, root and john
    dwadmin=admin
    dwuser1=user1
    dwuser2-user2
    root=root
    john=brad1983
    Listing 2. dw_groups.properties
    #This is a comment line
    #Entries are in the format groupname=<comma separated usernames in the group>
    #We have three groups namely Admin, User and Guest
    Admin=dwadmin,root
    User=dwuser1,dwuser2,root
    Guest=john

    To use these files in a security realm, they should be placed in a directory under <WASCE_HOME>, typically under <WASCE_HOME>/var/security. (Here, <WASCE_HOME> refers to the directory in which Community Edition is installed.)

    At this point, extract the contents of the wascesecurity_samples.zip download file, included with this article, to a directory of your choice. (The directory you chose will be referred to as <SAMPLES_HOME>.) Copy dw_users.properties and dw_groups.properties files from the <SAMPLES_HOME> directory to <WASCE_HOME>/var/security.

  2. Create security realm

    To create a properties file realm:

    1. Launch the Security Realms portlet from the Console Navigation pane, then select Add new security realm in the Security Realms pane (Figure 1). The Step 1 panel for creating a security realm (Figure 6) will display.

    2. Enter or select these values:

      • Name of Security Realm: SampleSecurityRealm
      • Realm Type: Properties File Realm

      Click Next.

      Figure 6. Step 1 - Select Name and Type
      Figure 6. Step 1 - Select Name and Type
    3. On the Step 2 panel (Figure 7), enter these values:

      • Users File URI: var/security/dw_users.properties
      • Groups File URI: var/security/dw_groups.properties

      These URI values should be relative to the location of the <WASCE_HOME> directory. Leave the remaining fields blank (they will be discussed later). Click Next.

      Figure 7. Step 2 - Configure Login Module
      Figure 7. Step 2 - Configure Login Module
    4. The Step 3 panel (Figure 8) shows four check box options:

      • Enable Auditing: Logs every attempt to the specified file.
      • Enable Lockout: Locks the user's account for a specified period of time if a certain number of logins fail within a certain time period (all values can be customized).
      • Store Password: When enabled, the security realm stores the authenticating user's username and password in a private credential in the Subject, enabling access to the password later after the login process has completed.
      • Named Credential: When enabled, the security realm stores the authenticating user's username and password in a private credential in the Subject under a specified credential name.

      For now, leave all options unchecked. They will be discussed later in this article.

      Figure 8. Step 3 - Advanced Configuration
      Figure 8. Step 3 - Advanced Configuration
    5. Select Test a Login. The Step 4 panel (Figure 9) will display.

      Figure 9. Step 4 -Test Login
      Figure 9. Step 4 -Test Login
    6. Enter a valid username and password (for this example, use john and brad1983, respectively) and click Next. The success page (Figure 10) will display.

      Figure 10. Step 5 - Login Results
      Figure 10. Step 5 - Login Results
    7. Click Show Plan to see the deployment plan that will be used to deploy this security realm. The deployment plan is shown in Listing 3.

      Listing 3. Security realm deployment plan
      <module xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
         <environment>
            <moduleId>
               <groupId>console.realm</groupId>
               <artifactId>SampleSecurityRealm</artifactId>
               <version>1.0</version>
               <type>car</type>
            </moduleId>
            <dependencies>
               <dependency>
                  <groupId>org.apache.geronimo.configs</groupId>
                  <artifactId>j2ee-security</artifactId>
                  <type>car</type>
               </dependency>
            </dependencies>
         </environment>
         <gbean name="SampleSecurityRealm"
            class="org.apache.geronimo.security.realm.GenericSecurityRealm"
            xsi:type="dep:gbeanType"
            xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <attribute name="realmName">SampleSecurityRealm</attribute>
            <reference name="ServerInfo">
               <name>ServerInfo</name>
            </reference>
            <xml-reference name="LoginModuleConfiguration">
               <log:login-config
                  xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0">
                     <log:login-module control-flag="REQUIRED"
                        wrap-principals="false">
                        <log:login-domain-name>
                           SampleSecurityRealm
                        </log:login-domain-name>
                        <log:login-module-class>
                        org.apache.geronimo.security.realm.providers.
                                PropertiesFileLoginModule
                        </log:login-module-class>
                        <log:option name="groupsURI">
                           var/security/dw_groups.properties
                        </log:option>
                        <log:option name="usersURI">
                           var/security/dw_users.properties
                        </log:option>
                     </log:login-module>
               </log:login-config>
            </xml-reference>
         </gbean>
      </module>

      A few important things to observe in this deployment plan are:

      • moduleId: An ID "console.realm/SampleSecurityRealm/1.0/car" is assigned to the configuration in which this security realm will run.
      • The configuration contains one GBean with the name SampleSecurityRealm, and the realmName attribute matches the name attribute in the gbean tag.
      • The login-module-class is org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule.
      • The options groupsURI and usersURI are specific to PropertiesFileLoginModule.
    8. At this point, you can choose to save the plan to disk and deploy the plan using Deploy New portlet. You will not need to specify an archive to deploy this plan (Figure 2). Simply click the Deploy Realm button to complete the creation of the Security realm. Figure 11 will display.

      Figure 11. Security Realms portlet
      Figure 11. Security Realms portlet

    You have successfully created a properties file realm called SampleSecurityRealm. When a user authenticates against SampleSecurityRealm, the subject will contain a GeronimoUserPrincipal with an authenticated username as the name in the principal, and zero or more GeronimoGroupPrincipals with the groups to which the authenticated username belongs as names in the principals. This security realm runs in a configuration with ID "console.realm/SampleSecurityRealm/1.0/car."

  3. Configure Web application security

    Next, you will see how the security realm created above can be used to configure security in a simple Web application. A Web application's security is usually configured by creating security roles and security constraints in its Java EE specific deployment descriptor web.xml file. These security roles are mapped to principals in a server-specific deployment plan (geronimo-web.xml in the case of Community Edition) used at application deployment time. The sample application used here consists of three JSPs: one with unrestricted access, one accessible by the admin role, and another accessible by user role. The deployment descriptor web.xml for this application is shown in Listing 4.

    Listing 4. web.xml for sample application
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="SimpleWebApp" version="2.5" ... >
        <display-name>SimpleWebApp</display-name>
        <login-config>
            <auth-method>BASIC</auth-method>
            <!-- For 'BASIC', realm-name will be shown in the prompt -->
            <realm-name>Sample Security Realm</realm-name>
        </login-config>
    
        <!-- Security roles used in the application -->
        <security-role><role-name>admin</role-name></security-role>
        <security-role><role-name>user</role-name></security-role>
    
        <!-- Configure authorization for Admin pages -->    
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>Admin</web-resource-name>
                <url-pattern>/admin/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>admin</role-name>
            </auth-constraint>
        </security-constraint>
        <!-- Configure authorization for User pages -->
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>User</web-resource-name>
                <url-pattern>/user/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>user</role-name>
            </auth-constraint>
        </security-constraint>
    </web-app>

    In the web.xml file:

    • <login-config> tag specifies the method used to authenticate the users and any additional required configuration. In this example, the value BASIC for auth-method means the login will be using a dialog box displayed by the browser. For this auth-method, you can optionally specify a value for realm-name, which will be displayed in the dialog for login.
    • <security-role> tag declares the security roles you want to use in this application. There can be zero or more security roles in a application. In this example, two security roles are used: admin and user.
    • <security-constraint> tag declares the authorization constraints for resources and the <url-pattern> tag specifies the URL pattern to which the constraint should apply. In this example, /admin/* means all URLs starting "/admin/" will be subject to this security constraint. Assuming the application is available at http://localhost:8080/simplewebapp, some of the URLs would be http://localhost:8080/simplewebapp/admin/admin.jsp, http://localhost:8080/simplewebapp/admin/another.jsp, and so on. The <auth-constraint> tag specifies the security roles that have access to the URL pattern.

    The <auth-method> tag in login-config (inside application deployment descriptor) enables you to specify the authentication method to be used by the Web application. Valid values are BASIC, DIGEST, FORM, and CLIENT-CERT:

    • When BASIC or DIGEST are specified, the login happens using a browser-specific dialog box. The BASIC auth-method is used in some of the sample applications with this article.

    • For FORM auth-method, login happens using a login page configured using form-login-config. An excerpt from the web.xml file in the SimpleWebApp-LDAP sample application configured for FORM authentication is shown in Listing 5. An example of how the form should be coded into the HTML page is shown in Listing 6.

      Listing 5. login-config
      <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>Not required for FORM auth</realm-name>
        <form-login-config>
          <form-login-page>/login/login.jsp</form-login-page>
          <form-error-page>/login/loginerror.jsp</form-error-page>
        </form-login-config>
      </login-config>
      Listing 6. Login form
      <form method="POST" action="j_security_check">
          <input type="text" name="j_username">
          <input type="text" name="j_password"> 
      </form>

      The action of the login form must always be j_security_check. The j_username input field should be used to get the user name, and the j_password input field should be used to get the user's password.

    • CLIENT-CERT is used if the application uses digital certificates for client authentication.

    Once the security roles and constraints are defined in web.xml, the security roles are mapped in the application deployment plan, geronimo-web.xml, to the principals. The deployment plan for this sample application is shown in Listing 7.

    Listing 7. geronimo-web.xml for sample application
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-2.0">
        <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
            <dep:moduleId>
                <dep:groupId>dw</dep:groupId>
                <dep:artifactId>SimpleWebApp</dep:artifactId>
                <dep:version>1.0</dep:version>
                <dep:type>war</dep:type>
            </dep:moduleId>
            <dep:dependencies>
                <dep:dependency>
                    <dep:groupId>console.realm</dep:groupId>
                    <dep:artifactId>SampleSecurityRealm</dep:artifactId>
                    <dep:version>1.0</dep:version>
                    <dep:type>car</dep:type>
                </dep:dependency>
            </dep:dependencies>
        </dep:environment>
        <context-root>simplewebapp</context-root>
        <security-realm-name>SampleSecurityRealm</security-realm-name>
        <security>
            <role-mappings>
                <role role-name="admin">
                    <principal name="Admin"
    	class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"/>
                </role>
                <role role-name="user">
                    <principal name="User"
    	class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"/>
                    <principal name="john"
    	class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"/>
                </role>
            </role-mappings>
        </security>
    </web-app>

    In the geronimo-web.xml file:

    • <moduleId> tag in the environment section enables you to specify a configuration ID for your application. If omitted, Community Edition will assign a configuration ID applying its own rules. In this example, the value is: dw/SimpleWebApp/1.0/war.
    • <dependencies> tag in the environment section enables you to specify your application's dependecy on other configurations running in the server. In this example, a dependency is specified on the configuration in which the properties file realm (created earlier) is running: console.realm/SampleSecurityRealm/1.0/car.
    • <context-root> tag specifies the context root at which your application will be available to the user. In this example, the value is "simplewebapp," which means the application can be accessed at the URL: http://localhost:8080/simplewebapp.
    • <security-realm-name> tag specifies the security realm name against which this application should authenticate. Recall that SampleSecurityRealm is the name used for the Properties File realm you created earlier.
    • <role> tag under role-mappings lets you configure the principals that should be mapped to each role. The role-name attribute is used to specify the role to which the principal elements inside the role tag are to be mapped. Here, the admin role is mapped to a GeronimoGroupPrincipal with name "Admin," and the user role is mapped to two principals: a GeronimoGroupPrincipal with name "User," and a GeronimoUserPrincipal with name "john." Recall that when a user logs into SampleSecurityRealm, the subject is populated with a GeronimoUserPrincipal with the username and zero or more GeronimoGroupPrincipals with the names of all groups the user belongs to.

    Once a user logs in, the authenticated user principal can be obtained in a servlet or JSP using the request.getUserPrincipal() method. Whether or not this user is in a specific role can be determined using the request.isUserInRole() method. An excerpt from admin.jsp is shown in Listing 8.

    Listing 8. admin.jsp
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <html>
    ...
    <br>Welcome <b><%=request.getUserPrincipal().getName() %></b> !!
    <br>
    <br>You are <%=request.isUserInRole("admin") ? 
    	"in" : "not in"%> 'admin' role.
    <br>You are <%=request.isUserInRole("user") ? 
    	"in" : "not in"%> 'user' role.
    ...
    </html>
  4. Install sample application

    You will now deploy the sample application using the Deploy New portlet. The WAR file, SimpleWebApp.war, is included in the download file provided with this article. Since the deployment plan (geronimo-web.xml) is packaged inside the WAR file in the WebContent/WEB-INF directory, you do not need to specify a plan file to install the application:

    1. Launch the Deploy New portlet (Figure 2).
    2. Navigate to the Archive file location <SAMPLES_HOME>\SimpleWebApp.war and click Install to install the application.
    3. Verify that the installed application is listed on the Web App WARs portlet (Figure 3).
  5. Test the application

    The sample application you deployed is available at http://localhost:8080/simplewebapp. You can test the application using these scenarios:

    Scenario 1:

    1. Open a new browser window and access http://localhost:8080/simplewebapp.
    2. Click the link to access Admin page. A dialog displays to provide the login information. Notice that this dialog shows the real-name "Sample Security Realm" configured in web.xml (Figure 12).
    3. For User name and Password, enter dwadmin and admin, respectively. Click OK.
    4. The Admin page should be accessible. Click the link to access User page. You should receive an error "HTTP Status 403."
    Figure 12. Web App Login
    Figure 12. Web App Login

    What just happened:

    • Logging in as dwadmin adds two principals to the subject: GeronimoUserPrincipal("dwadmin") and GeronimoGroupPrincipal("Admin").
    • Since role-mapping in geronimo-web.xml for the admin role lists GeronimoGroupPrincipal("Admin"), dwadmin is able to access the Admin page at http://localhost:8080/simplewebapp/admin/admin.jsp.
    • Since neither of the two principals in the subject appear in the role-mapping for the user role, dwadmin is forbidden to access the User page at http://localhost:8080/simplewebapp/user/user.jsp.

    Scenario 2:

    1. Open a new browser window and access http://localhost:8080/simplewebapp.
    2. Login as user dwuser1 with password user1. You will have access to the User page, but accessing the Admin page will give you an error "HTTP Status 403."

    What just happened:

    • Logging in as dwuser1 adds two principals to the subject: GeronimoUserPrincipal("dwuser1") and GeronimoGroupPrincipal("User").
    • Since role-mapping for the user role lists GeronimoGroupPrincipal("User"), dwuser1 is able to access the User page.
    • Since neither of the two principals in the subject appear in the role-mapping for the admin role, dwuser1 is forbidden to access the Admin page.

    Scenario 3:

    1. Open a new browser window and access http://localhost:8080/simplewebapp.
    2. Login as user root with password root. You will have access to both User and Admin pages.

    What just happened:

    • Logging in as root adds three principals to the subject: GeronimoUserPrincipal("root"), GeronimoGroupPrincipal("Admin") and GeronimoGroupPrincipal("User").
    • Since role-mapping for the admin role lists GeronimoGroupPrincipal("Admin"), then user root is able to access the Admin page.
    • Since role-mapping for the user role lists GeronimoGroupPrincipal("User"), then user root is able to access the User page.

    Scenario 4:

    1. Open a new browser window and access http://localhost:8080/simplewebapp.
    2. Login as user john using password brad1983. You will have access to the User page, but accessing the Admin page will give you an error "HTTP Status 403."

    What just happened:

    • Logging in as john adds two principals to the subject: GeronimoUserPrincipal("john") and GeronimoGroupPrincipal("Guest").
    • Since role-mapping for the user role lists GeronimoUserPrincipal("john"), john is able to access the User page.
    • Since neither of the two principals in the subject appear in the role-mapping for the admin role, john is forbidden to access the Admin page.

At this point, you have created a properties file realm, configured a Web application to authenticate against this security realm, and verified the authorization for resources in the application.

Database (SQL) realm

A security realm based on SQLLoginModule is generally referred to as a database realm, and can be configured to authenticate users using credentials stored in a database. This is a more robust security realm than the properties file realm, but for this you need to create tables and enter data in the database. In this example, you will use the embedded Cloudscape database provided by Community Edition. You will use the DB Manager portlet for creating a new database in the embedded Cloudscape instance, and for connecting to the database, creating tables, and inserting data. To connect to the database, the SQLLoginModule can be configured to either use JDBC directly, or use the connection pools in Community Edition. In this example, you will create a connection pool and configure the SQLLoginModule to use that connection pool for accessing the database. To create and use a Database realm, you need to:

  1. Create a database

    The first step in creating a database realm is to create a database instance, if you don't have any already. In this example, you will use the Cloudscape database that is embedded in Community Edition, so you will first create an embedded Cloudscape database instance:

    1. Open the DB Manager portlet (Figure 4).
    2. For Create DB, enter SAMPLEDB.
    3. Click the Create button and the database will be created.
  2. Create tables

    A database realm requires two SQL statements to be configured in the security realm:

    • User SELECT SQL
      As the name suggests, this is an SQL statement to load username and password information. It should return two columns, the first holding a username and the second holding a password.

    • Group SELECT SQL
      This is an SQL statement used to load group information for a user. It should return two columns, the first holding a username and the second holding a group name.

    Both statements can use the PreparedStatement syntax (see Resources) of "?" for a parameter, in which case the username will be set for every parameter.

    You will now create two tables for storing the user information and the group information; the two tables will be named "users" and "groups." The SQL to create these tables, provided in db-realm-tables.sql file in the included download file, is shown in Listing 9.

    Listing 9. db-realm-tables.sql
    create table users (username varchar (15), password varchar (64));
    create table groups (groupname varchar (15), username varchar (15));

    To create these tables:

    1. Launch the DB Manager portlet by clicking on DB Manager in the Console Navigation pane (Figure 1).
    2. In the Use DB dropdown, select SAMPLEDB as the database against which you will run the SQL (Figure 4).
    3. Copy and paste the commands from Listing 9 into the SQL Command/s field, then click Run SQL. The SQL commands will be executed and the tables will be created.
  3. Create a database pool

    Another important step is the creation of a database pool that will be used by the SQLLoginModule in the database realm to access the tables that contain the authentication information. The database pool will keep a pool of connections to the SAMPLEDB database instance. To create a database pool:

    1. Select the Database Pools portlet (Figure 5).
    2. In the Create a new database pool section, select Using the Geronimo database pool wizard. Figure 13 will display.
      Figure 13. Step 1 - Select Name and Database
      Figure 13. Step 1 - Select Name and Database
    3. For Name of Database Pool, enter DBRealmPool, and for Database Type, select Derby network. Click Next.
    4. In the next dialog (Figure 14), enter or select the following values:
      • Driver JAR: org.apache.derby/derbyclient/10.2.2.0/jar
      • Database Name: SAMPLEDB
      • User Name: APP.
      • Password and Confirm Password: password
      • Port Number: 1527
      • Pool Min Size: 5
      • Pool Max Size: 20
      Figure 14. Edit a new database pool
      Figure 14. Edit a new database pool
  4. Create and test the security realm

At this point, you have learned about the prerequisites and created the required artifacts for a database realm. The steps to create the security realm and test it with a sample application in combination with some advanced features will be discussed later in the article.

LDAP realm

A security realm based on LDAPLoginModule is generally referred to as an LDAP realm. An LDAP realm authenticates users based on credentials stored on an LDAP server. This security realm can be configured to use an LDAP server running either internally, within the Community Edition instance, or externally. For this article, the Apache Directory Server 1.5.0, installed as a plug-in in Community Edition, will be used. To create and use an LDAP realm:

  1. Install Apache Directory Server plug-in

    Plug-ins hosted in plug-in repositories can be installed in Community Edition using the Plugins portlet in the admin console. At the time of this writing, an Apache Directory Server plug-in had not yet been released and hosted in a plug-in repository. For demonstration purposes, a directory server plug-in file is included in the download materials accompanying this article that you can install with the command line deploy tool. To install Directory Server plug-in:

    1. Extract <SAMPLES_HOME>\directory-plugin-extras.zip to <WASCE_HOME>.
    2. When the Community Edition server is running, deploy the plug-in CAR file using this command in a command window:

      <WASCE_HOME>\bin\deploy install-plugin <SAMPLES_HOME>\directory-2.0-SNAPSHOT.car

    3. When prompted for user name and password, enter system and manager, respectively. (These are the same username and password values used to access the admin console.)

    This operation might take some time, as the installer will download the Apache Directory Server JARs and other dependencies from remote Maven repositories. Once the plug-in is installed and started, the message "Started org.apache.geronimo.plugins/directory/2.0-SNAPSHOT/car" will display in the installer window.

    The Apache Directory Server you installed is an LDAP v3 server. It runs on port 10389, uses "simple" authentication, and is accessible using User DN "uid=admin,ou=system" with password "secret." These properties will be required to access the directory server and will feature in configuring an LDAP realm later. See <WASCE_HOME>/var/directory/server.xml for the configuration properties used by the directory server. (Administering Apache Directory Server is beyond the scope of this article.)

  2. Add data to the directory server

    Before the directory server can be used in an LDAP realm, authentication data needs to be added to the directory server. For this article, you will use JXplorer (an open source LDAP browser, see Resources) to add some user credentials information, stored in an LDIF file, into the directory server. JXplorer v3.2 is used here. The file dw-ldap-realm.ldif, provided in the download materials, contains five user/password pairs:

    • dwadmin/adminldap
    • dwuser1/user1
    • dwuser2/user2
    • root/root
    • john/brad1983

    and three groups:

    • Admin group with members dwadmin, root
    • User group with members dwuser1, dwuser2, root
    • Guest group with member john

    After installing JXplorer, follow these steps to import dw-ldap-realm.ldif into the Apache Directory Server:

    1. Open JXplorer.
    2. Select File => Connect to launch Open LDAP Connection dialog (Figure 15).
      Figure 15. JXplorer - Connect to LDAP
      Figure 15. JXplorer - Connect to LDAP
    3. Enter or select the following values:
      • Host: localhost
      • Port: 10389
      • Protocol: LDAP v3
      • Base DN: ou=system
      • Level: User + Password
      • User DN: uid=admin, ou=system
      • Password: secret
    4. Click OK to connect to the LDAP server.
    5. Select LDIF => Import File.
    6. Navigate to the location of dw-ldap-realm.ldif and select Open. This will import the data from the file and display a panel similar to Figure 16.
      Figure 16. JXplorer - view data
      Figure 16. JXplorer - view data
  3. Create and test the security realm

You have learned about the prerequisites for an LDAP realm and created necessary artifacts. The steps to create and test the security realm with a sample application in combination with some advanced features will be discussed later in the next section.

Advanced features

The previous section discussed the prerequisites and explained how to create the necessary artifacts for a properties file realm, a database realm, and an LDAP realm. You also created a properties file realm and configured a Web application's security using that realm. Creating the database and LDAP realms was deferred until now to demonstrate these tasks in combination with some advanced features, like:

  • Using password digests in place of clear-text passwords.
  • Enabling auditing to log all login attempts.
  • Locking out after repeated failed login attempts.

These features are explored in this section as you create a database realm and an LDAP realm.

Password digests and encoding

It is not necessary to store the original passwords to be able to compare them with user-provided passwords. Message digests can be used to compare a user-provided password with an original password without having to store the original password. Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length binary hash value. It is easier to compute a message digest from a password and computationally infeasible to compute the password based on its message digest. Community Edition provides for using digests for passwords with properties file realms and database realms. It also provides for using HEX and BASE64 encodings to represent the binary hash values as text. To create and use a database realm configured to use password digests, you must:

  1. Generate digest for passwords

    To help you create digested passwords for this example, a utility called encode.jar is included in the download materials. This utility will generate the hash for the password. The usage of this utility is:

    java -jar encode.jar <password> <digest algorithm> <encoding>

    For example, this command:

    java -jar encode.jar "hello" "MD5" "hex"

    will output the MD5 digest of the string "hello" in hexadecimal format. Listing 10 provides some of the passwords we use in this security realm and their digests.

    Listing 10. Sample encoded passwords
    Password    MD5 with hex                       SHA-1 with base64	
    --------    ------------                       -----------------
    admindb     a961676177cb4a7c3fb72334600ef72b   HORSE4ibU6JF1xWcPb3vRSDCOek=
    user1       24c9e15e52afc47c225b757e7bee1f9d   s9qne0wEqVUbh4HQMZH+CY8yXmc=
    user2       7e58d63b60197ceb55a1c487989a3720   oYgcBu7JbbmQHHu/5BxCo/COnLQ=
    root        63a9f0ea7bb98050796b649e85481845   3Hbp8MAAbo+RngxRXGbbujmC94U=
    brad1983    b1dde9430b1084ca7514b53a93ec6548   B/ilkJHgVi17TiTcJ3Z5bK8yBFo=
    password    5f4dcc3b5aa765d61d8327deb882cf99   W6ph5Mm5Pz8GgiULbPgzG37mj9g=

    This security realm example uses "MD5" with "hex."

  2. Populate data in tables

    You can populate the tables for this example by running the script db-md5-hex-data.sql (provided in the download materials). This script will populate the database with the MD5 digest passwords encoded in hex format. You can copy the contents of the script and paste it in the SQL Command/s text area of the DB Manager portlet, then click Run SQL to populate the database. (Make sure you select SAMPLEDB.)

  3. Create database realm

    To create a database realm:

    1. Go to the Security Realms portlet and click on Add new security realm.
    2. For Name of the Security Realm, enter dw-db-realm.
    3. For Realm Type, select Database (SQL) Realm.
    4. Click Next to display the panel shown in Figure 17.
      Figure 17. Database (SQL) Realm settings
      Figure 17. Database (SQL) Realm settings
    5. Enter the following values:
      • User SELECT SQL: SELECT username, password FROM users WHERE username=?
      • Group SELECT SQL: SELECT username, groupname FROM groups WHERE username=?
      • Digest Algorithm: MD5
      • Digest Encoding: hex
      • Database Pool: DBRealmPool
    6. Click Next to display the panel shown in Figure 8.
    7. Click Test a Login to display the panel shown in Figure 9.
    8. Enter a valid user name and password (john, brad1983) and click Login. The success panel shown in Figure 10 should display.
    9. Click the Deploy Realm button to deploy the security realm.

    Here, you have created a database realm that used MD5 digest for passwords with hex encoding and a database pool to connect to the database.

  4. Test the security realm

    A sample application that is configured to authenticate against the database realm you created above is included in the download materials accompanying this article. Deploy this SimpleWebApp-DB.war application using the Deploy New portlet, then access it at http://localhost:8080/simplewebappdb/. You should be able to access the Admin page using the username and password dwadmin and admindb. Notice that the login dialog displays dw-db-realm, as configured in the applications web.xml. Also, verify that the security-realm-name in the application's SimpleWebApp-DB-plan.xml deployment plan is "dw-db-realm." This deployment plan is included in the download materials, packaged inside the WAR file SimpleWebApp-DB.war as WebContent\WEB-INF\geronimo-web.xml, so you do not need to provide a plan file at deployment time.

Auditing feature

The auditing feature enables you to configure a security realm that logs all login attempts to a file. To turn on this feature when creating a security realm, check the Auditing box under Advanced Configuration in the Security Realms portlet. To create and use a database realm enabled for auditing:

  1. Create a Database realm with auditing

    Recall that you already populated the data in the database tables. To create the database realm:

    1. Launch the Security Realms portlet and click Add new security realm.
    2. For Name of the Security Realm, enter dw-db-realm2.
    3. For Realm Type, select Database (SQL) Realm and click Next.
    4. On the Configure Login Module panel (Figure 18), enter or select the following values:
      • User SELECT SQL: SELECT username, password FROM users WHERE username=?
      • Group SELECT SQL: SELECT username, groupname FROM groups WHERE username=?
      • Digest Algorithm: MD5
      • Digest Encoding: hex
      • Database Pool: Leave blank, as you will be using JDBC directly.
      • JDBC Driver Class: org.apache.derby.jdbc.ClientDriver
      • Driver JAR: org.apache.derby/derbyclient/10.2.2.0/jar
      • JDBC URL: jdbc:derby://localhost:1527/SAMPLEDB
      • JDBC Username: APP
      • JDBC Password and Confirm Password: password
      Click Next.
      Figure 18. Database (SQL) Realm - JDBC settings
      Figure 18. Database (SQL) Realm - JDBC settings
    5. On the Advanced Configuration panel (Figure 19), check Enable Auditing and enter var/log/login-attempts.log for Log File.
      Figure 19. Enable auditing
      Figure 19. Enable auditing
    6. Click Test a Login to display the panel shown in Figure 9.
    7. Enter a valid username and password (john, brad1983) and click Login. This will display the success page, shown in Figure 10.
    8. Click Deploy Realm to deploy the security realm.

    You have now created a database realm that uses MD5 digest passwords with hex encoding, uses JDBC to connect to the database, and is enabled for auditing.

  2. Test the security realm

    A sample application configured to authenticate against the database realm enabled for auditing, created above, is included in the download materials provided with this article. Deploy this SimpleWebApp-Audit.war application using Deploy New portlet and access the application at http://localhost:8080/simplewebappaudit/. You should be able to access the Admin page using username and password dwadmin and admindb -- but before you use the correct login information to access the Admin page, enter incorrect login information to observe the login failure get logged to <WASCE_HOME>/var/log/login-attempts.log. Now, provide the correct login information to access to Admin page. Verify once again that the successful login is logged to <WASCE_HOME>/var/log/login-attempts.log.

Lockout feature

The lockout feature enables you to configure the locking out of a specific username for a certain duration (call it lockout duration) if a specified number of login failures occur within a specified time span for that username. After this specified number of failed login attempts -- even if the user provides the correct credentials for that username, Community Edition will report a login failure until the lockout duration has elapsed since the last login attempt. This article demonstrates the lockout feature in combination with an LDAP realm. To create and use an LDAP realm configured with the lockout feature:

  1. Create an LDAP realm with lockout

    Listing 11 shows an excerpt from the dw-ldap-realm.ldif file used earlier in this article to add data to a directory server. This listing shows data for one user with name "john" and one group with name "Admin." The entries that are of interest under User are "dn," "uid," and "userPassword, " and the entries of interest under Group are "dn," "uniqueMember," and "cn." These entries will be referred to when you configure the options in LDAP realm you will create in the next steps.

    Listing 11. dw-ldap-realm.ldif
    # User: john
    
    dn: uid=john,ou=users,ou=system
    cn: John Smith
    sn: John
    givenname: John
    objectclass: top
    objectclass: person
    objectclass: organizationalPerson
    objectclass: inetOrgPerson
    ou: Human Resources
    ou: People
    l: Las Vegas
    uid: john
    mail: john@dw.com
    telephonenumber: +1 408 555 5555
    facsimiletelephonenumber: +1 408 555 5556
    roomnumber: 4613
    userPassword: brad1983
    
    # Group: Admin
    
    dn: cn=Admin,ou=groups,ou=system
    objectClass: groupOfUniqueNames
    uniqueMember: uid=dwadmin,ou=users,ou=system
    uniqueMember: uid=root,ou=users,ou=system
    cn: Admin

    To create an LDAP realm configured to use the Apache Directory Server installed as a plug-in in Community Edition:

    1. Launch the Security Realms portlet and click Add new security realm.
    2. For Name of the Security Realm, enter dw-ldap-realm.
    3. For Realm Type, select LDAP Realm and click Next.
    4. On the Configure Login Module panel (Figure 20) , enter or select the following values:
      • Initial Context Factory: com.sun.jndi.ldap.LdapCtxFactory
      • Connection URL: ldap://localhost: 10389
      • Connect Username: uid=admin,ou=system
      • Connect Password and Confirm Password: secret
      • Connect Protocol: Leave blank
      • Authentication: simple
      • User Base: ou=users,ou=system
      • User Search Matching: uid={0}
      • User Search Subtree: false
      • Role Base: ou=groups,ou=system
      • Role Name: cn
      • Role User Search String: (uniqueMember={0})
      • Role Search Subtree: false
      • User Role Search String: Leave blank.
      The first seven fields above are used in connecting to the directory server. Recall that these are the same field values you used to connect to the directory server using JXplorer. The next eight fields, User Base through Role Search String, are used to authenticate the user against the data stored in the directory server and to obtain the group information for the user. Recall from Listing 11 that each user has a "dn" of the form uid=<username>,ou=users,ou=system, and that each group has a "dn" of the form cn=<groupname>,ou=groups,ou=system. This explains the values for the User Base, User Search Matching, Role Base, and Role Name fields. Recall also from Listing 11 that for each member in a group, there is a uniqueMember entry. This explains the value for the Role User Search String field.
      Figure 20. LDAP realm settings
      Figure 20. LDAP realm settings

      Click Next.

    5. On the Advanced Configuration panel, check Enable Lockout, then enter 3, 60, and 30 in the next three fields respectively (Figure 21).
      Figure 21. Enable lockout
      Figure 21. Enable lockout
    6. Click Test a Login to display a panel similar to Figure 9.
    7. Enter user name and password dwadmin and adminldap, then click Next. A Login Results panel similar to Figure 10 will display.
    8. Click Deploy Realm.

    This completes the creation of an LDAP realm. You have also configured the lockout feature so that it locks out a user for 30 seconds if there are three failed attempts within a period of 60 seconds.

  2. Test the security realm

    A sample application that is configured to authenticate against the LDAP realm you just created is included in the download materials provided with this article. Deploy this SimpleWebApp-LDAP.war application using the Deploy New portlet and access the application at http://localhost:8080/simplewebappldap/. You should be able to access the Admin page using username and password dwadmin and adminldap.

    To verify the lockout feature:

    1. If you have already logged in, logout from the application using the Logout link.
    2. Access http://localhost:8080/simplewebappldap/admin/admin.jsp.
    3. In the Login page, enter the user name dwadmin, do not enter a password, then click Login. A Login Error should display.
    4. Click your browser's Back button to return to the Login page. Enter the user name dwadmin again, do not enter a password, and click Login. This will register a second failed login attempt.
    5. Repeat step d to register a third failed login attempt.
    6. Click on the Back button once more. This time, enter the correct login information on the Login page (Username: dwadmin, Password: adminldap) and click Login once more. This should still result in a Login Error.
    7. Now, wait for at least 30 seconds and repeat step f. This time you will be able to login successfully.

    What just happened: You enabled the lockout feature to lock an account for 30 seconds after three failed attempts within 60 seconds. Therefore, by step e, the dwadmin account was locked, and so the login failed at step f -- even though you provided correct login information. After 30 seconds elapsed, the account was unlocked again and you were able to login successfully in step g.

Storing credentials

Here are two ways you can configure a security realm to store credentials for authenticating users:

  • Store password

    Applications do not typically require access to a user's password once the user authenticates. If this is required, Community Edition lets you configure a security realm to a store user's password. This is accomplished by simply selecting the Store Password option when you create a security realm (Figure 8). When this option is enabled, the security realm will store the authenticating user's username and password in a private credential in the subject, enabling access to the password later, after the login process has completed. In this case, Community Edition uses a GeronimoPasswordCredential object to store the user data.

  • Named credential

    The named credential feature lets you configure a credential name along with the password to be stored. This is also accomplished simply by selecting the Named Credential option on the Advanced Configuration panel (Figure 8) at security realm creation time. When enabled, the security realm stores the authenticating user's username and password in a private credential in the subject under the specified credential name. In this case, Community Edition uses a NamedUsernamePasswordCredential object to store the user's data.

    The named credential feature is usually used to pass on credentials while invoking Web services from within the application. Retrieving these private credentials from the subject is demonstrated in a sample application with the Application Scoped security realm later in this article. (Demonstrating Web service invocation is beyond the scope of this article.)

Realm principal and login domain principal

Typically, Community Edition can't distinguish between two different principals that have the same name and same principal class but were produced by two different LoginModules. If the wrap-principals option is enabled, Community Edition will "wrap" principals to track which login module and security realm each principal came from. This is done by setting the wrap-principals attribute in the login-module to "true" (Listing 12). Doing this lets you use the realm-principal and login-domain-principal elements in Community Edition deployment plan security mapping. Using realm-principal and login-domain-principal is demonstrated with an Application Scoped security realm, described next.

Application Scoped security realm

A security realm can also be deployed as part of the Web application that uses the security realm. This is done by adding the security realm GBean definition to the application's deployment plan. This type of security realm is generally referred to as an Application Scoped security realm. All the security realms you have created to this point in the article run in their own configuration, and their scope is considered to be server-wide, which is indicated in the "Deployed as" column in the Security Realms portlet (Figure 11).

  1. Examine the sample application

    The download materials provided with this article includes a sample application, SimpleWebApp-Subject.war, that uses a security realm deployed as part of the application. Notice that the application's deployment plan, SimpleWebApp-Subject-plan.xml (Listing 12), has a GBean to define a security realm with the name dw-prop-realm, which is a properties file realm that uses dw_users.properties and dw_groups.properties.

    Listing 12. Deployment plan for SimpleWebApp-Subject
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-2.0">
      ...
      <context-root>simplewebappsubject</context-root>
      <security-realm-name>dw-prop-realm</security-realm-name>
      <security>
        <role-mappings>
          <role role-name="admin">
            <realm-principal name="john" domain-name="dw-prop"
              realm-name="dw-prop-realm"
              class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" />
            <principal name="Admin"
              class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" />
          </role>
          <role role-name="user">
            <login-domain-principal name="john"
              domain-name="unknown"
              class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" />
            <principal name="User"
              class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" />
          </role>
        </role-mappings>
      </security>
      <gbean name="dw-prop-realm"
        class="org.apache.geronimo.security.realm.GenericSecurityRealm"
        xsi:type="dep:gbeanType"
        xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <attribute name="realmName">dw-prop-realm</attribute>
        <reference name="ServerInfo">
          <name>ServerInfo</name>
        </reference>
        <xml-reference name="LoginModuleConfiguration">
          <log:login-config
            xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0">
            <log:login-module control-flag="REQUIRED"
              wrap-principals="true">
              <log:login-domain-name>dw-prop</log:login-domain-name>
              <log:login-module-class>
                org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule
              </log:login-module-class>
              <log:option name="groupsURI">
                var/security/dw_groups.properties
              </log:option>
              <log:option name="usersURI">
                var/security/dw_users.properties
              </log:option>
            </log:login-module>
            <log:login-module control-flag="OPTIONAL"
              wrap-principals="false">
              <log:login-domain-name>
                dw-prop-realm-Password
              </log:login-domain-name>
              <log:login-module-class>
           org.apache.geronimo.security.realm.providers.GeronimoPasswordCredentialLoginModule
              </log:login-module-class>
            </log:login-module>
            <log:login-module control-flag="OPTIONAL" wrap-principals="false">
              <log:login-domain-name>
                dw-prop-realm-NamedUPC
              </log:login-domain-name>
              <log:login-module-class>
                org.apache.geronimo.security.jaas.NamedUPCredentialLoginModule
              </log:login-module-class>
              <log:option
                name="org.apache.geronimo.jaas.NamedUPCredentialLoginModule.Name">
                mycredname
              </log:option>
            </log:login-module>
          </log:login-config>
        </xml-reference>
      </gbean>
    </web-app>

    In this deployment plan:

    • The security realm GBean is part of the application deployment plan itself.
    • The wrap-principals attribute is set to "true" for PropertiesFileLoginModule. This results in a RealmPrincipal and a LoginDomainPrincipal getting added to the subject for each GeronimoUserPrincipal and GeronimoGroupPrincipal, in addition to the original principals.
    • The values for the domain-name and realm-name attributes in login-domain-principal and realm-principal in role-mapping come from the login-domain-name inside login-module and from the realmName attribute in the GBean. In this example, these values are "dw-prop" and "dw-prop-realm."
    • The two additional LoginModules GeronimoPasswordCredentialLoginModule and NamedUPCredentialLoginModule correspond to the store password and named credential features, discussed earlier.

    The subject containing the principals and credentials of the authenticated user can be retrieved inside a servlet or JSP using the method PolicyContext.getContext(). The Admin page in the sample application displays all the principals and credentials in the subject. An excerpt from admin.jsp is shown in Listing 13.

    Listing 13. JSP to display principals and credentials
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ page import="javax.security.auth.Subject" %>
    <%@ page import="javax.security.jacc.PolicyContext" %>
    <%@ page import="o.a.geronimo.security.realm.providers.GeronimoPasswordCredential" %>
    <%@ page import="org.apache.geronimo.security.jaas.NamedUsernamePasswordCredential" %>
    <html>
    ...
    <br>Welcome <b><%=request.getUserPrincipal().getName() %></b> !!
    <br>
    <br>You are <%=request.isUserInRole("admin") ? "in" : "not in"%> 'admin' role.
    <br>You are <%=request.isUserInRole("user") ? "in" : "not in"%> 'user' role.
    <br>
    ...
    <%  // This works for any JEE Server using JACC
    Subject subject =
     (Subject)PolicyContext.getContext("javax.security.auth.Subject.container");
    %>
    <%-- The following code displays the contents of the Subject --%>
    <br><%=subject.getPrincipals().size()%> Principals
    <%for(java.security.Principal p:subject.getPrincipals()) { %>
        <br>* <%=p.getClass().getName()%> : <%=p.getName()%>
    <%}%>
    <hr>
    <br><%=subject.getPrivateCredentials().size()%> Private Credentials
    <%for(Object c:subject.getPrivateCredentials()) { %>
        <br><%=c%>
    <%if(c instanceof GeronimoPasswordCredential) {%>
        <br>Username: <%=((GeronimoPasswordCredential)c).getUserName()%>
        <br>Password: <%=new String(((GeronimoPasswordCredential)c).getPassword())%>
    <%}%>
    <%if(c instanceof NamedUsernamePasswordCredential) {%>
        <br>Credential Name: <%=((NamedUsernamePasswordCredential)c).getName()%>
        <br>Username: <%=((NamedUsernamePasswordCredential)c).getUsername()%>
        <br>Password: <%=new String(((NamedUsernamePasswordCredential)c).getPassword())%>
    <%}%>
    <hr>
    <%}%>
    <br><%=subject.getPublicCredentials().size()%> Public Credentials
    <%for(Object c:subject.getPublicCredentials()) { %>
        <br><%=c%>
    <%}%>
    ...
    </html>

    Principals in the subject are retrieved using the Subject.getPrincipals() method. Private credentials can be retrieved using Subject.getPrivateCredentialsMethod(), and public credentials can be retrieved using the Subject.getPublicCredentails() method.

  2. Test the security realm

    1. Install the sample application SimpleWebApp-Subject.war using the Deploy New portlet.
    2. Now, visit the Security Realms portlet. Notice that the portlet shows dw/SimpleWebApp-Subject/1.0/war in the Deployed as column for dw-prop-realm.
    3. Access the application at http://localhost:8080/simplewebappsubject and login to the Admin page using user ID and password john and brad1983. Notice that the Admin page displays the principals, private credentials, and public credentials in the subject. Accessing the User page will result in an error "HTTP Status 403."

    Some important observations here:

    • In the role-mapping for the admin role, a realm-principal is specified with:
      • name="john"
      • realm-name="dw-prop-realm"
      • domain-name="dw-prop"
      Since all three values match what the RealmPrincipal in the Subject will contain when "john" logs in, this user will have access to Admin page.
    • In the role-mapping for the user role, a login-domain-principal is specified with:
      • name="john"
      • domain-name="unknown"
      But when "john" logs in, the LoginDomainPrincipal will have:
      • name="john"
      • domain-name="dw-prop"
      Although the name matches, the domain-names do not match, and so "john" will not have access to "User" page.
    • The Subject contains a RealmPrincipal and LoginDomainPrincipal corresponding to each GeronimoUserPrincipal/GeronimoGroupPrincipal. Also, there are two private credentials: GeronimoPasswordCredential and NamedUsernamePasswordCredential.

Conclusion

IBM WebSphere Application Server Community Edition V2.0 provides JAAS LoginModules implementations that can be readily used to create security realms that enable the storing of user credential information in a variety of data stores, such as properties files, database tables, and an LDAP server. In addition, Community Edition also provides advanced security features, like using digested passwords, auditing, and lockout on repeated login failures. This article illustrated how a desired infrastructure can be run within Community Edition, and how to configure Web application security using these security realms.


Download

DescriptionNameSize
Code sampleswascesecurity_samples.zip60 KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=256999
ArticleTitle=Configuring Web application security in WebSphere Application Server Community Edition V2.0
publish-date=09252007