Oracle9i Servlet Engine Developer's Guide
Release 1 (9.0.1)

Part Number A90213-02
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

7
Oracle Servlet Engine Security

This chapter covers basic aspects of security for the Oracle Servlet Engine, running in the Oracle Java Virtual Machine. This chapter focuses on security as established using the session shell tool. Chapter 8, "Oracle WAR Deployment" describes those aspects of security that are implemented using Web Archive (WAR) deployment files.

The topics discussed in this chapter are:

Overview

Security for the OSE/OJVM includes three security mechanisms:

  1. Oracle9i server security, which involves database schemas and roles.

  2. The JNDI protection mechanism, that is based on Oracle database security.

  3. The HTTP security mechanisms, involving realms, groups, and principals, and the access permissions associated with principals.

The first two aspects of OSE/OJVM security and the third are virtually orthogonal. The slight exception to their almost total independence comes when an HTTP security realm type uses database schemas as the principals. This is described in "The DBUSER Type".

This chapter first describes the JNDI protection mechanism that is based on Oracle database security, then describes how HTTP security is implemented by the OSE/OJVM. Although knowledge about basic database security and Java security in the database is helpful in reading this chapter, it is not essential. If you need more information on these topics see the following Oracle guides:

This Guide assumes some basic knowledge about HTTP security. For more information, you can look up the HTTP 1.1 specification RFC, which is available at

http://www.w3.org/Protocols/rfc2068/rfc2068

More accessible documentation about HTTP security is available in any of the trade press books that cover the Apache Web server. Two such are

JNDI Security

To create entries in the OSE/OJVM JNDI namespace, you must be in possession of a valid Oracle database schema name and password. Using the session shell tool requires a connection to a database session, which requires a database server login. For example, to create a Web service you must connect to the OSE session shell as the database schema SYS. If SYS then changes ownership of the service root to schema HR, then you have to be connected through the session shell as HR to do things like publish servlets, create HTTP security objects such as realms, add principals to realms, and so on.

When a client accesses the OSE, from a Web browser for example, and runs a servlet that is owned by a schema, then that servlet runs with all the database privileges associated with that schema. The servlet can query database tables or other database objects, update tables and other objects, run stored procedures, and do all the other things that a database user can do, exactly in accord with the database permissions that the schema possesses.

What HTTP security allows you to do is permit and restrict access to servlets and other JNDI objects (JSPs, text files, and so on) above and beyond the database access permissions. For example, you might not want all Web browser users to be able to access servlets that in turn access the HR database schema. So you can add authentication and authorization requirements to the HR servlets using HTTP security, which is described in "HTTP Security".

JNDI Security Implementation

JNDI security is implemented using a UNIX-like permissions scheme. Each OSE JNDI object, for example a published servlet in a named_servlets context, has an owner. The owner has a combination of three types of permission: read, write, and execute. The exact semantics of each permission type are described in the Oracle9i Java Tools Reference. In summary, read permission allows the session shell user to "read" the object: list it, get its properties, and actually read it to the extent that it is readable. Write permission allows the user to modify the object: delete it, substitute another object, write it to the extent it is writable (a text file, for example), add objects or properties to it (if it is a context, or a realm). Execute permission allows the user to have the OSE activate the object, if it is for example a servlet, or to search the object, if it is a context.

In addition to owner's permissions, each OSE JNDI object has an access control list. (This is where JNDI permissions differ somewhat from UNIX permissions, as the UNIX group concept is not directly implemented in the OSE JNDI namespace implementation.) So an object can have a list of database users (schemas), each of which can have a different set of access permissions.

Servlet Permissions

Normally, OSE JNDI objects in a servlet context inherit the ownership and permissions of the owner of the Web domain. However in many cases it is desirable for the owner of a domain to grant the right for other schemas to publish servlet contexts in that domain, and to then effectively publish servlets in those contexts. For example, the HR schema owns a domain HRRoot. HR can grant the schema BENEFITS the right to publish servlets in its own context in that domain.

Run As Owner

In the normal course of events, the OSE would use the domain owner's database permissions when executing servlets in a servlet context in the domain. However, the domain owner can establish that a servlet context is to run with the database permissions of the servlet context owner. This is set by adding a group property to the domain config object, as the follow example, for the HRRoot service shows

$ cd /HRRoot
$ addgroupentry config context.properties context.runAsOwner true

Granting Permissions

OSE JNDI object ownership is controlled using the session shell chown command, and permissions and access control lists are controlled by the chmod command. These commands are documented in the Oracle9i Java Tools Reference.

HTTP Security

