This article explains how to leverage database tables for storing account information
for user authentication and authorization of Java EE applications in JDeveloper
10.1.3.2 and OC4J 10.1.3.2.
Container-managed security allows web applications to delegate authentication
and authorization decisions to the executing web container. In Oracle Containers
for J2EE (OC4J) the authentication and authorization decision is handled by
the OracleAS JAAS Provider (referred to in previous releases as the Oracle JAZN framework). Web applications running in OC4J
can be configured to authenticate users against Oracle Internet Directory (OID),
third-party LDAP, CoreId, jazn-data.xml or a custom JAAS LoginModule. The web application
code itself doesn't need to know about the configured security provider and instead uses
the standard Java Servlet APIs isUserInRole(), getRemoteUser(), and getUserPrincipal() to programmatically evaluate access to application
resources. In addition to programmatic security, the container enforces URL
pattern based authorization and user authentication: Basic, Form, PKI or Digest. Although OracleAS JAAS Provider is a JAAS implementation, declarative security in J2EE does not require
the application developer to use JAAS and instead is configured through the standard J2EE web.xml and OC4J orion-application.xml deployment descriptors. Usually the first
thing developers understand when approaching security in J2EE is container-managed
security. This is because container-managed security is easy to setup, easy
to work with, and extremely portable across J2EE containers. A follow-up next
step then usually is how to use a custom security provider like the database
for user authentication and authorization.
This JDeveloper article explains how-to use the DBTableOraDataSourceLoginModule
JAAS LoginModule in OC4J to implement container-managed authentication and authorization
based on a database security provider. For guidance on how to create your own
JAAS LoginModule that then can be configured for OC4J container managed security,
see the Login Module Developer's Guide.
Container Managed Security in OC4J
In container-managed security the application delegates authentication
and authorization decisions to the J2EE container. The benefit of container-managed
security in contrast to a pure JAAS approach (Java Authentication and
Authorization Service) approach is that the application logic is not mixed
with authentication and authorization code, which ensures portability.
Figure 1: OC4J Security Architecture
Container-managed security protects web resources by their URL. If a
user requests a protected web resource, the J2EE container checks whether the
user is authenticated and otherwise delegates the request to the integrated
authentication service. The Oracle JAAS Provider authenticates users based
on a username and password pair or a client side x509 certificate. The
default authentication provider is either file-based, (jazn-data.xml) or
LDAP directory-based (Oracle Internet Directory). Other authentication providers can
be configured with OC4J but require a pluggable JAAS LoginModule. One
of the LoginModules provided by OC4J since 10.1.3.1 is DBTableOraDataSourceLoginModule, which authenticates the user against a database user table and role table.
Once the user is authenticated, OC4J checks whether the user is a member of the
security role that is configured to protect the requested web resource.
The authentication provider adds a user's role membership to the user
subject in the form of a Java security Principal. Because authentication is
performed only one time, no second opportunity exists to grant users
role privileges. If the request is authenticated and authorized, the web
resource is returned to the requesting client. Otherwise a HTTP error
code is returned.
Web.xml deployment descriptor definition
J2EE authentication and authorization is configured in the web.xml deployment
descriptor. If a custom JAAS LoginModule is specified, then OC4J delegates authentication
and authorization to the pluggable security provider.
The web.xml confguration above defines basic authentication relying on the browser's
native login dialog, with authentication to be enforced on the application's root URL. Access
is granted to all users that are members of the USER role, a case sensitive,
semantic role that doesn't have physical permissions associated. The JAAS
LoginModule, if not using the default Oracle JAAS Provider, adds the
USER role in form of a Java Principal to the authenticated user subject.
Application developers don't necessarily need to be aware of how authentication
is performed and configured. All implementation details are relevant to
the administrator and JAAS LoginModule developer.
The DBTableOraDataSourceLoginModule
requires a USERS table and ROLES table in the database, where the username
column of the USERS table is the primary key and the username column in
the ROLES table is the corresponding foreign key (see note below). An example table script
that creates the USERS table and ROLES table into the database authschema
is:
CREATE TABLE "AUTHSCHEMA"."APPLICATION_USERS"
( "ID" NUMBER NOT NULL ENABLE,
"USERNAME" VARCHAR2(100) NOT NULL ENABLE,
"PASSWD" VARCHAR2(100) NOT NULL ENABLE
) ;
ALTER TABLE "AUTHSCHEMA"."APPLICATION_USERS" ADD CONSTRAINT
"APPLICATION_USERS_PK" PRIMARY KEY ("USERNAME") ENABLE;
REM INSERTING into APPLICATION_USERS
Insert into APPLICATION_USERS ("ID","USERNAME","PASSWD")
values (1,'DFAVIET','welcome');
Insert into APPLICATION_USERS ("ID","USERNAME","PASSWD")
values (2,'AHUNOLD','welcome');
Insert into APPLICATION_USERS ("ID","USERNAME","PASSWD")
values (3,'SKING','welcome');
/
CREATE TABLE "AUTHSCHEMA"."APPLICATION_ROLES"
( "ID" NUMBER NOT NULL ENABLE,
"ROLE_NAME" VARCHAR2(100) NOT NULL ENABLE,
"USERNAME" VARCHAR2(100)
) ;
ALTER TABLE "AUTHSCHEMA"."APPLICATION_ROLES" ADD CONSTRAINT
"APPLICATION_ROLES_PK" PRIMARY KEY ("ID") ENABLE;
ALTER TABLE "AUTHSCHEMA"."APPLICATION_ROLES" ADD CONSTRAINT
"APPLICATION_ROLES_APPLICA_FK1" FOREIGN KEY ("USERNAME")
REFERENCES "AUTHSCHEMA"."APPLICATION_USERS" ("USERNAME")
ENABLE;
REM INSERTING into APPLICATION_ROLES
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (1,'PRESIDENT','SKING');
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (2,'MANAGER','SKING');
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (3,'MANAGER','AHUNOLD');
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (4,'USER','SKING');
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (5,'USER','AHUNOLD');
Insert into APPLICATION_ROLES ("ID","ROLE_NAME","USERNAME")
values (6,'USER','DFAVIET');
/
The DBTableOraDataSourceLoginModule helps you to secure account passwords
in two ways:
An option to configure a password
encoder that encrypts the user-provided password before comparing
it with the encrypted value in the database. Using this option the password
is encrypted in the database, allowing you to use database encryption
features when creating the user account.
A J2EE data source to provide the database access information for the
LoginModule. In OC4J, data sources can use password indirection, in which
case the password is read from a named user account in the OC4J system-jazn-data.xml.
Using password indirection encrypts the password so it cannot be stolen
from the configuration file.
Configuring the database LoginModule with Oracle
JDeveloper embedded OC4J
Oracle JDeveloper has an embedded OC4J container for testing web applications
during development. The embedded OC4J is configured differently than the standalone OC4J to support runtime testing of applications without requiring application
deployment. To do this, all web applications are executed as "current-workspace-app",
no matter what the assigned name for the J2EE application. This information
is important because to use JAAS LoginModules with the embedded OC4J, they need
to be configured under the name of the application using it: current-workspace-app.
NOTE: Failing to use the current-workspace-app name for the LoginModule
will cause OC4J to use its own default Realm LoginModule and look for the
username / password pair in the system-jazn-data.xml file directly. Thus, failing to find login credentials would end in an unauthenticated request.
All configuration files of the embedded OC4J are located in the JDEVELOPER_HOME\jdev\system\oracle.j2ee.10.1.3.40.66\embedded-oc4j\config directory, where JDEVELOPER_HOME is the directory in which you unzipped
JDeveloper after downloading the software from OTN. The
configuration files that you will edit to configure database LoginModule support are:
system-jazn-data.xml
application.xml
data-sources.xml
System-jazn-data.xml
The system-jazn-data.xml file contains the JAAS LoginModule definition
of the DBTableOraDataSourceLoginModule or any custom JAAS LoginModule.
The difference between the DBTableOraDataSourceLoginModule and
a custom JAAS LoginModule is that this LoginModule already exists in the class
path of OC4J and doesn't need to be added to the lib directory
or configured in the application.xml file. The DBTableOraDataSourceLoginModule
is configured and ready for you to use. Note however that the default LoginModule
in OC4J is the JAZN Realm LoginModule, which is used for all applications that
don't have a application specific login configuration. To create an application
specific login configuration for the JDeveloper current-workspace-app,
the LoginModule configuration in system-jazn-data.xml need to be
edited as follows:
Note that a login configuration for a web application can have multiple JAAS LoginModules
configured. In this case, they will be called in the sequence they show in the configuration
file. The control-flag of the LoginModule configuration specifies whether the
authentication performed by a LoginModule needs to be successful for the
whole authentication to be successful, or whether the LoginModule is optional,
which means it may fail. Because the DBTableOraDataSourceLoginModule is
the only LoginModule configured for the default web application in the
embedded OC4J, the flag needs to be set to required. All configured options
are LoginModule-specific, including, for example, the name of the data source for the database
table access.
While nothing prevents you from hand editing the system-jazn-data.xml file, JDeveloper provides a dialog to assist you. To launch
the editor, select the menu option Tool | Embedded OC4J Server from the JDeveloper
toolbar.
Figure 2: Visual editor for the system-jazn-data.xml file of the embedded OC4J
Application.xml
But how does embedded OC4J know that it should use DBTableOraDataSourceLoginModule for authentication and not the default Realm LoginModule? The application.xml file, located in the JDEVELOPER_HOME\jdev\system\oracle.j2ee.10.1.3.40.66\embedded-oc4j\config directory, can contain two properties as a switch that indicates that
the JAAS LoginModule provider should be used instead of the default Realm LoginModule.
The role.mapping.dynamic property defines that J2EE security roles should
be read from the authenticated user subject, allowing the LoginModule
to add role grants to the authenticated user. The custom.loginmodule.provider property tells OC4J to use a custom JAAS LoginModule for authentication.
The application.xml file cannot be edited from within JDeveloper and
instead needs to be edited manually.
Note: Configuring the application.xml to authenticate
with custom LoginModules enforces this authentication type to be used
for all projects run by this JDeveloper instance. For this reason it is
recommended to set up a JDeveloper installation to build and test applications
that require JAAS LoginModule authentication.
Data-sources.xml
The data-sources.xml file is used to define the J2EE data-source referenced
by the LoginModule to access the database tables for authentication.
The LoginModule configuration shown earlier has the following LoginModule
option defined
According to this configuration, the datasource name jdbc/authschemaDS is resolved by the LoginModule at runtime to connect to the database.
The data-source.xml file is expected to be part of the JDeveloper view layer
project an should be created manually as follows:
In the Application Navigator, select the View layer project and choose New from the context
menu to open the New Gallery
In the Filter By select option, choose All
Technologies.
Expand the General node and select the Deployment
Descriptors entry.
Choose OC4J Deployment Descriptor Wizard from the
available options.
In the wizard choose data-sources.xml and continue.
In the following wizard page, choose version 10.1 for
a data-source.xml file that works with JDeveloper version 10.1.3 and
above.
Finishing the wizard, creates a file data-sources.xml in the project's
META-INF directory. To populate the data-source.xml file with the
database connection expected by the LoginModule, create a named database connect
in JDeveloper.
Open the Connections Navigator by pressing Ctrl+Shift+O
Right mouse click onto the database connection node to create a new connection.
Enter the database name without the "jdbc/" and without the "DS"
strings in the Connection Name field on the first wizard
page. In the example used in this article, the name is "authschema".
Continue and complete the wizard, providing the connect information for
the database connect.
To populate the data-source.xml file with this information, choose
Tools | Embedded OC4J Server Preferences from the JDeveloper
menu. In the menu, expand the Current Workspace node
and select the Data Sources entry. Press the Refresh
Now button on the right hand side to copy all database connections
that exist in JDeveloper into the data-sources.xml file. From the list
of data sources created below the Data Sources entry,
delete all data source definitions that are not required for this application.
Figure 3: data-sources.xml editing option
In order to protect the database password, JDeveloper uses OC4J password indirection
for entries in the data-sources.xml file. Passwords in the data-sources.xml file may look similar to password="->DataBase_User_TNyMa-DJkD88CAzvVVLM8EX__YiKXy2P".
The indirected password points to a user account created in the project specific
jazn-data.xml file, located in the application - or workspace - root directory.
The jazn-data.xml file is not shown in the JDeveloper project hierarchy.
To add the jazn-data.xml file to the JDeveloper
project, so that it is visible to the application developer, do as follows:
Select the ViewLayer project and choose New from the context
menu to open the New Gallery.
In the Filter By select option, choose All
Technologies.
Expand the General node and select the Deployment
Descriptors entry.
Choose OC4J Deployment Descriptor Wizard from the
available options.
In the wizard choose jazn-data.xml and continue.
In the following wizard page choose version 10.1 for
a jazn-data.xml file that works for JDeveloper version 10.1.3 and above.
To populate the created jazn-data.xml file with the indirected
passwords from the data-sources.xml file, choose Tools
| Embedded OC4J Server Preferences from the JDeveloper menu. In the
menu, expand the Current Workspace node and select the Data
Sources entry. Press the Refresh Now button on the
right hand side to copy all database connections that exist in JDeveloper into
the data-sources.xml file. At the same time, the indirected passwords
are created in the jazn-data.xml file.
Note: If the password accounts aren't created, delete the
data source entries shown under Data Sources node before pressing
the refresh button.
Configuring the database LoginModule with Oracle
OC4J standalone
Deploying an application that uses DBTableOraDataSourceLoginModule for
J2EE authentication is easier to a standalone OC4J instance than to the
embedded instance because JDeveloper automates many of the steps for you. The configuration
files that needs to be added or edited are
orion-application.xml
data-sources.xml
system-jazn-data.xml
orion-application.xml
The orion-application.xml deployment descriptor is needed to define the
DBTableOraDataSourceLoginModule configuration. To create an orion-application.xml file in Oracle JDeveloper:
Select the View layer project and choose New from the context
menu to open the New Gallery.
In the Filter By select option, choose All
Technologies.
Expand the General node and select the Deployment
Descriptors entry.
Choose OC4J Deployment Descriptor Wizard from the
available options.
In the wizard choose orion-application.xml and continue.
In the following wizard page, choose version 10.0 for
a data-source.xml file that is required for JDeveloper version 10.1.3 and
above.
Unlike the embedded OC4J server, in which the application name for the JAAS
LoginModule is current-workspace-app, the application name
for the standalone OC4J instance is the name of the deployed J2EE application.
The application name can be defined when creating the deployment profile or
within the View layer project's properties. To open the properties dialog, select
the project node and choose Project Properties from the context
menu. Select the J2EE Application entry to specify the J2EE
application name and the name of the J2EE web context root.
Figure 4: J2EE Application definition in the View layer
project properties
In the example shown above, the application name of the deployed application
is secure-web-app. Edit the orion-application.xml file
to contain the LoginModule configuration:
The LoginModule configuration itself hasn't changed compared to the embedded
OC4J usage, except that the configuration is added to the orion-application.xml and not to the system-jazn-data.xml file. Upon deployment, OC4J performs
the system-jazn-data.xml configuration and also sets the required properties:
Note that t his configuration can be undone automatically when undeploying the J2EE web
application. Furthermore standalone OC4J instances can run J2EE web application using
both custom JAAS LoginModules for authentication and applications and the
default Realm LoginModule authentication at the same time.
data-sources.xml
The DBTableOraDataSourceLoginModule is configured with a data source
reference to connect to the database. The data-sources.xml file can be
deployed with the J2EE web application or created after deployment using
the Enterprise Manager web application console of OC4J, which you can
access from http://server:8888/em.
Creating a data-sources.xml file in Oracle JDeveloper is explained
earlier in this document.
system-jazn-data.xml
If the data-source.xml file is configured with password indirection,
which is the Oracle JDeveloper default, then the user account must be
added to the system-jazn-data.xml file of the OC4J instance. The system-jazn-data.xml file is located in the \j2ee\home\config directory of the OC4J instance.
There are two options available to add the account in OC4J.
Manual account creation
In this scenario, you open the data-sources.xml file created in Oracle
JDeveloper and locate the data-source definition of the data source used
in the LoginModule configuration. In the example configuration above,
this is jdbc/authschemaDS.
The content of the data-sources.xml file in this example is
Note that the jdbc/authschemaDS entry points to the jdev-connection-pool-authschema,
which has its password redirected to the DataBase_User_H3qWButn9PYa0q-iROlsk52Spi7YzAG_ user account.
You can either keep this reference or change it to an existing username
in the system-jazn-data.xml file of the target OC4J instance. Depending
on your configuration in JDeveloper, the user account equivalent to DataBase_User_H3qWButn9PYa0q-iROlsk52Spi7YzAG_ contained in the project specific jazn-data.xml file, or the <workspace name>-jazn-data.xml in the root directory
of your JDeveloper workspace in the file system.
It is also possible to change the user account name after deployment
using the EnterpriseManager web console of OC4J.
Figure 5: EnterpriseManager console in OC4J to
define the password indirection for a data source
Troubleshooting
This article explained how to configure the DBTableOraDataSourceLoginModule for the embedded and standalone OC4J. However, if things don't work as expected,
follow these steps to help identify the source of the problem.
Logging in embedded OC4J
The DBTableOraDataSourceLoginModule is a closed system in that it is
shipped without the source code. During application development it is
important for the developer to understand what the LoginModule does to
identify problems and their cause.
For the embedded OC4J container, edit the j2e-logging.xml file located
in the JDEVELOPER_HOME\jdev\system\oracle.j2ee.10.1.3.40.66\embedded-oc4j\config directory and add
Figure 6: Log messages printed to the JDeveloper
console
Logging in standalone OC4J
Logging for the standalone instance of OC4J is configured in the j2ee-logging.xml file located in the OC4J_HOME\j2ee\home\config directory. The log entries
are written in an XML format to the log.xml file located in the OC4J_HOME\j2ee\home\log\oc4j directory.
Please refer to the OC4J security documentation for more information
about configuring logging in OC4J.
Verifying the J2EE data sources connection working
To ensure the J2EE datasource used by the DBTableOraDataSourceLoginModule to connect to the database work, open a SQL*Plus session, connect as System
and type:
select username from v$session;
The resulting username list should contain an instance of the database
schema the DBTableOraDataSourceLoginModule connects to.
Unlocking database accounts
Too many failed attempts to connect to the database schema will eventually
lock the schema. You can verify this by opening SQL*Plus and connecting to
the schema. If the account is locked, connect as System and type:
alter user authschema account unlock;
This unlocks the account for further testing.
Summary
Database authentication and authorization in container-managed J2EE security
is possible through the OC4J DBTableOraDataSourceLoginModule or a custom
database JAAS LoginModule. Developers that extend existing non-J2EE applications
to Java usually have the requirement to leverage an existing database infrastructure
for authentication and authorization. The Oracle Application Server security
infrastructure in OC4J allows developers to configure standard JAAS LoginModules
to be used at design time and runtime instead of the default XML file-based or LDAP directory-based
provider. DBTableOraDataSourceLoginModule is a LoginModule provided by Oracle
that authenticates and authorizes users against a defined database schema in a secure
way by connecting to the database with J2EE data sources that protect the database
password through password indirection.
Note: A bug in DBTableOraDataSourceLoginModule
of OC4J 10.1.3.2 demands that the username column names are identical
in the two tables. When this bug is fixed, the username column in the
user table can be a different name than the name used for the same information
in the roles table.