This chapter includes in the following topics:
To use OPSS in a Java SE application:
Place the jps-manifest.jar
file in the class path.
Call the JpsStartup.start
method at initialization.
Set the following properties:
oracle.security.jps.config
, the file path to the jps-config-jse.xml
file.
common.components.home
, the path to the oracle_common
directory.
java.security.policy
, the path to the file java.policy
.
opss.audit.logDirectory
, the path to a writable directory where audit writes records for the application.
Set -Djava.security.policy
to the location of the Oracle WebLogic Server weblogic.policy
policy file (located in the wl_home/server/lib
directory).
Use the OPSS AppSecurityContext
class and note the required associated grant:
String appID = AppSecurityContext.getApplicationID(); try { setApplicationID(appName); ..... } finally { setApplicationID(appID ); } } private static void setApplicationID(final String applicationID) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { AppSecurityContext.setApplicationID(applicationID); return null; } }); }
The call AppSecurityContext.setApplicationID
requires that you include in your jps-config-jse.xml
a codesource permission like the following:
<grant> <grantee> <codesource> <url>myJavaSEapp/-</url> </codesource> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>AppSecurityContext.setApplicationID.myAppStripeID</name> </permission> </permissions> </grant>
The following sections describe the states, runtime options, and examples of use of the JpsStartup
class:
The transition states of the JpsStartup.start
method are defined by the following constants:
UNINITIALIZED
- The state before a call to JpsStartup.start
.
INITIALIZING
- The state to which it transitions after calling JpsStartup.start
.
FAILURE
- The state to which it transitions if the INITIALIZING
state run into any errors.
ACTIVE
- The state to which it transitions if the INITIALIZING
state completed successfully.
INACTIVE
- The state to which it transitions after calling the JpsStatup.stop
method.
The JpsStartup.getState
method returns the current OPSS state.
The class includes the following constructor:
JpsStatup(java.lang.String platformType, java.util.Map<java.lang.String,ContextConfiguration> ctxtCfgs, java.util.Map<java.lang.String,?> options)
Call this constructor when you want to start OPSS with additional context details and options.
The ctxCfgs
argument holds the details of the context specified in the jps-config-jse.xml
file. To start contexts other than the default context, pass multiple context information. To start a context other than the default context, pass the context name. If unspecified, then it uses the default context.
The options
argument groups specific OPSS startup values. For information about runtime options, see Table 24-1.
See also:
The following table describes the options you use with the jpsStartup
method:
Table 24-1 JpsStartup Runtime Options
Option | Values | Default | Description |
---|---|---|---|
|
The name of an active context. |
default |
Use the specified context. Otherwise, use the default context. |
|
|
|
Set to |
|
|
|
Set to |
|
|
|
Set to |
|
|
|
Set to |
|
|
|
Set to SCRIPT to have the following options set to
Otherwise set to |
|
The path to |
Use the specified path. Otherwise, use the default path. |
This section illustrates the use of the JpsStartup
class in typical scenarios.
Example 1
The following example illustrates how to start OPSS with no explicit parameters.
JpsStartup jpsStartUp = new JpsStartup(); jpsStartUp.start(); jpsStartUp.getState(); jpsStartUp.stop();
Example 2
The following example illustrates how to start OPSS with specific configuration values. Note that:
default1
is the default context passed as part of the contextConfig
map.
To disable audit, set ENABLE_AUDIT_SERVICE_EXT
to false
. By default, it is enabled.
To disable runtime services set ENABLE_POLICY_STORE_SERVICE_EXT
to false
. By default, it is enabled.
ConfigurationServiceProvider prov = ConfigurationServiceProvider.newInstance(); ConfigurationService configService = prov.getConfigurationService(); ContextConfiguration configuration = configService.getContextConfiguration("default1"); Map<String, ContextConfiguration> contextConfig = new HashMap<String, ContextConfiguration>(); contextConfig.put(JpsConstants.DEFAULT_CONTEXT_KEY, configuration); Map<String, Object> option = new HashMap<String, Object>(); option.put(JpsConstants.ENABLE_AUDIT_SERVICE_EXT, "FALSE"); option.put(JpsConstants.ENABLE_POLICY_STORE_SERVICE_EXT, "FALSE"); JpsStartup jpsStartUp = new JpsStartup("JSE", contextConfig, option); jpsStartUp.start(); jpsStartUp.stop();
Example 3
The following example illustrates how to start OPSS with an additional context:
Map<String, Object> startupOption = new HashMap<String, Object>(); ConfigurationServiceProvider prov = ConfigurationServiceProvider.newInstance(); ConfigurationService configService = prov.getConfigurationService(); ContextConfiguration configuration = configService.getContextConfiguration("default1"); Map<String, ContextConfiguration> contextConfig = new HashMap<String, ContextConfiguration>(); contextConfig.put(JpsConstants.DEFAULT_CONTEXT_KEY, configuration); JpsStartup jpsStartUp = new JpsStartup("JSE", contextConfig, startupOption); jpsStartUp.start(); jpsStartUp.stop();
Example 4
The following example illustrates how to start OPSS with multiple contexts. It assumes that the jps.config-jse.xml
file includes the contexts:
<jpsContexts default="default"> <jpsContext name="default"> <serviceInstanceRef ref="credstore"/> ... </jpsContext> <jpsContext name="default1"> <serviceInstanceRef ref="idstore.loginmodule"/> ... </jpsContext> <jpsContext name="default2"> <serviceInstanceRef ref="keystore"/> ... </jpsContext> <jpsContext name="default3"> <serviceInstanceRef ref="policystore "/> ... </jpsContext> <jpsContext name="bootstrap_credstore_context"> <serviceInstanceRef ref="bootstrap.credstore"/> </jpsContext> </jpsContexts> ConfigurationServiceProvider prov = ConfigurationServiceProvider.newInstance(); ConfigurationService configService = prov.getConfigurationService(); ContextConfiguration configuration1 = configService.getContextConfiguration("default1"); ContextConfiguration configuration2 = configService.getContextConfiguration("default2"); ContextConfiguration configuration3 = configService.getContextConfiguration("default3"); Map<String, ContextConfiguration> contextConfig = new HashMap<String, ContextConfiguration>(); contextConfig.put(JpsConstants.DEFAULT_CONTEXT_KEY, configuration); contextConfig.put(("default1", configuration1); contextConfig.put(("default2", configuration2); contextConfig.put(("default3", configuration3); Map<String, Object> startupOption = new HashMap<String, Object>(); startupOption.put(JpsConstants.ACTIVE_CONTEXT, "default"); JpsStartup jpsStartUp = new JpsStartup("JSE", contextConfig, startupOption); jpsStartUp.start(); jpsStartUp.stop();
The ACTIVE_CONTEXT
parameter specifies the context to use as default. If DEFAULT_CONTEXT_KEY
is not passed as part of map, then the default context is started provided there is no ACTIVE_CONTEXT
key passed as part of startupOption
map.
Example 5
The following example illustrates how to start OPSS in the SCRIPT
mode. This mode is used when you do not want runtime services started.
Map<String, Object> startupOption = new HashMap<String, Object>(); startupOption.put(JpsConstants.RUNTIME_MODE, "SCRIPT"); JpsStartup jpsStartUp = new JpsStartup("JSE", startupOption); jpsStartUp.start(); jpsStartUp.stop();
The following sections describe the OPSS support in Java SE applications:
The following sections explain the identity store support in Java SE applications:
A Java SE application can use an LDAP identity store configured in the jps-config-jse.xml
file with the serviceProvider
, serviceInstance
, and jpsContext
elements:
<serviceProviders> <serviceProvider type="IDENTITY_STORE" name="idstore.ldap.provider" class="oracle.security.jps.internal.idstore.ldap.LdapIdentityStoreProvider"> <description>Prototype LDAP ID store</description> </serviceProvider> </serviceProviders> <serviceInstances> <serviceInstance name="idstore.ldap" provider="idstore.ldap.provider"> <property name="idstore.type" value="OID"/> <property name="max.search.filter.length" value="500"/> <extendedProperty> <name>user.search.bases</name> <values> <value>cn=users,dc=us,dc=oracle,dc=com</value> </values> </extendedProperty> <extendedProperty> <name>group.search.bases</name> <values> <value>cn=groups,dc=us,dc=oracle,dc=com</value> </values> </extendedProperty> </serviceInstance> </serviceInstances> <jpsContexts default="ldap_idstore"> <jpsContext name="ldap_idstore"> <serviceInstanceRef ref="idstore.ldap"/> </jpsContext> <jpsContext name="bootstrap_credstore_context"> <serviceInstanceRef ref="bootstrap.cred"/> </jpsContext> </jpsContexts>
Note the following points:
The name of the serviceInstance
(idstore.ldap
in the example) must match the instance referenced in serviceInstanceRef
.
The name of the serviceProvider
(idstore.ldap.provider
in the example) must match the provider specified in serviceInstance
.
Unless otherwise stated the information in this section applies to both Java EE and SE applications, and the API you use to call login modules is common to both kinds of applications.
A login module is a component that authenticates users and populates a subject with principals. The login module authenticates a user after requesting a name and a password or some other data. If the authentication succeeds, then the module assigns the relevant principals to the subject.
In any of the supported login modules, set the following properties:
enable.anonymous (default: false) remove.anonymous.role (default: true) add.application.roles (default: true) add.authenticated.role (default: true)
The supported login modules are:
In Java SE applications, the default identity store service supports the User Authentication and the User Assertion login modules.
Use the User Authentication login module in both Java EE or SE applications to authenticate a user with a given user name and password. The configuration of this login module is available ready-to-use, and it authenticates against the domain identity store.
The following example illustrates the use of this module for programmatic authentication:
import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; public class MyCallbackHandler extends CallbackHandler { private String name = null; private char[] password = null; public MyCallbackHandler(String name, char[] password) { this.name = name; this.password = password; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof NameCallback) { NameCallback ncb = (NameCallback) callback; ncb.setName(name); } else if (callback instanceof PasswordCallback) { PasswordCallback pcb = (PasswordCallback) callback; pcb.setPassword(password); } else { throw UnsupportedCallbackException(callback); } } } } JpsLoginModuleFactory factory = JpsLoginModuleFactory.getLoginModuleFactory(); CallbackHandler cbh = new MyCallbackHandler("name", "password".toCharArray()); LoginContext ctx = factory.getLoginContext(JpsLoginModuleType.USER_AUTHENTICATION, null, cbh); ctx.login(); Subject s = ctx.getSubject();
Use the User Authentication login module in both Java EE and SE applications to assert a user identity in the identity store. This requires provisioning an oracle.security.jps.JpsPermission
permission and implementing the oracle.security.jps.callback.IdentityCallback
callback, as described in the following sections:
Provisioning the jpsPermission
The following example illustrates a grant allowing the jdoe
principal permission to execute the User Assertion login module:
<grant> <grantee> <principals> <principal> <class>weblogic.security.principal.WLSUserImpl</class> <name>jdoe</name> </principal> </principals> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>IdentityAssertion</name> <action>execute</action> </permission> </permissions> </grant>
See also:
Implementing the CallbackHandler
The following example illustrates an implementation of the callback handler:
import oracle.security.jps.callback.IdentityCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class AssertCallbackHandler implements CallbackHandler { private String name = null; public AssertCallbackHandler(String name) { this.name = name; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof IdentityCallback) { IdentityCallback nc = (IdentityCallback) callback; nc.setIdentity(name); } else { throw new UnsupportedCallbackException(callback); } } } }
Implementing the Programmatic Assertion
The following example illustrates how to assert a user:
import oracle.security.jps.callback.IdentityCallback; import oracle.security.jps.internal.api.jaas.module.JpsLoginModuleFactory; import oracle.security.jps.internal.api.jaas.module.JpsLoginModuleType; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import java.io.IOException; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; Subject subject = AccessController.doPrivileged(new PrivilegedExceptionAction<Subject>() { public Subject run() throws Exception { JpsLoginModuleFactory f = JpsLoginModuleFactory.getLoginModuleFactory(); CallbackHandler cbh = new AssertCallbackHandler(name); LoginContext c = f.getLoginContext(JpsLoginModuleType.USER_ASSERTION, null, cbh); c.login(); return c.getSubject(); } });
A Java SE application can use a stack of login modules to authenticate its users. Each module performs its own computations independently from the others in the stack, and they are specified in the jps-config-jse.xml
file.
The sequence in which a context lists the login modules in a stack is significant because the authentication algorithm takes this order into account in its computation. Ready-to-use, the identity store service is specified in the system-jazn-data.xml
file. The service can be reconfigured to use an LDAP store.
OPSS APIs includes the oracle.security.jps.service.login.LoginService
interface that allows a Java SE application to call not just all the login modules in a stack, but a subset of them in a prescribed order. The context passed to LoginContext
in this interface determines the stack of login modules that your application uses.
The class associated with Identity Store login module is the oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule
class.
Properties specific to this login module include remove.anononymous.role
and add.application.role
.
You configure an instance of this module in the jps-config-jse.xml
file:
<serviceInstance name="idstore.loginmodule" provider="jaas.login.provider"> <description>Identity Store Login Module</description> <property name="loginModuleClassName" value="oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule"/> <property name="jaas.login.controlFlag" value="REQUIRED"/> </serviceInstance>
The following sections explain the use of this module in Java SE applications:
Using the Identity Store Login Module for Authentication
This section describes the use of the Identity Store login module for basic user name and password authentication.
The following example illustrates how to configure the appName
context:
<jpsContext name="appName"> <serviceInstanceRef ref="jaaslm.idstore1"/> </jpsContext> <serviceProvider type="JAAS_LM" name="jaaslm.idstore" class="oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule"> <description>Identity Store-based LoginModule </description> </serviceProvider> <serviceInstance name="jaaslm.idstore1" provider="jaaslm.idstore"> <property name="jaas.login.controlFlag" value="REQUIRED"/> <property name="debug" value="true"/> <property name="addAllRoles" value="true"/> </serviceInstance>
The following example illustrates a callback that handles the name and password:
import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.callback.*; import java.io.IOException; Subject sub = new Subject(); CallbackHandler cbh = new YourCallbackHandler(); LoginContext context = new LoginContext(appName, subject, cbh); context.login();
public class SampleCallbackHandler implements CallbackHandler { //For name/password callbacks private String name = null;private char[] password = null; public SampleCallbackHandler(String name, char[] pwd) { if (name == null || name.length() == 0 ) throw new IllegalArgumentException("Invalid name "); else this.name = name; if (pwd == null || pwd.length == 0) throw new IllegalArgumentException("Invalid password "); else this.password = pwd; } public String getName() { return name; } public char[] getPassword() { return password; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { if (callbacks != null && callbacks.length > 0) { for (Callback c : callbacks) { if (c instanceof NameCallback) { ((NameCallback) c).setName(name); } else if (c instanceof PasswordCallback) { ((PasswordCallback) c).setPassword(password); } else { throw new UnsupportedCallbackException(c); } } } } }
Using the Identity Store Login Module for Assertion
To use the Identity Store login module for assertion, provide a permission to execute the protected setIdentity
method, and implement the callback handler that uses the oracle.security.jps.callback.IdentityCallback
class.
The following example illustrates a configuration that allows the MyApp
application permission to execute protected methods in the assertion login module:
<grant> <grantee> <codesource> <url>file:${soa.oracle.home}/application/myApp.ear</url> <--! soa.oracle.home is a system property set when the server JVM is started --> </codesource> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>IdentityAssertion</name> </permission>t </permissions> </grant>
The following example illustrates the configuration that allows the jdoe
user permission to execute the assertion login module:
<grant> <grantee> <principals> <principal> <class>weblogic.security.principal.WLSUserImpl</class> <name>jdoe</name> </principal> </principals> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>IdentityAssertion</name> </permission> </permissions> </grant>
The following example illustrates an implementation of the callback handler:
import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import oracle.security.jps.callback.IdentityCallback; public class CustomCallbackHandler implements CallbackHandler { private String name = null; private char[] password; public CustomCallbackHandler(String name) { this.name = name; } public CustomCallbackHandler(String name, char[] password) { this.name = name; this.password = password; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof NameCallback) { NameCallback nc = (NameCallback) callback; nc.setName(name); } else if (callback instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) callback; pc.setPassword(password); } else if (callback instanceof IdentityCallback) { IdentityCallback idcb = (IdentityCallback)callback; idcb.setIdentity(name); idcb.setIdentityAsserted(true); idcb.setAuthenticationType("CUSTOM"); } else { //throw exception throw new UnsupportedCallbackException(callback); } } } }
The following example illustrates the implementation of a login module:
import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import oracle.security.jps.service.JpsServiceLocator; import oracle.security.jps.service.login.LoginService; public class LoginModuleExample { private static final String CONTEXT_NAME = "JSE_UserAuthnAssertion"; public LoginModuleExample() { super(); } public Subject assertUser(final String username) throws Exception { CallbackHandler cbh = AccessController.doPrivileged(new PrivilegedExceptionAction<CallbackHandler>() { public CallbackHandler run() throws Exception { return new CustomCallbackHandler(username); } }); Subject sub = new Subject(); LoginService ls = JpsServiceLocator.getServiceLocator().lookup(LoginService.class); LoginContext context = ls.getLoginContext(sub, cbh); context.login(); Subject s = context.getSubject(); return s; } public Subject authenticate(final String username, final char[] password) throws Exception { CallbackHandler cbh = new CustomCallbackHandler(username, password); Subject sub = new Subject(); LoginService ls = JpsServiceLocator.getServiceLocator().lookup(LoginService.class); LoginContext context = ls.getLoginContext(sub, cbh); context.login(); Subject s = context.getSubject(); return s; } public static void main(String[] args) { LoginModuleExample loginModuleExample = new LoginModuleExample(); try { System.out.println("authenticated user subject = " + loginModuleExample.authenticate("testUser", "password".toCharArray())); System.out.println("asserted user subject = " + loginModuleExample.assertUser("testUser")); } catch (Exception e) { e.printStackTrace(); } } }
Applications often must execute actions as run-as operations. OPSS allows you to use the subjects of an asserted user to execute application logic as if it were executed by that user.
The following sections explains how to use the OPSS SubjectSecurity
class to implement run-as operations:
The SubjectSecurity Class
Here are several scenarios where you use this class:
UC1 - A scheduler allows submitting and executing jobs. These jobs are submitted at one time and executed at some future time, therefore the need to assert the user's identity and execute the scheduled job in the user's context.
UC2 - A scheduled job is executed by an entity bean that calls other entity beans to complete the job, and all the code to complete the job must execute in the user's context. Therefore this context must be propagated through the call path, across entity beans.
UC3 - The permissions to execute a scheduled job are based on the user's application roles. In this case, the user's context must be aware of the application roles granted to the user regardless of the code path across entity beans.
UC4 - When an unauthenticated user submits a job, the job metadata must persist the anonymous user. Eventually, the job must be executed by the anonymous user.
UC5 - An MBean running in an application is called from a UI via an MBean server. The MBean operation call a series of diagnostic tests that must be run as a particular user.
UC6 - An identity has been asserted and the assertion has produced a user context that can be used to run operations as that user.
Programming Guidelines and Recommendations
The SubjectSecurity
class allows you to execute code either when a precomputed subject is available, or when the user must first be asserted. If the application context has not been set, then before you use the SubjectSecurity
class, set its ID:
AppSecurityContext.setApplicationID(applicationID)
If you have set the application context, then the call to setApplicationID
is optional.
When programming with the SubjectSecurity
class:
Use SubjectSecurity.getActionExecutor(subject)
if you have already obtained a subject and want to execute some operation with it.
If you obtained the subject with the SubjectUtil.getCurrentSubject
method, then that subject works with the container security and OPSS, and application roles are considered.
If you obtained the subject programmatically using the JpsLoginModuleFactory
class, then that subject works with the container security and OPSS.
Use SubjectSecurity.getActionExecutor(userName)
if just the user name is available and want to execute some operation as that user. To use this method, provide a codesource permission like the following:
<grant> <grantee> <codesource> <url>file:${domain.home}/servers/${weblogic.Name}/myApp.ear/-</url> </codesource> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>IdentityAssertion</name> <actions>execute</actions> </permission> </permissions> </grant>
where url
specifies the location of the code where the method is called.
Note that ActionExecutor.execute(PrivilegedAction)
calls Subject.doAs
with the subject and the application's PrivilegedAction
.
Use SubjectSecurity.executeAs(Subject subject, PrivilegedAction<T> action)
to execute the action immediately.
Use SubjectSecurity.executeAs(Subject subject, PrivilegedExceptionAction<T> action)
to execute the action immediately. This method obtains the action executor using the getActionExecutor
method, and executes the action.
For information about the oracle.security.jps.runtime.SubjectSecurity
class and the oracle.security.jps.runtime.ActionExecutor
interface, see Java API Reference for Oracle Platform Security Services.
Using SubjectSecurity
The following example illustrates how to use the SubjectSecurity
class to run as the asserted jdoe
user:
// get a SubjectSecurity instance final SubjectSecurity subjectSecurity = SubjectSecurity.getInstance(); String username = "jdoe"; // create ActionExecutor with subjectSecurity getActionExecutor(String username) ActionExecutor executor = AccessController.doPrivileged(new PrivilegedExceptionAction<ActionExecutor>() { public ActionExecutor run() throws AssertionException { return subjectSecurity.getActionExecutor(username); } }, null); // When OPSS subjects are available, // create ActionExecutor with SubjectSecurity getActionExecutor(Subject subject) Subject opssSubject = SubjectUtil.getCurrentSubject(); ActionExecutor ececutor = subjectSecurity.getActionExecutor(opssSubject); //run privilegedAction PrivilegedAction action = new MyPrivilegedAction(); executor.execute(action); //run PrivilegedExceptionAction PrivilegedExceptionAction exceptionAction = new MyPrivilegedExceptionAction(); try { executor.execute(exceptionAction); } catch (PrivilegedActionException e) { // handle PrivilegedActionException }
To call a login module in Java SE applications, use the getLoginContex
t method of the oracle.security.jps.service.login.LoginService
interface.
Similar to the LoginContext
method in the standard Java Authorization and Authentication Services (JAAS) API, the getLoginContext
method returns a LoginContext
object instance that you use to authenticate a user, but, more generally, it allows you to use any number of login modules and in any order. Authentication is performed on just those login modules and in the order you passed them.
The following example illustrates user authentication against a subset of login modules with the getLoginContext
method:
import oracle.security.jps.service.ServiceLocator; import oracle.security.jps.service.JpsServiceLocator; import oracle.security.jps.service.login.LoginService; //Obtain the login service ServiceLocator locator = JpsServiceLocator.getServiceLocator(); LoginService loginService = locator.lookup(LoginService.class); //Create the handler for given name and password CallbackHandler cbh = new MyCallbackHandler("name", "password".toCharArray()); //Invoke login modules selectively in a given order selectiveModules = new String[]{"lmName1", "lmName2", "lmName3"}; LoginContext ctx = loginService.getLoginContext(new Subject(), cbh, selectiveModules); ctx.login(); Subject s = ctx.getSubject();
selectiveModules
is an array of login module names, and the authentication uses these login modules in the order listed in the array. Each login module in the array is listed in the default context in the jps-config-jse.xml
file.
The following example illustrates the configuration of a stack of two login modules:
<serviceProvider type="LOGIN" name="jaas.login.provider" class="oracle.security.jps.internal.login.jaas.JaasLoginServiceProvider"> <description>Common definition for any login module instances</description> </serviceProvider> <serviceInstance name="auth.loginmodule" provider="jaas.login.provider"> <description>User Authentication Login Module</description> <property name="loginModuleClassName" value="oracle.security.jps.internal.jaas.module.authentication.JpsUserAuthenticationLoginModule"/> <property name="jaas.login.controlFlag" value="REQUIRED"/> </serviceInstance> <serviceInstance name="custom.loginmodule" provider="jaas.login.provider"> <description>My Custom Login Module</description> <property name="loginModuleClassName" value="my.custom.MyLoginModuleClass"/> <property name="jaas.login.controlFlag" value="REQUIRED"/> </serviceInstance> <jpsContexts default="aJpsContext"> <jpsContext name="aJpsContext"> <serviceInstanceRef ref="auth.loginmodule"/> <serviceInstanceRef ref="custom.loginmodule"/> </jpsContext> </jpsContexts>
Use a file, LDAP, or database-based security store in your Java SE applications and configure all services in the jps-config-jse.xml
file. In this file, you also set system properties appropriate to your applications.
The following sections describe the configuration of policy and credential stores:
See also:
A file policy store is specified in the system-jazn-data.xml
file. A file credential store is specified in the cwallet.sso
file.
The following example illustrates policy and credential configurations:
<serviceProviders> <serviceProvider type="CREDENTIAL_STORE" name="credstoressp" class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider"> <description>SecretStore-based CSF Provider</description> </serviceProvider> <serviceProvider type="POLICY_STORE" name="policystore.xml.provider" class="oracle.security.jps.internal.policystore.xml.XmlPolicyStoreProvider"> <description>XML-based PolicyStore Provider</description> </serviceProvider> </serviceProviders> <serviceInstances> <serviceInstance name="credstore" provider="credstoressp" location="./"> <description>File Credential Store Instance</description> </serviceInstance> <serviceInstance name="policystore.xml" provider="policystore.xml.provider" location="./system-jazn-data.xml"> <description>File Policy Store Service Instance</description> <property name="oracle.security.jps.policy.principal.cache.key" value="false"/> </serviceInstance> </serviceInstances> <jpsContexts default="TestJSE"> <jpsContext name="TestJSE"> <serviceInstanceRef ref="credstore"/> <serviceInstanceRef ref="policystore.xml"/> ... </jpsContext> </jpsContexts>
Note that setting the oracle.security.jps.policy.principal.cache.key
property to false
in the policy store instance is required.
See also:
modifyBootStrapCredential and addBootStrapCredential in WLST Command Reference for Infrastructure Security
The examples in this section assume that the domain uses an LDAP store.
The following example illustrate the configurations of providers, instances, and context for a Java SE application:
<serviceProviders <serviceProvider type="POLICY_STORE" mame="ldap.policystore.provider" class=oracle.security.jps.internal.policystore.ldap.LdapPolicyStoreProvider"/> <serviceProvider type="CREDENTIAL_STORE" mame="ldap.credential.provider" class=oracle.security.jps.internal.credstore.ldap.LdapCredentialStoreProvider"/> </serviceProviders> <serviceInstances> <serviceInstance provider="ldap.policystore.provider" name="policystore.ldap"> <property value="OID" name="policystore.type"/> <property value="bootstrap" name="bootstrap.security.principal.key"/> <property value="cn=PS1domainRC3" name="oracle.security.jps.farm.name"/> <property value="cn=myTestNode" name="oracle.security.jps.ldap.root.name"/> <property value="ldap://myComp.com:1234" name="ldap.url"/> </serviceInstance> <serviceInstance provider="ldap.credential.provider" name="credstore.ldap"> <property value="bootstrap" name="bootstrap.security.principal.key"/> <property value="cn=PS1domainRC3" name="oracle.security.jps.farm.name"/> <property value="cn=myTestNode" name="oracle.security.jps.ldap.root.name"/> <property value="ldap://myComp.com:1234" name="ldap.url"/> </serviceInstance> </serviceInstances>
<serviceInstance location="./bootstrap" provider="credstoressp" name="bootstrap.cred"> <property value="./bootstrap" name="location"/> </serviceInstance>
<jpsContexts default="TestJSE"> <jpsContext name="TestJSE"> <serviceInstanceRef ref="policystore.ldap"/> <serviceInstanceRef ref="credstore.ldap"/> </jpsContext> <jpsContext name="bootstrap_credstore_context"> <serviceInstanceRef ref="bootstrap.cred"/> </jpsContext> </jpsContexts>
The following example illustrates how to obtain programmatically a reference to the security store and assumes that you have set the oracle.security.jps.config
system property to the location of the jps-config-jse.xml
file:
String contextName="TestJSE"; public static PolicyStore getPolicyStore(String contextName) { try-block JpsContextFactory ctxFact; ctxFact = JpsContextFactory.getContextFactory(); JpsContext ctx = ctxFact.getContext(contextName); return ctx.getServiceInstance(PolicyStore.class); catch-block ...
This sections presents configuration examples of database-based policy, credential, and keystores in the jps-config-jse.xml
file. Note the points about the following example:
The value of the jdbc.url
property should be identical to the name of the Java Database Connectivity (JDBC) data source entered when you created the data source.
The values of the bootstrap credentials (map and key) must match those you passed to the addBootStrapCredential
WebLogic Scripting Tool (WLST) command when you created the bootstrap credential.
<jpsConfig …> <propertySets> <propertySet name="props.db.1"> <property value="cn=myDomain" name="oracle.security.jps.farm.name"/> <property value="DB_ORACLE" name="server.type"/> <property value="cn=myRoot" name="oracle.security.jps.ldap.root.name"/> <property name="jdbc.url" value="jdbc:oracle:thin:@myhost.com:1521/srv_name"/> <property name="jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/> <property name="bootstrap.security.principal.key" value="myKeyName" /> <property name="bootstrap.security.principal.map" value="myMapName" /> </propertySet> </propertySets> <serviceProviders> <serviceProvider class="oracle.security.jps.internal.policystore.OPSSPolicyStoreProvider" type="POLICY_STORE" name="policy.rdbms"> <description>DBMS based PolicyStore</description> </serviceProvider> <serviceProvider class="oracle.security.jps.internal.credstore.rdbms.DbmsCredentialStoreProvider" type="CREDENTIAL_STORE" name="db.credentialstore.provider" > <serviceProvider class="oracle.security.jps.internal.keystore.KeyStoreProvider" type="KEY_STORE" name="keystore.provider" > <property name="provider.property.name" value="owsm"/> </serviceProvider> </serviceProviders> <serviceInstances> <serviceInstance name="policystore.rdbms" provider="db.policystore.provider"> <propertySetRef ref = "props.db.1"/> <property name="policystore.type" value="DB_ORACLE"/> </serviceInstance> <serviceInstance name="credstore.rdbms" provider="db.credstore.provider"> <propertySetRef ref = "props.db.1"/> </serviceInstance> <serviceInstance name="keystore.rdbms" provider="db.keystore.provider"> <propertySetRef ref = "props.db.1"/> <property name="keystore.provider.type" value="db"/> </serviceInstance> </serviceInstances> <jpsContexts default="default"> <jpsContext name="default"> <serviceInstanceRef ref="policystore.rdbms"/> <serviceInstanceRef ref="credstore.rdbms"/> <serviceInstanceRef ref="keystore.rdbms"/> </jpsContext> </jpsContexts> </jpsConfig>
The file store does not support methods that involve cascading deletions. It supports only simple queries.
The following example illustrates a simple query that returns of all permissions with a display name matching MyDisplayName
:
PermissionSetSearchQuery query = new PermissionSetSearchQuery(); query.addQuery(PermissionSetSearchQuery.SEARCH_PROPERTY.DISPLAY_NAME, false, ComparatorType.EQUALITY, "MyDisplayName", BaseSearchQuery.MATCHER.EXACT); getPermissionSets(query);
Cascading deletions relates to any method whose signature includes the Boolean cascadeDelete
argument. The only value allowed in case of a file store is false
.
The following sections explain how to use Oracle Platform Security Services Common Audit Framework to audit events in Java SE applications and some common audit usage scenarios:
See also:
In Java SE applications, the audit configuration is specified in the jps-config-jse.xml
file:
<serviceInstance provider="audit.provider" name="audit"> <property value="Medium" name="audit.filterPreset"/> <property value="0" name="audit.maxDirSize"/> <property value="104857600" name="audit.maxFileSize"/> <property value="" name="audit.specialUsers"/> <property value="" name="audit.customEvents"/> <property value="Db" name="audit.loader.repositoryType"/> <property value="file" name="auditstore.type"/> </serviceInstance>
Audit lets your application capture specific runtime events that are recorded in bus-stop files. The audit loader periodically moves data from bus-stop files to the audit store.
The bus-stop file names follow the format host_pid_audit_major_minor.log
, as in sample.myhost.com_12345_audit_1_0.log
. Note that the host name, the process ID, and the version number are embedded in the file name.
Your Java SE application must use a writable directory to which the service writes audit bus-stop files. To specify this location, set the audit.logDirectory
property with the setAuditRepository
WLST command, or set the opss.audit.logDirectory
system property. If the runtime process is unable to determine a writable directory, then audit may not work.
Java SE applications can share the bus-stop directory if you set it with the audit.logDirectory
property and all the Java SE applications in the environment use the same jps-config-jse.xml
file, or the same value is passed as a system property to all Java SE applications.
See also:
setAuditRepository in WLST Command Reference for Infrastructure Security
The audit loader is a process that moves audit data from bus-stop files to a database. The audit.loader.repositoryType
system property must be set in Java EE and SE applications. By default, it is set to database.
Java SE applications can use two kinds of loaders:
The audit loader, a thread started by runtime audit. Ready-to-use, the audit loader is disabled; to enable it, set audit.loader.enable=true
.
The standalone audit loader for Java SE applications, which Oracle recommends, especially if you are using a shared directory.
See also:
The following sections describe common scenarios that implement audit in Java SE applications. We consider environments with and without a collocated WebLogic Server. A collocated environment is a WebLogic Server domain where Java Required Files (JRF) are installed.