HTTP security allows you to extend and refine the basic security provided by the JNDI/Oracle database security model. The OSE/OJVM supports the most popular aspects of the HTTP security model, including BASIC and DIGEST authentication, as well as authentication using Oracle Single Sign-On (OSSO).

While the database and JNDI security covers for the most part access to database objects, HTTP security determines who can access servlets from a Web client, and what HTTP requests clients can use.

Access to a protected Web service resource involves authentication and authorization. Authentication is the validation of submitted credentials, which establish that a client is known and validated by the system. Authorization is the determination that an authenticated user is allowed to perform the requested action.

There are four steps in setting up HTTP security for a Web application:

Follow these steps to ensure that the correct base information is established to define HTTP security for your Web resources. If one or more of these steps is not followed, security can become either non-existent, or access to protected resources can be denied to users who should have it.

Establishing the Principals

Principal is the generic term for either a servlet engine user, or a group of users. A group contains users or other groups. The realm is an object in the Web service that contains and organizes the declared principals. Figure 7-1 shows that the realm objects are at the top level of the Web service, in the realms context, which is at the same level as the config object for the Web service.

Figure 7-1 Realm objects in a Web service

Text description of JNDI_Realm.gif follows.
Text description of the illustration JNDI_Realm.gif

Groups

Groups contain other principals (users or other groups). Individual members of a group inherit the permissions of the group object.

Users

Users are single objects. Unlike a group, there are no subsets of other principals belonging to a user.

Realms

The realm is the basic unit of HTTP security in the OSE/OJVM. Each realm defines a separate set of principals. A Web service can contain multiple realms, as shown in Figure 7-1. The realm is the source of the valid set of principals, and the types of principals that are handed to the server. The realm is the source of all principals, and it also determines what kind of credentials are to be used to authenticate a principal.

Each realm has a type, which determines the way the realm information originates and the way it is stored. There are four types of realms, which are:

DBUSER

Uses only database schemas as principals.

RDBMS

Keeps all the realm information directly in a database table.

JNDI

Stores all realm information in objects in the OSE JNDI namespace.

OSSO

Used for Oracle Single Sign-On management.

The DBUSER Type

A realm that has the DBUSER type derives principal definitions and permissions from the users and roles defined in the database. The implications of this are:

The RDBMS and JNDI Types

These realm types behave the same, only the way the information about principals and groups is stored differs. You manage realms of this type using the session shell realm commands.

The OSSO Type

The OSSO realm type is described in "Configuring mod_osso".


Note:

The OSSO realm type is not available in Oracle8i Release 3. 


The Session Shell Realm Commands

The session shell realm commands are the tools that you use to establish, configure, and remove realms. Use these session shell commands to:

This chapter lists some common ways to use the realm commands. Complete documentation for the realm commands is available in the Oracle9i Java Tools Reference.

Realm Configuration

To Create or Remove a Realm

To create a realm, use the realm publish command. Here is an example:

$ realm publish -webservice /testRoot -add testRealm1 -type JNDI

You can also remove a realm using realm publish with the -remove option. An example is:

$ realm publish -webservice /testRoot -remove testRealm1

Realm declarations reside in the JNDI namespace. You could deploy a custom realm type that you have written using the -classname option. Here is an example:

$ realm publish -w /testRoot -add myRealm -classname steve:foo.bar.MyRealm

In this example, the realm name and the class name are the same, but they do not have to be so.

To Create or Remove a Principal

Create a user with the realm user command. An example is:

$ realm user -webservice /testRoot -realm testRealm1 -add steve -p boss

To create a group use realm group, as follows:

$ realm group -webservice /testRoot -realm testRealm1 -add HRgroup -p gpswd1 

With either of these commands, if the password is left blank, the principal name is used for the password.

You can delete a user as follows:

$ realm user -webservice /testRoot -realm testRealm1 -remove steve

To delete a group use the realm group command. An example is:

$ realm group -webservice /testRoot -realm testRealm1 -remove HRgroup

To List Users and Groups

Use the realm user command to list the users in a realm, as shown in this example:

$ realm user -webservice /testRoot -realm testRealm1

Use realm group to list groups in a realm. For example:

$ realm group -webservice /testRoot -realm testRealm1

To Add, Remove, or List the Principals for a Group

Use the parent variant of the realm command to add a principal to a group. Here is an example:

$ realm parent -w /testRoot -realm testRealm -group group1 -add user1

Remove a principal from a group also using realm parent, with the -remove option, as shown in:

$ realm parent -w /testRoot -realm testRealm -group group1 -remove user1

You can also list principals within a group by using the realm parent command. For example:

$ realm parent -w /testRoot -realm testRealm -group group1

To query which groups a principal is a member of use the -query option. For example:

$ realm parent -w /testRoot -realm testRealm -query user1


