Oracle® Containers for J2EE Security Guide 10g (10.1.3.5.0) Part Number E13977-01 |
|
|
View PDF |
This chapter discusses general tasks and related guidelines that apply across the various security providers you can use with OC4J:
See Also:
Oracle Application Server Best Practices (available post-release) for information about best practices for security
The following Web site for OC4J "how-to" examples:
http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html
Many OC4J components require passwords for authentication. Embedding these passwords into deployment and configuration files poses a security risk, especially if the permissions on the files allow them to be read by any user. To avoid this problem, OC4J provides two solutions:
Password indirection, which replaces cleartext passwords with information necessary to look up the password in another location (system-jazn-data.xml
in OC4J).
Password obfuscation, which replaces passwords stored in cleartext files with an encrypted version of the password.
The rest of this discussion covers these topics:
The following configuration files support password indirection in one or more elements:
data-sources.xml
: password
attribute of <native-data-source>
and <managed-data-source>
elements
ra.xml
: <res-password>
element
rmi.xml
: keystore-password
attribute of <ssl-config>
element
jms.xml
: <password>
element
*-web-site.xml
: keystore-password
attribute of <ssl-config>
element
To make any of these passwords indirect, replace the literal password string with a string containing "->
" followed by either the user name or by the realm and user name separated by a slash ("/
").
Here are some examples of indirect versus direct passwords.
<data-source password="->Scott">
Look up Scott
in the default realm, and use the password stored in the password manager.
<res-password="->customers/Scott">
Look up Scott
in the customers
realm, and use the password stored there.
<cluster password="mypass">
The literal string "mypass
" is the password; the password is not indirect.
Note:
If you choose to use indirect passwords in the current OC4J implementation, an indirect user is created in thesystem-jazn-data.xml
file. If an indirect user account is created, either automatically or manually, undeploying an application does not automatically remove the account; you must manually remove the account.The <password-manager>
element in the OC4J-specific system-application.xml
file (associated with the OC4J system
application) specifies the security provider that is used to look up indirect passwords (discussed in the preceding section, "Using Password Indirection"). If this element is omitted, the security provider of the global application is used for authentication and authorization of indirect passwords. The <jazn>
element within a <password-manager>
element in the system-application.xml
file can be different from the <jazn>
element at the top level of that file.
Note that for security reasons, credentials stored in Oracle Internet Directory cannot usually be retrieved in decrypted (cleartext) format, which means that Oracle Internet Directory cannot be used as a password manager for your application. To resolve this, you can specify the file-based provider as your application password manager, even when your application uses Oracle Identity Management as the security provider.
To do this, add an entry such as the following to the OC4J-specific system-application.xml
file:
<password-manager> <jazn provider="XML" location=ORACLE_HOME/j2ee/instance_name/config/system-jazn-data.xml /> </password-manager>
Note:
By default,system-jazn-data.xml
is used as the password manager.The JAAS configuration files jazn.xml
and system-jazn-data.xml
(or optionally an application-specific jazn-data.xml
file) contain user names and passwords for JAAS authorization. To protect these files, OC4J uses password obfuscation.
Generally, whenever you update jazn.xml
or system-jazn-data.xml
, OC4J reads the file, then rewrites it with obfuscated (encrypted) versions of all passwords.
In addition (relevant for Oracle Identity Management), a setting for the ldap.password
property within a <jazn>
element, such as in orion-application.xml
, is obfuscated. For example:
<jazn ... > <property name="ldap.password" value="welcome123"/> ... </jazn>
In other OC4J configuration, you can avoid exposing password cleartext by using password indirection, as explained in "Using Password Indirection".
Note:
Insystem-jazn-data.xml
or an application-specific jazn-data.xml
file, you can specify clear (human-readable) passwords in one of two ways, although this is discouraged:
Set the clear
attribute of the <credentials>
element to "true
":
<user> <name>myname</name> <credentials clear="true">welcome</credentials> ... </user>
Precede the password with "!" (in which case "!" is not considered part of the password):
<credentials>!welcome</credentials>
In OC4J, both the file-based provider and LDAP-based Oracle Identity Management use the concept of security realms, introduced in "Security Realms in the OracleAS JAAS Provider". You can configure a single realm or multiple realms, and the default realm is specified through your OC4J configuration. Note that the concept of realms is not supported when you use external LDAP providers such as Active Directory or Sun Java System Directory Server.
This section discusses key details for using security realms to control authentication and authorization in OC4J, covering the following topics:
Default Realm with the File-Based Provider or Oracle Identity Management
Evaluation of Default Realm for File-Based Provider, Oracle Identity Management
Omitting the Realm Name When Retrieving an Authenticated Principal
A default realm is specified in the default-realm
attribute of the <jazn>
element. For the file-based provider, this is either at application level in your orion-application.xml
file, or at the OC4J level in the instance-level jazn.xml
file. For Oracle Identity Management, this is in the jazn.xml
file of the OC4J home
instance.
For the file-based provider, jazn.com
is configured as the default realm by default, at the instance level:
<jazn provider="XML" location="./system-jazn-data.xml" default-realm="jazn.com" />
For Oracle Identity Management, the default realm is according to the Oracle Internet Directory, where it is determined during Oracle Internet Directory installation. After you associate OC4J with an Oracle Internet Directory instance, the default realm is reflected at the OC4J instance level, such as in the following example:
<jazn provider="LDAP" location="ldap://www.example.com:636" default-realm="us"/>
"Using the Default Realm" discusses guidelines to be aware of when you use the default realm.
Important:
A default realm should always be specified, even if you use only one realm. For the file-based provider, this means you should specify a default realm when you configure your security provider during application deployment.
Do not remove configuration of the jazn.com
realm from system-jazn-data.xml
; it is there by default and must remain there for use by the OC4J system
application.
As noted in the preceding section, a default realm should always be configured. However, for reference purposes only, this section discusses the progression that is followed to determine the default realm if one is not specified, when using the file-based provider or Oracle Identity Management.
If your application uses the file-based provider:
OracleAS JAAS Provider looks for default realm configuration at the application level, in the orion-appliation.xml
file. If a default realm is found there, it is used as the default realm for your application.
If there is no default realm setting at the application level, OracleAS JAAS Provider looks for default realm configuration at the OC4J instance level, in the jazn.xml
file:
If jazn.xml
sets provider="XML"
, OracleAS JAAS Provider uses the default realm specified in jazn.xml
, if one is specified, as the default realm for your application. If none is specified, an error is thrown to indicate that you are missing the default realm attribute.
If jazn.xml
sets provider="LDAP"
, OracleAS JAAS Provider uses jazn.com
as the default realm for your application.
If your application uses Oracle Identity Management:
If configuration specifies the LDAP-based provider both for your application and at the OC4J instance level (in jazn.xml
), then OracleAS JAAS Provider looks for default realm configuration in jazn.xml
. If a default realm is found there, it is used as the default realm for your application.
If configuration does not specify the LDAP-based provider at the OC4J instance level, or if there is no default realm setting at the instance level, the Oracle Internet Directory default subscriber is used as the default realm. (This is configured in the Oracle Internet Directory server.)
For authentication, when you use the default realm, there is no need to prefix the user name with a realm name. For example, if a user scott
is in the default realm jazn.com
, for authentication the user name need only be specified as "scott
".
This is also true for applicable OC4J components and services such as JNDI, JMS, and J2EE Connector Architecture.
Similarly, for password indirection, the OC4J deployment descriptor need not prefix the realm name in the user name specified for indirection: "->scott
".
If you are using a nondefault realm (in other words, a custom realm)—such as acme.com
, for example, in this discussion—you must always prefix user names with the realm name. To authenticate the user scott
in acme.com
, for example, you would have to specify "acme.com/scott
", not just "scott
".
This is also the case for applicable OC4J components and services such as JNDI, JMS, and J2EE Connector Architecture.
Similarly, for password indirection, the OC4J deployment descriptor must prefix the realm name in the user name specified for indirection, if the user is in a nondefault realm: "->acme.com/scott
".
Also be aware that when you use a custom realm, and JAAS policies are granted to users or roles in the custom realm, you should do the following:
In the <jazn>
element of your application orion-application.xml
file, specify a default-realm
setting of "custom_realm_name
".
Do not specify a location
attribute setting in the <jazn>
element.
Set the jaas.username.simple
property to "false
" in jazn.xml
, using a <property>
subelement of the <jazn>
element, as discussed in "Omitting the Realm Name When Retrieving an Authenticated Principal".
These steps allow the custom realm and its users, roles, and policies to be persisted.
Note that to use JAAS authorization, in particular to grant permissions to users or roles in a custom realm, the custom realm and its users and groups must be defined and persisted in system-jazn-data.xml
, not in an application-specific jazn-data.xml
file.
When multiple realms are configured, you must prefix user names with the realm name for any nondefault realm that you use. For this discussion, assume the realms jazn.com
, acme.com
, and example.org
are configured, with jazn.com
being the default realm. Further assume user scott
is in jazn.com
, while user ralph
is in example.org
.
To specify scott
for authentication, you need only specify the user as "scott
", because he is in the default realm jazn.com
.
To specify ralph
for authentication, you must specify "example.org/ralph
".
This is also the case for applicable OC4J components and services such as JNDI, JMS, and J2EE Connector Architecture. The realm name must be specified for a user in any nondefault realm.
Similarly, for password indirection, the OC4J deployment descriptor must prefix the realm name in the user name specified for indirection if the user is in any nondefault realm: "->example.org/ralph
". But you need not specify the realm name for any user in the default realm, such as "scott
".
Important:
Always setjaas.username.simple
to "false
" when multiple realms are configured. (See the next section, "Omitting the Realm Name When Retrieving an Authenticated Principal".)Unless you configure custom realms, it is typically desirable to omit the realm name from the authenticated principal that is returned by key methods for servlets, EJBs, and Web services. In OC4J, use the jaas.username.simple
property to control this behavior. This property affects the following methods:
getUserPrincipal()
method of any HTTPServletRequest
instance (servlets)
getRemoteUser()
method of any HTTPServletRequest
instance (servlets)
getCallerPrincipal()
method of any EJBContext
instance (EJBs)
getUserPrincipal()
method of any ServletEndpointContext
instance (Web services)
With a "true
" property setting, which is the default, principal names returned by these methods do not include the realm name: for example, "scott
".
If you set the property to "false
", then principal names returned by these methods are prefixed with the realm name: for example, "jazn.com/scott
".
To specify a "false
" setting, use a <property>
subelement of the <jazn>
element (in orion-application.xml
for application level, or in the instance-level jazn.xml
file for OC4J instance level) as follows:
<jazn ... > ... <property name="jaas.username.simple" value="false" /> ... </jazn>
Important:
If you switch from the file-based provider to Oracle Identity Management at any time for any application through Application Server Control, the <jazn>
element in orion-application.xml
for the application is replaced with the following. Any prior settings within the <jazn>
element would be lost and would have to be redone.
<jazn provider="LDAP" />
Always set jaas.username.simple
to "false
" when multiple realms are configured.
This section discusses security issues to consider when deploying your application, covering the following topics:
See Also:
Oracle Containers for J2EE Deployment Guide for a full discussion of deployment and related considerations
The security provider is designed to work with the J2EE declarative security model. This declarative model requires little or no programming to use JAAS security in your application. Instead, most security decisions are made as part of the deployment process, making it easy to make changes without requiring re-coding. If the declarative model is not sufficient, the security provider also supports programmatic security in the same manner that JAAS is used in any J2SE environment.
Using the declarative security model, the deployer must make the following security-related decisions:
Decide which security provider you want to use. The Oracle Application Server includes Oracle Identity Management, which uses the LDAP-based Oracle Internet Directory as the repository, and the file-based provider, which uses an XML file as the repository. OC4J also supports external (third-party) LDAP providers, custom security providers (custom login modules), and, beginning in OC4J 10.1.3.x implementations, the Oracle Access Manager.
Determine the J2EE logical roles that are assumed in the application, then define these roles in the deployment descriptors. For example, an HR application may assume that the J2EE role hr_manager
is running the application; the deployer must define that role.
Determine the authorization constraints that apply to these roles and define them in the deployment descriptors. For web modules, these constraints typically apply to URL patterns as defined in the J2EE specification. EJB modules typically have constraints at the EJB-method level.
Map the security roles (including the application-specific roles, if they exist) to users and roles defined by the OracleAS JAAS Provider. For example, the J2EE role called hr_manager
may be mapped to a given set of users defined by the OracleAS JAAS Provider.
Consider whether you have any code that you will want to load as shared libraries (login modules, for example).
This section discusses how to deploy an application, focusing on the functionality of the Application Server Control Console.
General information about deploying an application to OC4J, including information about deployment plans and using Application Server Control Console, is provided in the Oracle Containers for J2EE Deployment Guide. This section reviews the basic steps:
In the OC4J Home page, select the Applications tab. (In an Oracle Application Server environment, from the Cluster Topology page, choose the desired OC4J instance to get to its home page.)
In the resulting Applications page, choose Deploy.
In the resulting Deploy: Select Archive page (page 1 of 3), specify the archive file to deploy and your desired choice for a deployment plan.
In the Deploy: Application Attributes page (page 2 of 3), specify the desired application name, parent application, Web site, and context root.
In the Deploy: Deployment Settings page (page 3 of 3), you can choose any of the following tasks:
Map Environment References (if applicable)
Select Security Provider
Map Security Roles (if applicable)
Configure EJBs (if applicable)
Configure Clustering
Configure Class Loading (such as for loading shared libraries)
For security, selecting a security provider and mapping security roles are of particular interest. You may also want to configure class loading for shared libraries, such as if you have login modules that you want to load as shared libraries.
In the Deploy: Deployment Settings page, when you are done with any applicable tasks mentioned in the previous step, select Deploy.
This section discusses how to specify the security provider using Application Server Control Console, as well as considerations for using the file-based provider versus the LDAP-based provider.
Generally, use the file-based provider during development and for deployed applications with a small user population, such as in a standalone OC4J environment. Use Oracle Identity Management in larger production environments.
The file-based provider is a lighter-weight implementation, while Oracle Identity Management offers better security and performance. The centralized Oracle Internet Directory server scales well as the number of applications and users grows, and enables you to configure cache parameters to improve overall performance of authentication and authorization. It also simplifies access to the user repository from multiple OC4J instances; with the file-based provider, user data updates have to be coordinated between instances, given that each instance has its own repository.
In addition, Oracle Internet Directory offers features such as centralized account creation and management, single passwords, and credential management.
Note:
To use Oracle Identity Management, the OC4J instance must have been previously associated with an Oracle Internet Directory instance through Application Server Control.In Application Server Control Console, specify the security provider during deployment, from the Deploy: Deployment Settings page (see "Deploying an Application through Application Server Control" for how to get to this page), as follows:
Choose the Select Security Provider task.
In the resulting Deployment Settings: Select Security Provider page, choose the desired security provider from the dropdown list. The choices are:
File-Based
Oracle Identity Management
Third Party LDAP Server (for an external LDAP provider)
Custom (for a custom login module)
Each type of security provider necessitates its own set of configuration tasks, documented in the following locations:
Back in the Deploy: Deployment Settings page, choose Deploy to complete the deployment, or choose another task, as desired. The list of tasks is noted in "Deploying an Application through Application Server Control".
Note:
The Oracle Access Manager security provider is not supported through Application Server Control (although its login module can be configured through Application Server Control like any other login module). See Chapter 11, "Oracle Access Manager" for information about how to configure Oracle Access Manager.This section discusses various aspects of the following:
Defining security roles in an application and linking them to J2EE logical roles declared in the standard deployment descriptor
Mapping J2EE roles to deployment roles in the OC4J-specific configuration, and how to accomplish this mapping in Application Server Control
The information is organized as follows:
Specifying Security Role Mapping through Application Server Control
Mapping J2EE Roles to Deployment Roles in OC4J Configuration Files
Using the OC4J PUBLIC Role to Allow General Access by Authenticated Users
Note:
Security role mappings are not inherited from a parent application.See Also:
The process of security role definitions and references includes the following steps:
In your standard deployment descriptor (web.xml
or ejb-jar.xml
), use <security-role>
elements to define J2EE logical roles, such as in the following example:
<security-role> <role-name>sr_developers</role-name> </security-role>
Use <security-role-ref>
elements in the standard deployment descriptor to link from the roles you have developed in your application to the J2EE roles you have defined in the standard descriptors, such as in the following example, where ar_developers
is an application role:
<security-role-ref> <role-name>ar_developers</role-name> <role-link>sr_developers</role-link> </security-role-ref>
After these steps, mappings to deployment roles defined in the security provider (such as in a jazn-data.xml
file or the system-jazn-data.xml
file for the file-based security provider, or in Oracle Internet Directory for the LDAP-based provider) are defined in the OC4J-specific descriptors—orion-web.xml
, orion-ejb-jar.xml
, or orion-application.xml
. These files are updated, as appropriate, through the mappings you define when you deploy an application through Application Server Control, and are reflected in <security-role-mapping>
elements. These mappings are discussed in the next two sections, "Specifying Security Role Mapping through Application Server Control" and "Mapping J2EE Roles to Deployment Roles in OC4J Configuration Files".
See Also:
The preceding discussion leaves out some details that differ between Web applications and EJBs. Refer to the following for additional information:In Application Server Control Console, map J2EE roles to deployment roles during the deployment process, from the Deploy: Deployment Settings page (see "Deploying an Application through Application Server Control" for how to get to this page), as follows:
Select the Map Security Roles task.
In the resulting Deployment Settings: Map Security Roles page, choose the Map Role task for each J2EE role you want to map. (You can also choose Clear All Mappings.)
In the Deployment Settings: Map Security Role page for the role, you can do any of the following:
Map all users and groups (deployment roles) to the J2EE role.
Map selected users to the J2EE role. Choose Add Existing User, then specify the desired users in the Select and Search: Users page, then choose Select. If Add Existing User does not list the desired user, use the Add User feature in the Deployment Settings: Map Security Role page.
Map selected groups to the J2EE role. Choose Add Existing Group, then specify the desired groups in the Select and Search: Groups page, then choose Select. If Add Existing Group does not list the desired group, use the Add Group feature in the Deployment Settings: Map Security Role page.
Choose Continue when you are finished mapping users and groups.
Back in the Deployment Settings: Map Security Roles page, choose OK.
Back in the Deploy: Deployment Settings page, choose Deploy to complete the deployment, or choose another task, as desired. The list of tasks is noted in "Deploying an Application through Application Server Control".
These actions create <security-role-mapping>
elements in the applicable OC4J configuration file, such as orion-application.xml
, orion-web.xml
, or orion-ejb-jar.xml
, as shown in the next section, "Mapping J2EE Roles to Deployment Roles in OC4J Configuration Files".
Note:
There is no way to alter security mappings through Application Server Control after deployment. You would have to update the configuration manually (as shown in "OC4J Mapping of J2EE Roles to Deployment Roles" and "Mapping J2EE Roles to Deployment Users and Roles") and then restart or redeploy the application.Portable J2EE logical roles defined in a standard deployment descriptor are mapped to deployment roles in OC4J through <security-role-mapping>
settings in the orion-application.xml
file (to apply throughout a J2EE application), orion-web.xml
file (to apply to a particular Web application), or orion-ejb-jar.xml
file (to apply to a particular EJB application).
In this example, the J2EE role sr_developers
is mapped to the deployment role developers
. Note that a <group>
subelement under a <security-role-mapping>
element corresponds to a deployment role, such as one defined in system-jazn-data.xml
or Oracle Internet Directory. You can also have <user>
subelements for mapping individual users.
<security-role-mapping name="sr_developers"> <group name="developers" /> </security-role-mapping>
This association permits the developer
role to access resources that are accessible to the sr_developers
role according to security constraints configured in the standard deployment descriptors.
Consider a user john
, for example, who is a member of the developer
deployment role. Because this role is mapped to the J2EE role sr_developers
, john
has access to the application resources available to the sr_developers
role.
For situations where you care only about authentication, not authorization, OC4J supports a mode where any authenticated user is allowed access to a given application or resource. This is supported through the PUBLIC
role, and can be configured down to a per-URL or per-method basis as desired. This involves the following steps:
If you do not already have a J2EE logical role intended for public access, you can define such a role in web.xml
(for a Web application) or in ejb-jar.xml
(for an EJB).
For example, in web.xml
:
<web-app> ... <security-role> <role-name>public_role</role-name> </security-role> ... <auth-constraint> <role-name>public_role</role-name> </auth-constraint> ... </web-app>
Or, in ejb-jar.xml
:
<assembly-descriptor> ... <security-role> <role-name>public_role</role-name> </security-role> ... <method-permission> <role-name>public_role</role-name> <method>method</method> </method-permission> ... </assembly-descriptor>
Map your public role to the PUBLIC
role in orion-application.xml
(for a Web application) or orion-ejb-jar.xml
(for an EJB).
To map the role defined in web.xml
above, include the following in orion-application.xml
:
<orion-application> ... <security-role-mapping name="public_role"> <group name="{{PUBLIC}}"/> </security-role-mapping> ... </orion-application>
Or, for an EJB, use the <security-role-mapping>
element in orion-ejb-jar.xml
instead (where it is a subelement of the <assembly-descriptor>
element).
Note:
This example assumes the default setting of "{{PUBLIC}}
" for the OC4J public group. This may be overridden through the OracleAS JAAS Provider public.group
property.This section discusses the following consideration for after you have deployed your application:
After you have deployed your application, you can go to the Security Provider page for your application in the Application Server Control Console to examine or update the application-level security settings. Starting from the OC4J Home page for your OC4J instance:
Choose the Administration tab.
In the Administration page, go to the Security Providers task (under "Security").
In the Security Providers page, under "Application Level Security", go to the Edit task for your application.
This brings you to the Security Provider page, displaying information on the provider for your application and allowing you to update settings or change to a different security provider.
The OracleAS JAAS Provider is integrated with the OC4J class loading architecture. You can make libraries available to applications by loading them as OC4J shared libraries. This is useful to share the following among applications, for example:
Login modules
Principal classes for authorization and subject propagation
Identity management framework implementation classes
There are two main steps to sharing and using a library (considering functionality of the Application Server Control Console in particular):
Note:
The<library>
element and ORACLE_HOME
/j2ee/home/applib
location are still supported for OC4J shared libraries, but are discouraged.See Also:
Oracle Containers for J2EE Developer's Guide for more information about OC4J class loading and shared libraries
To load a library as an OC4J shared library through Application Server Control, use the Shared Libraries task.
Go to the Administration tab for the OC4J instance.
Choose the Shared Libraries Task (under Properties).
From the Shared Libraries page, choose Create.
From the Create Shared Library: Attributes page, specify the desired library name and version, then proceed to the next page.
From the Create Shared Library: Add Archives page, choose Add to add a library.
From the Add Archives: Add Archive page, you can choose to upload a library from the local host, upload a library from the server where Application Server Control is located, or specify a location on the target server where the library already exists. Repeat this process for each library you want to add, then continue.
Again from the Create Shared Library: Add Archives page, you can either finish, or go to the next page, Create Shared Library: Import Shared Libraries page. There you can import additional libraries into your library, then finish. This takes you back to the Shared Libraries page.
Loading a library results in configuration such as the following in the OC4J server.xml
file:
<application-server ... > ... <shared-library name="mylib.lib" version="1.0" library-compatible="true"> <code-source path="../mypath" /> </shared-library> ... </application-server>
You can import a library into your application through Application Server Control in the process of deploying your application:
When you reach the Deploy: Deployment Settings page (as discussed in "Deploying an Application through Application Server Control"), you can choose the Configure Class Loading task to import shared libraries.
From the Deployment Settings: Configure Class Loading page, choose the libraries to import, then choose OK.
Proceed with the deployment.
Importing a library results in configuration such as the following in your application orion-application.xml
file:
<orion-application ... > ... <imported-shared-libraries> <import-shared-library name="mylib.lib" /> ... </imported-shared-libraries> ... </orion-application>