Oracle® Containers for J2EE Security Guide 10g (10.1.3.4.0) Part Number E12514-01 |
|
|
View PDF |
Chapter 2, "Java Platform Security" provided an overview of three major Java security models: J2EE role-based security, Java 2 code-based security, and JAAS subject-based security.
This chapter shows how to use the authorization features with each of these models. They can be used individually or in combinations. At the end of the chapter there is discussion of how to choose between security models.
The following topics are covered:
This section discusses security managers and policy files for Java 2 (code-based) security, covering the following topics:
For Java 2 (code-based) security policies to be enforced by OC4J and the underlying JDK, a security manager (java.lang.SecurityManager
instance) must be enabled. This may affect, for example, access to class loaders, access to JDK resources, execution of JDK APIs, or execution of JAAS APIs (such as the ability for the Subject.doAs()
or Subject.doAsPrivileged()
method to be executed). With a security manager enabled, the policies specified in the Java 2 policy file determine the resources that executing code can access.
You can specify a security manager in either of the following ways:
Call the static setSecurityManager(SecurityManager)
method of the java.lang.System
class to specify any desired security manager.
Use the system property java.security.manager
when starting OC4J, either with no setting to use the default security manager, or with a setting that indicates a desired security manager.
The following example starts OC4J with the default security manager:
% java -Djava.security.manager ... -jar oc4j.jar
The following example specifies a security manager:
% java -Djava.security.manager=com.abc.MySecurityManager ... -jar oc4j.jar
Notes:
Using a security manager is not typically necessary in OC4J. Within an Oracle Application Server installation, OC4J instances run by default with no security manager. If you choose to install a security manager, there may be significant performance impact. If you use a custom security manager, ensure that it does not interfere with OC4J functions.
Assuming you use the default implementation of AccessController
(provided with the Sun JDK), a call to AccessController.checkPermission()
, discussed in "Using the checkPermission() Method", enforces Java 2 security policy for your application regardless of whether a security manager is enabled.
The permissions granted to particular classes by the default security manager are determined by reading a policy file. The default policy file is supplied as part of the J2SE. You can specify any desired policy file by setting the system property java.security.policy
to the full path of the desired file. The following example starts OC4J with the default security manager and the policy file that is supplied with OC4J:
% java -Doracle.home=$ORACLE_HOME -Djava.security.manager \ -Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy \ -jar oc4j.jar
Notes:
Be aware that this java2.policy
file includes permissions that are required for OC4J to run with a security manager. If you use a different policy file, make sure the same permissions are included in that file.
A .policy
file is for Java 2 (code-based) policies only. With the OracleAS JAAS Provider, JAAS (subject-based) policies are declared within the <jazn-policy>
element of the system-jazn-data.xml
file, or in Oracle Internet Directory if you are using the Oracle Identity Management security provider, as discussed in "OracleAS JAAS Provider Policy Configuration".
See Also:
The following sections, "Using PrintingSecurityManager to Determine Required Java 2 Permissions" and "Creating or Updating a Java 2 Policy File", for related information
"Java 2 Authorization: Security Managers and Access Controllers" for an overview of security managers
To assist you in identifying all the required permissions for an application running on OC4J, Oracle provides a custom security manager, PrintingSecurityManager
, that does not throw security exceptions. Instead, it prints a message specifying what exceptions the default security manager would have thrown. PrintingSecurityManager
also generates the policy grants that would avoid the security exceptions.
Run PrintingSecurityManager
as in the following example, assuming you run OC4J from ORACLE_HOME
/j2ee/home
:
% java -Xbootclasspath/p:lib/oc4j-psm.jar -Doracle.home=$ORACLE_HOME \ -Djava.security.manager=oracle.oc4j.security.PrintingSecurityManager \ -Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy \ -jar oc4j.jar
(-Xbootclasspath
puts PrintingSecurityManager
into the boot classpath, where it runs with all permissions.)
PrintingSecurityManager
generates output that lists the following:
Which codesources require which permissions
Policy grants that you can copy and paste into the policy file
By default, these outputs go to System.out
, but you can specify output files through the following system properties. The first is for messages about missing permissions; the second is for policy grants:
-Doracle.oc4j.security.manager.printing.file=filenamepath -Doracle.oc4j.security.manager.printing.generated.grants.file=filenamepath
Note:
PrintingSecurityManager
is not tied to OC4J, so you can alternatively use it outside of OC4J.A Java 2 policy file grants permissions to trusted code or applications, allowing them appropriate access privileges to execute properly in your environment.
A preconfigured Java 2 policy file, java2.policy
, is provided in ORACLE_HOME
/j2ee/home/config
. You can modify this file if desired, or create and specify an alternative policy file. Be aware, however, that the java2.policy
file supplied by Oracle includes permissions that are required for OC4J to run with a security manager. If you use a different policy file, make sure the same permissions are included in that file.
The following policy file sample grants all permissions, such as opening system files and opening sockets or ports, to the trusted jazn.jar
(the OracleAS JAAS Provider Admintool):
/* grant the JAAS library AllPermission */ grant codebase "file:${oracle.home}/j2ee/home/jazn.jar" { permission java.security.AllPermission; };
Similarly, the following example grants all permissions to wssecurity.jar
(for Web services security functions):
/* grant the WSSecurity AllPermission */ grant codebase "file:${oracle.home}/webservices/lib/wssecurity.jar" { permission java.security.AllPermission; };
The following example grants specific permissions to all applications running in the ORACLE_HOME
/appdemo
directory:
/* Assuming you are running your application demo in $ORACLE_HOME/appdemo/, */ /* Grant JAAS permissions to the demo to run JAAS APIs*/ grant codebase "file:/${oracle.home}/appdemo/-" { permission oracle.security.jazn.JAZNPermission "getPolicy"; permission oracle.security.jazn.JAZNPermission "getRealmManager"; permission oracle.security.jazn.policy.AdminPermission; }
You can grant additional permissions for your application code or for classes generated by OC4J, as necessary, by manually creating additional entries in the .policy
file. (There is currently no tool for this.) The required permissions will depend on the details of your application, and the required codebase will depend on the details of your installation.
Note:
Note the use of "${oracle.home}
" to specify the location of ORACLE_HOME
. This is an environment variable that is set appropriately by default.See Also:
For details about policy file syntax:
http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html
This section discusses the following authorization features in OC4J:
OracleAS JAAS Provider allows any protected resource to be modeled using Java permissions. The Java permission model (and associated java.security.Permission
class) is extensible and allows a flexible way to define fine-grained access control.
OracleAS JAAS Provider builds upon the J2SE standard, using standard APIs to support the following features related to fine-grained authorization:
JAAS mode, which is related to standard Subject.doAs()
and Subject.doAsPrivileged()
functionality for either Web applications or EJBs
OracleAS JAAS Provider realm and policy API features
Features for granting permissions
Features for checking permissions
Note:
APIs documented here can be used with eithersystem-jazn-data.xml
or Oracle Internet Directory as the policy repository.See Also:
"Authorization Coding and Configuration" for related task-oriented steps and examples
For standard JAAS programming reference information:
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html
For detailed JAAS API information, java.security.*
packages and javax.security.auth.*
packages:
http://java.sun.com/j2se/1.4.2/docs/api/
For details about permissions:
http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html
Oracle Containers for J2EE Security Java API Reference for Javadoc for the OracleAS JAAS Provider
OC4J 10.1.3.x implementations provide a fine-grained authorization feature called JAAS mode, which is related to standard functionality of the Subject
class static methods doAs()
and doAsPrivileged()
, discussed in "JAAS Authorization: Subject Methods doAs() and doAsPrivileged()".
These methods are used with your application according to your JAAS mode setting. Set JAAS mode in the jaas-mode
attribute of the <jazn>
element in the orion-application.xml
file of your application. JAAS mode determines doAs()
or doAsPrivileged()
usage as follows:
With the setting jaas-mode="doAs"
, application modules (Web modules and EJBs) are executed by OC4J within a Subject.doAs()
block.
This mode is useful if you want code-based security together with subject-based security.
With the setting jaas-mode="doAsPrivileged"
, application modules are executed within a Subject.doAsPrivileged()
block, using a null access control context.
This mode is useful if you want subject-based security only.
With the setting jaas-mode="null"
(default), modules are executed under neither method.
This mode is useful if you want code-based security only.
Because jaas-mode
is set in the application-level orion-application.xml
file, it will affect any Web module or EJB in the application.
Important:
Set jaas-mode
in orion-application.xml
only, not in jazn.xml
.
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 previous <jazn>
settings would be lost and would have to be redone.
<jazn provider="LDAP" />
Note:
JAAS mode replacesrunas-mode
and doasprivileged-mode
settings from earlier releases, in the <jazn-web-app>
element of orion-application.xml
or orion-web.xml
.
These settings are deprecated in OC4J 10.1.3.x implementations, but still supported for backward compatibility.
The setting jaas-mode="null"
is equivalent to runas-mode="false"
; jaas-mode="doas"
is equivalent to runas-mode="true"
with doasprivileged-mode="false"
; jaas-mode="doAsPrivileged"
is equivalent to runas-mode="true"
with doasprivileged-mode="true"
.
See Also:
"Java 2 Authorization: Security Managers and Access Controllers" for an introduction to access controllers and access control contexts
This section discusses OracleAS JAAS Provider classes and methods related to JAAS authorization.
An instance of the oracle.security.jazn.JAZNConfig
class represents a configuration of the <jazn>
element. This class includes the following methods:
JAZNConfig getJAZNConfig()
This static method of the JAZNConfig
class returns a JAZNConfig
instance.
RealmManager getRealmManager()
This instance method of the JAZNConfig
class returns a RealmManager
instance, which is used to manage realms.
The oracle.security.jazn.realm.RealmManager
class includes the following instance method:
Realm getRealm(String)
This method returns a realm object for the specified realm name.
An instance of the oracle.security.jazn.realm.Realm
class provides access to the store of users and roles for the particular realm. In the realm
package, user management is defined by the UserManager
interface and role management is defined by the RoleManager
interface. The Realm
class includes the following instance methods:
UserManager getUserManager()
This method returns a UserManager
instance, which you can use to manage users in this realm.
RoleManager getRoleManager()
This method returns a RoleManager
instance, which you can use to manage roles in this realm.
Use an oracle.security.jazn.realm.UserManager
instance to manage (add, retrieve, or remove) users in the realm. This interface includes the following method:
RealmUser getUser(String)
This method returns a user object, for the specified name of a user in the realm.
See Also:
Chapter 12, "User and Role API Framework" for information about new user and role APIs that are available, and in future releases will replace some of the APIs discussed here
The JAZNConfig
class, mentioned in the preceding section, also has the following method:
JAZNPolicy getPolicy()
This method returns an oracle.security.jazn.policy.JAZNPolicy
instance, which represents the repository of JAAS (subject-based) authorization policies.
The JAZNPolicy
interface includes the following methods:
void grant(Grantee, Permission)
This method grants the specified permission to the specified grantee, taking as input an oracle.security.jazn.policy.Grantee
instance and a java.security.Permission
instance.
void revoke(Grantee, Permission)
This method revokes the specified permission for the specified grantee.
boolean hasPermission(Grantee, Permission)
This method determines whether the specified grantee has the specified permission.
The Grantee
class includes a constructor that takes a Principal
instance as input:
new Grantee(Principal)
Table 5-1 summarizes permission classes supplied by Oracle.
Note:
Features to grant permissions to a role replace functionality in the deprecatedcom.evermind.security.Group
class.See Also:
For information about these classes, the OracleAS JAAS Provider Javadoc: Oracle Containers for J2EE Security Java API Reference
Table 5-1 OracleAS JAAS Provider Permission Classes
Permission | Part of Package | Description |
---|---|---|
|
Represents the right to administer a permission (that is, grant or revoke another user's permission assignment). |
|
|
The grantee of this permission is granted the right to further grant/revoke the target role. |
|
|
For authorization permissions. |
|
|
Represents permission actions for a realm (such as |
|
|
|
This permission is required for access to EJBs over the ORMI protocol. Typical usage is |
You can construct instances of these permission classes as follows:
new AdminPermission(String)
new AdminPermission(Permission)
The AdminPermission
constructor takes an encoded permission string or a java.security.Permission
instance.
new RoleAdminPermission(String)
new RoleAdminPermission(RealmRole)
The RoleAdminPermission
constructor takes one of the following:
A string indicating the name of the role whose administrative permission is to be granted, of the form realmname/rolename
. Specifying just "*
" will match all roles in the system; specifying "realm/
*
" will match all roles in the realm.
An oracle.security.jazn.realm.RealmRole
instance, which is an instance of a class that implements the RealmRole
interface, representing a role associated with a particular realm.
new JAZNPermission(String)
The JAZNPermission
constructor takes a symbolic name of the permission, such as "getRealmManager
", "getPolicy
", "getProperty
.propertyname
", and so on.
new RealmPermission(String realm, String actions)
The RealmPermission
constructor takes a string for the name of the realm, and a string consisting of a comma-delimited list of the actions applicable to the realm.
new RMIPermission(String param, String actions)
The RMIPermission
constructor takes a string for the RMIPermission
parameter (login
, for example) and a string consisting of a comma-delimited list of applicable actions.
You can also construct instances of standard permission classes, as needed:
new Permission(String permname)
The java.security.Permission
constructor takes a string to specify the name of the permission.
new BasicPermission(String permname)
The java.security.BasicPermission
constructor takes a string to specify the name of the permission.
new FilePermission(String path, String actions)
The java.security.FilePermission
constructor takes one string to specify the path of the file in question, and another string that is a comma-delimited list of permissible actions. Supported actions are "read", "write", "execute", and "delete".
new AllPermission()
An instance of the java.security.AllPermission
class is a permission that represents all other permissions. Its constructor takes no parameters.
Important:
AllPermission
should be used with caution, and only when necessary.Note:
While there are standard mechanisms for checking permissions (as described in the next section), JAAS does not provide standard mechanisms for managing users and granting permissions. This is why the classes and methods described in this section are Oracle-specific.Access control, such as checking permissions, was introduced in "Java 2 Authorization: Security Managers and Access Controllers". Any of the following APIs may be involved in retrieving and checking permissions.
The java.security.AccessController
class includes the following methods:
AccessControlContext getContext()
This method examines the current calling context, which includes the inherited access control context of the current thread, and represents the context as a java.security.AccessControlContext
instance.
void checkPermission(Permission)
Given a java.security.Permission
instance, this static method checks whether the access request indicated by the permission should be allowed, and throws an AccessControlException
if it should be denied. This method uses the default access control context.
Note that this method enables you to check against Java 2 policy (as applicable) without a security manager enabled.
The java.security.AccessControlContext
class includes the following method:
void checkPermission(Permission)
This has the same functionality as the AccessController.checkPermission()
method, but is called on a particular AccessControlContext
instance to use that access control context. (You can construct an AccessControlContext
instance from an array of ProtectionDomain
instances.)
Note that this method enables you to check against Java 2 policy (as applicable) without a security manager enabled.
The java.lang.SecurityManager
class includes the following method:
void checkPermission(Permission)
This has the same functionality as the checkPermission()
methods of the AccessController
and AccessControlContext
classes, but is used with a security manager in place, is called against the security manager instance, and throws a SecurityException
if access should be denied.
The javax.security.auth.Subject
class includes the following method:
Subject getSubject(AccessControlContext)
This static method returns the subject that is associated with the specified access control context. You can specify the default access control context as follows:
mysubject = Subject.getSubject(AccessController.getContext());
The abstract class javax.security.auth.Policy
includes the following methods:
Policy getPolicy()
This static method returns a Policy
instance.
PermissionCollection getPermissions(Subject, CodeSource)
This method, given a javax.security.auth.Subject
instance or a java.security.CodeSource
instance or both (inputs can be null), returns a java.security.PermissionCollection
instance that indicates the set of permissions allowed. The codesource field can be null
.
The PermissionCollection
class includes the following method:
boolean implies(Permission)
This abstract method indicates whether the specified permission is implied by the set of permissions in the permission collection. For example, if the permission collection consists of permissions of a subject, this method tells you if the subject has the specified permission, such as in the following example:
jaaspolicy = javax.security.auth.Policy.getPolicy(); jaaspolicy.getPermissions(mysubject,null).implies(perm);
Note:
Thejavax.security.auth.Policy
class is deprecated in JDK 1.4 but fully supported in OC4J 10.1.3.x implementations and still supported by the Sun Microsystems JDK and J2SE. As of this release, OC4J itself does not support the java.security.Policy
class.See Also:
"Java 2 Authorization: Java 2 Security Policies" for an introduction to codesources
JAAS based authentication is not well integrated with Java EE. Typically JAAS authentication requires the use of a login module. However, a login module (including custom login modules) do not assert the Subject into the container. This behavior causes applications to not use the authenticating subject. To solve this problem OC4J provides an API that allows a Subject to be asserted into the OC4J container that can be used in place of container managed security (declarative security).The API is located in the oracle.oc4j.security
package and is used as follows:
Security.setSubject(Subject subject, Longevity longevity);
The setSubject
method asserts the Subject identity into the container for this request and all further requests associated with the Web container if applicable. If the current application context does not have a Web component, then only the current application server thread context will make use of the Subject and upon returning to the pool it will be cleared. This API is only relevant for server-side execution and not for application client-side code.
subject
– the identity to assert into the container
longevity
– the duration for which the identity assertion should be held. This can be Longevity.REQUEST
or Longevity.SESSION
.
OC4J 10.1.3.x implementations support the Java Authorization Contract for Containers (JACC), as specified in JSR-115. This is a contract between containers and authorization service providers, allowing authorization to be decoupled from the container. OC4J authorization functionality is delegated to a standard JACC provider.
Note that as a result of the JACC contract, J2EE security constraints are translated into Java 2 permissions, so that the J2EE security model fully leverages the J2SE security model. Yet JACC still fully preserves the existing J2EE declarative security model as well as the J2EE security API. Essentially, you can enable JACC to use an extended version of J2EE authorization, using the same configuration and code for authorization in your application.
JACC is typically invisible to a developer; it is more of a deployment-time consideration.
The contract defined in JSR-115 interacts with an application server container, deployment tools, and policy provider, and is divided into the following subcontracts:
Provider configuration subcontract
Policy configuration subcontract
Policy decision and enforcement subcontract
JACC provides new java.security.Permission
class implementations that adhere to the J2EE authorization model. Under JACC, access decisions by the container are made according to operations on instances of these Permission
classes. JACC defines the ways that policy providers make use of the new permission classes to address requirements of the J2EE authorization model, as follows:
Defining roles as collections of permissions
Granting the permissions of a role to a principal
Determining whether a principal has been granted the permissions of a role
See Also:
For general information about JACC:
http://java.sun.com/j2ee/javaacc/ http://www.jcp.org/en/jsr/detail?id=115
There is not a set standard for subject-based policy management; the implementation is left up to each vendor. This section discusses how to use OracleAS JAAS Provider features for subject-based policy management—granting permissions, the resulting configuration, checking permissions, and (where necessary) explicitly specifying the OracleAS JAAS Provider policy provider:
See Also:
"Java 2 Security and Code-Based Policy Management" regarding code-based policy
With either system-jazn-data.xml
or Oracle Internet Directory as the policy repository, you can use the OracleAS JAAS Provider Admintool to grant, revoke, or list permissions—using the grantperm
, revokeperm
, or listperm
command, respectively. (An alternative, for runtime, is to use APIs discussed in the next section, "Using OracleAS JAAS Provider Policy Management APIs".) Complete syntax for these commands is documented in "Granting and Revoking Permissions" and "Listing Permissions".
You can grant permissions to a user (through the grantperm -user
option), to a role (through the -role
option), or to a principal.
For example, to grant RMI permission "login" to the role developers
in the realm myrealm
:
% java -jar jazn.jar -grantperm myrealm -role developers \ com.evermind.server.rmi.RMIPermission login
(RMI permission "login" is a permission you must often grant to allow EJB/RMI access.)
To grant this same permission to the user JDOE_ENDUSER
:
% java -jar jazn.jar -grantperm myrealm -user JDOE_ENDUSER \ com.evermind.server.rmi.RMIPermission login
To grant this permission to the LDAP principal hobbes
(when using an external LDAP provider):
% java -jar jazn.jar -grantperm oracle.security.jazn.realm.LDAPPrincipal hobbes \ com.evermind.server.rmi.RMIPermission login
To grant FilePermission
for a file sample.txt
for actions "read, write
" to user martha
in realm foo
:
% java -jar jazn.jar -grantperm foo -user martha java.io.FilePermission sample.txt read,write
Resulting configuration from the grantperm
command is discussed in "OracleAS JAAS Provider Policy Configuration".
See Also:
"OracleAS JAAS Provider Policy Configuration" regarding configuration resulting from permission grants
With either system-jazn-data.xml
or Oracle Internet Directory as the policy repository, you can use OracleAS JAAS Provider policy management APIs to grant or revoke permissions. (An alternative, for nonruntime, is to use OracleAS JAAS Provider Admintool commands discussed in the preceding section, "Granting Permissions through the OracleAS JAAS Provider Admintool".) In this example, the doGet()
method shown in "Using J2EE Authorization APIs" is expanded to use the OracleAS JAAS Provider policy management API to grant file permissions to a user.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream out = response.getOutputStream(); response.setContentType("text/html"); out.println("<HTML><BODY bgcolor=\"#FFFFFF\">"); out.println("Time stamp: " + new Date().toString()); out.println("request.isUserInRole('ar_developers') = " + request.isUserInRole("ar_developers") + "<br>"); try { //Grant Permissions to a user developer //get JAZNConfiguration related info JAZNConfig jc = JAZNConfig.getJAZNConfig(); //create a Grantee for "developer" RealmManager realmmgr = jc.getRealmManager(); Realm realm = realmMgr.getRealm("jazn.com"); UserManager userMgr = realm.getUserManager(); final RealmUser user = userMgr.getUser("developer"); //grant developer file permission JAZNPolicy policy = jc.getPolicy(); if ( policy != null) { Grantee gtee = new Grantee( (Principal) user); java.io.FilePermission fileperm = new java.io.FilePermission("foo.txt", "read"); policy.grant( gtee, fileperm); } } catch (Exception e) { /* print stack trace */ } out.println("</BODY>"); out.println("</HTML>"); }
See Also:
"OracleAS JAAS Provider APIs for Granting or Revoking Permissions"
The next section, "OracleAS JAAS Provider Policy Configuration", regarding configuration resulting from permission grants
This section documents subject-based policy configuration that results from granting permissions when you use the OracleAS JAAS Provider Admintool or policy management APIs, as discussed in preceding sections. In OC4J, this configuration can be located in either the system-jazn-data.xml
file or in Oracle Internet Directory, depending on the security provider.
The following topics are covered:
Note:
Configuration discussed here is for subject-based security only. Code-based security is configured in a Java 2 policy file (.policy
), as discussed in "Specifying a Java 2 Security Manager and Policy File" and "Creating or Updating a Java 2 Policy File".The policy repository for security policies for an OC4J instance is the provider specified in the jazn.xml
file, as indicated by the provider
setting in the <jazn>
element, as follows:
provider="XML"
to use system-jazn-data.xml
for policy configuration
provider="LDAP"
to use Oracle Internet Directory for policy configuration
By default, provider
in jazn.xml
is set to "XML
" to use system-jazn-data.xml
as the policy repository. When you use Oracle Identity Management and associate an Oracle Internet Directory instance with the OC4J instance, the provider setting in jazn.xml
is changed to "LDAP
", resulting in the use of Oracle Internet Directory as the policy repository.
(Similarly, the provider
setting in orion-application.xml
specifies the security provider of the application, which is "XML
" for the file-based provider, "LDAP
" for Oracle Identity Management, and by convention is also "XML"
for an external LDAP provider, custom login module, or Oracle Access Manager.)
Note:
Policy repository configuration injazn.xml
(such as settings for the provider
and location
attributes of the <jazn>
element) is OC4J instance-level configuration. If you deploy an application to the OC4J instance, and the application configures a different provider, the result would be a mixed usage where the provider configured in orion-application.xml
would be the identity store used for authentication, while the provider specified in jazn.xml
would be the policy store used for authorization.For the file-based provider, Oracle Access Manager, an external LDAP provider, or a custom login module, policy configuration is located in the <jazn-policy>
element of the system-jazn-data.xml
file.
As an example, we repeat one of the grantperm
examples from "Granting Permissions through the OracleAS JAAS Provider Admintool":
% java -jar jazn.jar -grantperm myrealm -role developers \ com.evermind.server.rmi.RMIPermission login
This results in <jazn-policy>
configuration such as in the following example:
<jazn-data> ... <jazn-policy> <grant> <grantee> <principals> <principal> <realm-name>myrealm</realm-name> <type>role</type> <class>oracle.security.jazn.XMLRealmRole</class> <name>developers</name> </principal> </principals> </grantee> <permissions> <permission> <class>com.evermind.server.rmi.RMIPermission</class> <name>login</name> </permission> </permissions> </grant> ... </jazn-policy> ... </jazn-data>
For Oracle Identity Management (the LDAP-based provider), policy configuration is located in Oracle Internet Directory. As with system-jazn-data.xml
, policy information stored in Oracle Internet Directory is accessible through the OracleAS JAAS Provider Admintool or policy management APIs.
If you use the Java virtual machine shipped with Oracle Application Server, the JAAS policy provider supplied with OracleAS JAAS Provider is automatically specified as the policy provider to use in OC4J. If you use another JVM (in other words, if you run an application outside OC4J), then the Oracle JAAS policy provider, oracle.security.jazn.spi.PolicyProvider
, must be explicitly specified as the policy provider. (By default, a non-Oracle JVM uses the Sun Microsystems JAAS provider.)
You can specify Oracle-specific JAAS properties, such as the policy provider, in a security properties file that you supply to the JVM when you run OC4J. Oracle offers a default security properties file, ORACLE_HOME
/j2ee/home/config/jazn.security.props
, that specifies oracle.security.jazn.spi.PolicyProvider
as the policy provider to use in OC4J, with the following configuration:
auth.policy.provider=oracle.security.jazn.spi.PolicyProvider
To append default Oracle-specific security property settings, including the above specification of the Oracle JAAS policy provider, to existing security properties, set the java.security.properties
system property as follows:
-Djava.security.properties=ORACLE_HOME/j2ee/home/config/jazn.security.props
To replace all security properties with the Oracle properties (note the two equals signs, "=="):
-Djava.security.properties==ORACLE_HOME/j2ee/home/config/jazn.security.props
This section provides discussion and examples of the following steps to check authorization during runtime:
Enabling the Java Authorization Contract for Containers (optional extension of J2EE authorization)
Samples here use a servlet method, but the basic functionality is similar for EJBs.
See Also:
Appendix B, "OracleAS JAAS Provider Samples" for the complete example
This sample servlet doGet()
method uses standard J2EE authorization methods to retrieve a user and principal, and determine whether a user is in the specified role.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream out = response.getOutputStream(); response.setContentType("text/html"); out.println("<HTML><BODY bgcolor=\"#FFFFFF\">"); out.println("Time stamp: " + new Date().toString()); out.println("request.isUserInRole('ar_developers') = " + request.isUserInRole("ar_developers") + "<br>"); out.println("</BODY>"); out.println("</HTML>"); }
To perform authorization in your code, you will often have to obtain a Subject
instance for the authenticated user who is attempting to access resources. You can accomplish this through standard JAAS functionality, using the static Subject.getSubject()
method and specifying an access control context.
Typically, use the default access control context:
mysubject = Subject.getSubject(AccessController.getContext());
Alternatively, you can specify a particular access control context (such as one you have constructed from a set of protection domains, for example):
mysubject = Subject.getSubject(acc);
Note that when you use JAAS mode, OC4J associates an authenticated subject and its permissions with the default access control context and its permissions.
You will typically use a checkPermission(Permission)
call in your authorization code, which checks whether the access request indicated by the specified permission should be allowed, based on the security policy currently in effect, and throws an exception if not.
This method is available in the AccessController
and AccessControlContext
classes. Assuming you use the default implementations (provided with the Sun JDK), the checkPermission()
method of either class can enforce Java 2 (code-based) policy in your application regardless of whether a security manager is enabled.
When you use a security manager, the method is also available in the SecurityManager
class, but the default SecurityManager
implementation of checkPermission()
calls AccessController.checkPermission()
.
You will typically use the AccessController.checkPermission()
method, which is static. This call uses the default access control context (the context inherited when the thread was created). If you want the permissions check to be with respect to some other context, however, you can call the instance method checkPermission()
on a particular AccessControlContext
instance. The following example uses the AccessController
method:
//create permission FilePermission perm = new FilePermission("/home/developer/foo.txt","read"); //check permission AccessController.checkPermission(perm);
In OC4J, any JAAS mode setting is relevant with respect to what the access control context consists of when AccessController.checkPermission()
is called, as follows:
With no JAAS mode (jaas-mode="null"
), checkPermission()
enforces code-based security based on the security policy in effect, as presumably specified in a Java 2 policy file. There is no provision for subject-based security.
With doAs
JAAS mode (jaas-mode="doas"
), checkPermission()
enforces a combination of code-based and subject-based security according to the new access control context created through the doAs()
block within which OC4J executes your application code. OC4J appends the permissions of the subject to the permissions of the default access control context.
With doAsPrivileged
JAAS mode (jaas-mode="doasprivileged"
), checkPermission()
has the same functionality as in doAs
mode, but OC4J uses a null access control context, as specified when OC4J calls doAsPrivileged()
. This is to use subject-based security only.
In this example, the doGet()
method shown in "Using J2EE Authorization APIs" is expanded to create and check permissions. Furthermore, assume the JAAS mode doAsPrivileged
, which is set with configuration such as the following in the application orion-application.xml
file:
<orion-application ... > ... <jazn ... jaas-mode="doAsPrivileged" /> ... </orion-application>
The code follows, using two different ways to check permissions, for demonstration purposes. Because of the JAAS mode setting, the action method, in this case doGet()
, will be executed by OC4J within a Subject.doAsPrivileged()
block for the authenticated subject.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream out = response.getOutputStream(); response.setContentType("text/html"); out.println("<HTML><BODY bgcolor=\"#FFFFFF\">"); out.println("Time stamp: " + new Date().toString()); out.println("request.isUserInRole('ar_developers') = " + request.isUserInRole("ar_developers") + "<br>"); //create Permission FilePermission perm = new FilePermission("/home/developer/foo.txt","read"); { // CHECK PERMISSION VIA ACCESS CONTROLLER AccessController.checkPermission(perm); // CHECK PERMISSION VIA JAAS POLICY //get current AccessControlContext AccessControlContext acc = AccessController.getContext(); javax.security.auth.Policy currPolicy = javax.security.auth.Policy.getPolicy(); // Query policy now out.println("Policy permissions for this subject are " + currPolicy.getPermissions(Subject.getSubject(acc),null)); //Check Permissions out.println("Policy.implies permission: "+ perm +" ? " + currPolicy.getPermissions(Subject.getSubject(acc),null).implies(perm)); } out.println("</BODY>"); out.println("</HTML>"); }
See Also:
This section describes how to enable the Oracle JACC provider in OC4J. With JACC, J2EE security constraints are translated into Java 2 permissions to effectively provide an extended version of J2EE authorization, using the same configuration and code for authorization in your application.
The following topics are covered:
Note:
JACC is supported only for the file-based provider. Generated policies are stored insystem-jazn-data.xml
.See Also:
"Implementation of Java Authorization Contract for Containers" for an overview
By default, JACC is disabled in OC4J. It can be enabled with the following system property setting at OC4J startup:
-Doracle.oc4j.security.jacc=true
To employ a JACC provider, the system properties described in Table 5-2 must be set appropriately at application server startup. For the Oracle JACC provider, this happens automatically when you enable JACC, with the properties being set as shown in parentheses.
Table 5-2 System Properties for the JACC Provider
Property | Description |
---|---|
javax.security.jacc.policy.provider |
Class name of the policy provider (oracle.security.jacc.provider.J2SEPolicy) |
javax.security.jacc.policy. PolicyConfigurationFactory.provider |
Class name of the policy mapping configuration factory (oracle.security.jacc.provider. JACCPolicyConfigurationFactory) |
oracle.security.jacc.provider. RoleMappingConfigurationFactory.provider |
Class name of the role mapping configuration factory (oracle.security.jacc.provider. JACCRoleMappingConfigurationFactoryImpl) |
For each of the key Java security models discussed earlier—J2EE, Java 2, and JAAS—this section summarizes when it may be advantageous to use it, and how it works. Complete operational details are provided elsewhere in this manual (mostly earlier in this chapter).
J2EE (static role-based) security is a coarse-grained model that specifies what security roles can access a Web application or EJB.
When Should You Use It?
In a J2EE application, this is the simplest and most basic form of security. Almost any J2EE application will use it, and it will often be enough to suit your needs. It is standard and therefore platform-independent.
Because of its limitations, however, it is sometimes used in conjunction with the other security models. Note that with J2EE security alone, you cannot control access to particular resources or define particular permissions for a role. You also cannot control access by particular code entities. In addition, the J2EE security model is a static model; policies cannot be changed at runtime.
How Do You Set It Up?
Set up J2EE security through standard specifications for security roles, role-linking, and security constraints through the web.xml
and ejb-jar.xml
files, in addition to specifications for role-mapping through the OC4J-specific descriptors such as orion-application.xml
.
If you use only J2EE security, JAAS mode is unnecessary (jaas-mode="null"
).
How Is It Enforced?
J2EE security is enforced by the J2EE container (OC4J).
Java 2 (code-based) security controls access to resources based on the location of executing code or on code signers.
When Should You Use It?
Use Java 2 security when your application must check code-based permissions, perhaps regardless of the user or role trying to access it. With Java 2 security, an administrator can enable or disable a security manager to control when the security manager performs security checks.
Generally, code-based security and the use of a security manager is required only if a situation may arise where the application server is exposed to untrusted code. Also be aware that there may be a performance impact with the use of a security manager.
Java 2 security may be used in conjunction with either J2EE security, JAAS security, or both.
How Do You Set It Up?
Specify Java 2 policies through a standard .policy
file, typically named java.policy
or java2.policy
. The policy file ORACLE_HOME
/j2ee/home/config/java2.policy
is supplied with OC4J and includes permissions that are required for OC4J to run with a security manager.
Oracle provides no tools to maintain Java 2 policy files; you must do so manually or use tools provided by the JDK vendor or a third-party vendor.
If you use Java 2 security alone or with J2EE security only, JAAS mode is unnecessary (jaas-mode="null"
).
How Is It Enforced?
For Java 2 security policies to be enforced by an application server and the underlying JDK, a security manager must be enabled.
For Java 2 security policies to be enforced within your application:
If you want the capability of code-based security in your application, but with an administrator being able to control when the security checks are performed, you can choose to enforce code-based security only when a security manager is enabled. In this case, you can use the checkPermission()
method of the SecurityManager
instance.
Be aware that for this scenario, the JVM must be started with a security manager enabled.
If code-based security requirements in your application are independent of a security manager, you can choose to enforce code-based security within your application regardless of the presence of a security manager. In this case, you can use the static AccessController.checkPermission()
method to check permissions.
In this scenario, it is important to note that the overall environment will not be secure without a security manager. Other code in the environment, including JDK classes, will not be running in a secure mode.
To specify the particular protection domains to be checked, you can construct an AccessControlContext
instance from an array of ProtectionDomain
instances, and call the checkPermission()
method on the AccessControlContext
instance. (This is not a common usage scenario, however.)
JAAS (subject-based) security is a relatively fine-grained model that controls access to resources according to the particular permissions of the authenticated subject.
When Should You Use It?
Usually, the coarser-grained security of the J2EE model will suffice. JAAS security is more complicated to administer and deploy; however, JAAS security is valuable if you want finer control over resources, such as:
According to factors other than whether the resource is accessed as part of the execution of a Web module or EJB
According to individual permissions that can be granted or revoked either by an administrator beforehand or in your code at runtime
J2EE security, by contrast, is more static—access control cannot be modified at runtime.
JAAS security is typically used together with J2EE security, and may also be used together with Java 2 security.
How Do You Set It Up?
You can grant (or revoke) permissions either beforehand, using the OracleAS JAAS Provider Admintool (as shown in "Granting Permissions through the OracleAS JAAS Provider Admintool") or at runtime through OracleAS JAAS Provider APIs (as shown in "Using OracleAS JAAS Provider Policy Management APIs"). The resulting JAAS (subject-based) policy is reflected in system-jazn-data.xml
, or Oracle Internet Directory if you use Oracle Identity Management as the security provider.
How you set the JAAS mode is also relevant. To use JAAS authorization without Java 2 (code-based) authorization, use the doAsPrivileged
JAAS mode by setting jaas-mode="doasprivileged"
, and check permissions by using the Policy.implies()
method.
To use JAAS authorization together with Java 2 authorization:
Use the doAs
JAAS mode by setting jaas-mode="doas"
.
Specify Java 2 policies through a standard .policy
file, typically the java2.policy
file supplied by Oracle.
Note:
If a resource being accessed indoAsPrivileged
mode is a resource defined by the JVM vendor, additional security checks may be performed if a security manager is enabled.How Is It Enforced?
You can enforce JAAS security through the AccessController.checkPermission()
method or Policy.implies()
method.
If you are also using Java 2 security and have a security manager enabled, you can alternatively use the SecurityManager.checkPermission()
method.
(Also refer to earlier discussion regarding enforcement of Java 2 policy.)