Notes:

Not all realms support the query option. For example, DBUSER realms do not support this kind of principal manipulation. 


Where Realms Are Located

When you declare realms for a service, they are located in a realms subcontext of the service. For JNDI-type realms, there are additional subcontexts within the realms context that contain the realm's principal declarations.

Removing the Web service realms context removes all realm definitions for the service, such as user and group names, permission mappings, and so on. However any external resources, such as table entries, would still remain. For efficient realm management, it is much better to use the session shell realm commands.

Removing subcontexts of realms can affect JNDI-type realms.

RDBMS-type realms use the following database tables:

Note that creating an RDBMS-type realm also creates a /realms context in the Web service root, and entries in this context. But no subcontexts are created for RDBMS-type realms.

Protecting Web Resources

Realms are containers for principals, groups, and the protection schemes that protect Web resources. OSE HTTP security resource protection is local to the servlet context.

Resource Protection Schemes

When you need to protect a Web resource, you declare a protection scheme. The syntax for a protection scheme is

<authType>:<realmName> | NONE

So, you specify an authentication method, followed by the name of the realm to which the authentication applies, or no protection (NONE).

There are only two valid authentication methods for the OSE/OJVM, as shown below.

BASIC

BASE64 encoding, which is very insecure.

DIGEST

In the DIGEST scheme, both parties keep the password, and pass encrypted codes. The DIGEST scheme is documented in RFC 2069, at



http://www.w3.org/Protocols/rfc2069/rfc2069

Form-based and SSL schemes are not supported, though they can be plugged in through namespace entries.

Although DIGEST is far more secure than BASIC, not all browsers support it.

You can also declare resources not to be protected. This is useful when the servlet context root is to be protected. However, when the root is protected, the error pages, being part of the tree, are also protected. Delivering an error page is part of the authentication process. If the error page is protected, cycles develop, and the desired behavior is not observed.

Instead of letting the error page default as part of the tree, explicitly declare the error pages as not being protected. Use a protection scheme of <NONE>. For example:

$ realm map -s /testRoot/contexts/myContext -a /system/* -scheme <NONE>
$ realm map -s /testRoot/myService/contexts/myContext -a /* -scheme \
basic:testRealm1

Using "realm map" to Protect Resources

The protected path is local to the servlet context. Internally, that path is normalized, enabling stable, predictable patterns for matching. This may cause the internal representation to differ from the original path used to create the protection scheme. HTTP Security will use the longest, most exact match possible when trying to apply the protection rules.

Here is an example that protects paths to resources with the BASIC protection scheme:

$ realm map -s /testRoot/contexts/myContext -a /doc/index.html -scheme \
basic:testRealm1 $ realm map -s /testRoot/contexts/myContext -a /doc -scheme basic:testRealm2 $ realm map -s /testRoot/contexts/myContext -a /doc/* -scheme basic:testRealm3

When declarations are made, as shown in the previous example, the paths are matched to realms as in the following examples:

/doc/index.html -> testRealm1 
/doc/foo -> testRealm3 
/doc -> testRealm2 
/doc/ -> testRealm2 
/doc/index -> testRealm3

You can remove the protection on a path using the realm map command, as shown here:

$ realm map -s /testRoot/contexts/myContext -r /doc/index.html

To list all protected paths within a servlet context, use the realm map command as shown here:

$ realm map -s /testRoot/contexts/myContext

You can explicitly declare that a path not be protected. Here is an example:

$ realm map -s /testRoot/contexts/myContext -a /system/* -scheme <NONE>

To list all protected paths within a servlet context, just use realm map and specify only the service root. For example:

$ realm map -s /testRoot/contexts/myContext

The JNDI entry for protection mappings is located in the policy subcontext of the servlet context. Within the policy subcontext there is an object called httpMapping. This creates the object responsible for handling the security servlet protection mapping. By default, httpMapping is used as an index into the JAVA$HTTP$REALM$MAPPING$ database table. The HTTP realm mapping table contains all the mapped paths. Using JNDI entry manipulation you could introduce a customized version of httpMapping.

Declaring Permissions

Permissions are the most complicated of all HTTP security declarations, because they tie service-scoped entities with servlet context-scoped entities and reside in the servlet context themselves.

To set up a permission declaration, supply the following information:

Given all the pieces that are being tied into one permission declaration, it is easy to see why these are the most complicated declarations.

HTTP Request Types

HTTP security permissions concern only valid HTTP request methods: GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS.

Examples of Permission Declarations

Declare a granted permission on /foo/index.html for user1 for GET and POST:

$ realm perm -w /testRoot -realm testRealm1 -s /testRoot/contexts/myContext -n \
user1 -u /foo/index.html + get,post

Declare a denied permission on /foo/* for user1 for PUT and DELETE:

$ realm perm -w /testRoot -realm testRealm1 -s /testRoot/contexts/myContext -n \
user1 -u /foo/* - put,delete

Clear granted permissions on /foo/index.html for user1:

$ realm perm -w /testRoot -realm testRealm1 -s /testRoot/contexts/myContext -n \
user1 -u /foo/index.html +

List all permissions for user1:

$ realm perm -w /testRoot -realm testRealm1 -s /testRoot/contexts/myContext -n \
user1

In the policy subcontext of a servlet context, there is a config object. This entry is used to create the object responsible for all permission declaration checks. The object is used as a key into the permissions table: JAVA$HTTP$REALM$POLICY$.

Declaring A Security Servlet

All HTTP security is declared through JNDI namespace entries. This is also true for the servlet that does the enforcing of security. In the servlet context, if there is a PrivilegedServlet named httpSecurity, that servlet is added as the first pre-filter for all requests within that servlet context.

Any customization is allowed as long as the PrivilegedServlet interface is implemented. The purpose of this servlet is to either:

or

After authentication and authorization have taken place, the servlet must set specific authenticated principal values on the request itself. This is the user information that can be retrieved from the request by any executing servlet.

Creating a Security Servlet

You can use realm secure to create a security servlet. For example:

$ realm secure -s /testRoot/contexts/myContext 

Removing the security servlet removes all security enforcement in a servlet context. If the entry is missing, the Web server continues execution with no security enforcement.

To remove a security servlet, type:

$ rm /myDomain/contexts/myContext/httpSecurity 


Note:

The servlet is not published in named_servlets but within the servlet context directory itself.  


Examples

There are two security-related examples in the $ORACLE_HOME/demo directory of your distribution. The demos are reproduced here.

rdbmsRealm

This example protects the path /event_log* with a realm that uses a database table for its source of principals. Note that paths in permission declarations are relative to the servlet context mapping.

This example presupposes that the sample database has already been setup. The prerequisites are:

First, make sure that there is a security servlet for the servlet context:

$ realm secure -s /HRRoot/contexts/HRContext

Publish a realm that uses a database table for its users:

$ realm publish -w /HRRoot -add docRealmExample -type rdbms

Create a user in the realm:

$ realm user -w /HRRoot -realm docRealmExample -add alex -p welcome

Create a group in the realm:

$ realm group -w /HRRoot -realm docRealmExample -add docGroup -p welcome

Add "alex" to the docGroup:

$ realm parent -w /HRRoot -realm docRealmExample -group docGroup -add alex

Allow docGroup to execute HTTP requests with the GET and POST methods:

$ realm perm -w /HRRoot -realm docRealmExample -s \
/HRRoot/contexts/HRContext -name docGroup -path /event_log + get,post

Protect the resource /event_log:

$ realm map -s /HRRoot/contexts/HRContext -add /event_log -scheme \
Basic:docRealmExample

Now, when a client tries to access /ose/event_log the browser prompts for a username and password. Be sure to type in the username with the correct capitalization ("alex"). Username/password is alex/welcome.

You could also enter username: docGroup password: welcome

To remove the password protection without removing the realm declaration, execute the following session shell command:

$ realm map -s /HRRoot/contexts/HRContext -remove /event_log

dbUserRealm

dbUserRealm is a simple example that protects the path /doc*, and only allows the database user HR access to it. Note that paths in permission declarations are relative to the servlet context mapping.

This example presupposes that the sample database has already been setup. The prerequisites are:

First, be sure that there is a security servlet for the /HRRoot/contexts/HRContext servlet context:

$ realm secure -s /HRRoot/contexts/HRContext

Next, publish a realm that uses database users as for its principals:

$ realm publish -w /HRRoot -add dbUserExample -type dbuser

Allow HR to execute HTTP requests with the GET and POST methods:

$ realm perm -w /HRRoot -realm dbUserExample -s \
/HRRoot/contexts/HRContext -name HR -path /http_log + get,post

Protect the resource /http_log:

$ realm map -s /HRRoot/contexts/HRContext -add /http_log -scheme \
Basic:dbUserExample

Now, when a client tries to access /ose/http_log for the HR demo server the browser prompts for username and password. Be sure that the letter case matches exactly. In this case, the username is literally "HR", and the password is "hr".

To remove the password protection without removing the realm declaration, execute the following session shell command:

$ realm map -s /HRRoot/contexts/HRContext -remove /http_log

Troubleshooting

There are several layers of suspected problems to eliminate when debugging HTTP security. This minimal checklist helps you get started trouble shooting.


Go to previous page Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback