16 Integrating Application Security with OPSS

This chapter describes a number of security use cases, including the propagation of identities in domains and across domains, and the typical life cycle of an Oracle Application Development Framework (Oracle ADF) application security.

This chapter includes the following sections:

About Security Challenges

This chapter introduces use cases that solve several typical security challenges. Use these use cases as the departing point to solve your particular application security requirements. The audience includes developers, security architects, and security administrators, and the solutions presented offer both declarative and programmatic approaches.

The top security issues that you face include managing users, user passwords, and controlling access to resources. OPSS provides solutions to these challenges by supporting:

  • External security artifacts separate from the application logic

  • A declarative approach to security

  • A complete user identity life cycle

  • Policy-driven access controls

Figure 16-1 illustrates how applications access the security stores and the tools you use to manage them.

Figure 16-1 Applications, Security Stores, and Management Tools

Description of Figure 16-1 follows
Description of "Figure 16-1 Applications, Security Stores, and Management Tools"

Security Integration Use Cases

The following sections introduce several use cases:

Each use case includes a brief description of the problem it attempts to solve, the security and features involved, and links to details.

Authentication

The following sections describe authentication use cases:

Java EE Application Requiring Authenticated Users

To access a Java EE application, users must be authenticated against the identity store in cases where the identity store is any of the following:

  • A single LDAP store.

  • Several LDAP stores of the same kind.

  • Several LDAP stores of different kinds, such as, for example Microsoft Active Directory and Oracle Internet Directory.

  • A single DB store.

  • Several LDAP and DB stores.

This use case requires:

  • Allowing access to the application to only authenticated users.

  • Not modifying the application code, even when customers have user identities in different repositories.

This use case features:

  • Configuring the appropriate authentication providers according to your particular set of user repositories.

  • Configuring the authentication provider in case of a mixed LDAP or mixed LDAP and DB types.

According to the repository used, the details of this use case are divided into the following scenarios:

  • Single user repository - Configure the appropriate WebLogic Server Authentication Provider.

  • Multiple user repositories - Configure the LDAP providers.

  • DB repositories - Configure the database providers.

For information about authentication providers, see WebLogic Server Authentication Providers.

Java EE Application Requiring Programmatic Authentication

A Java EE application not using deployment descriptors must authenticate the user programmatically against the configured identity store(s).

This use case requires using OPSS APIs to authenticate a user, and it features:

  • Configuring authentication providers for a Java container

  • Using the oracle.security.jps.service.login.LoginService interface to authenticate the user.

For information about authentication, see About Authentication in Java EE Applications.

Java SE Application Requiring Authentication

A Java SE application must authenticate users against the LDAP identity store used in the domain. The application code requesting authentication must be the same regardless of the specifics of the domain's identity store.

This use case requires configuring the identity store(s) against which the authentication should take place and using the oracle.security.jps.service.login.LoginService interface. A Java SE application can use only one identity login module.

For information about using login modules programmatically, see Using the Login Modules in Java SE Applications.

Identities

The following sections describe identity use cases:

Application Running in Two Environments

An application that can run in two different environments requires access to user profile information stored in an LDAP store. The LDAP server may differ with the environment.

More specifically, this use case assumes that:

  • The application uses the UserProfile.getEmail method.

  • In one environment, mail is configured in the Microsoft Active Directory server:

    mail.attr = msad_email
    
  • In the other environment, mail is configured in the Oracle Identity Directory server:

    mail.attr = mail
    

For the application to retrieve the correct information without modifying the code and regardless of the environment (first or second) in which it runs, you must configure the identity store providers with the correct property in each of the environments.

In Microsoft Active Directory, set the identity store provider name property:

<property name="mail.attr" value="msad_mail">

In Oracle Identity Directory, set the identity store provider name property:

<property name="mail.attr" value="mail"

For information about identity store provider configuration, see Configuring the Identity Store Provider.

Application Accessing User Profiles in Multiple Stores

An application requires access to user profile information located in more than one LDAP store servers. In this scenario, you must configure the environment for multiple LDAP stores. For information about the procedure, see Configuring Single and Multiple LDAPs.

Authorization

The following sections describe authorization use cases:

Java EE Application Accessible by Specific Roles

For a Java EE application that allows access only to users that had been assigned specific roles in web descriptors, the group-to-role assignment must be configurable at deployment based on the customer's environment.

For information about declarative security, see the following topics in Developing Applications with the WebLogic Security Service:

Oracle ADF Application Requiring Fine-Grained Authorization

For an Oracle ADF application that requires fine-grained authorization at the level of individual controls on the pages of the application, you must externalize policies and customize them after you application deployment.

See also:

Securing Oracle ADF Applications

Enabling ADF Security in a Fusion Web Application in Developing Fusion Web Applications with Oracle Application Development Framework

Application Securing Web Services

The application requires securing web services with fine-grained authorization. For information about Web services, see Configuring Authorization Using Oracle Web Services Manager in Securing Web Services and Managing Policies with Oracle Web Services Manager.

Java EE Application Requiring Codesource Permissions

A Java EE application requires codesource permissions to perform specific actions. Typical examples are reading a credential from the credential store or looking up policies. For information about permissions, see Configure a Grant.

Non-Oracle ADF Application Requiring Fine-Grained Authorization

A non-Oracle ADF application requires fine-grained authorization checks. In this scenario:

  • Place checks in the application code

  • Configure the appropriate policies

For information about managing and checking policies programmatically, see The JAAS/OPSS Authorization Model.

Credentials

The following section describe a credential use case:

Application Requiring Credentials to Access System

An application requires a credential to connect to a back-end system, such as a database or an LDAP server. The application code should reference this credential in such a way that the specifics of the credential can be changed per customer post deployment without modifying the application code. Furthermore, this use case also requires specifying who can access the credential store and what operations an authorized user can perform on credential data.

This use case features:

  • Using the credential store to persist credentials

  • Fetching credentials at runtime with the Credential Store Framework API in application code

  • Defining and enforcing system policies on codesource

Audit

The following sections describe audit use cases:

Auditing Security-Related Activity

The settings explained in this use case apply to all applications and components in a domain. Applications running in a domain require recording when policies, credentials, or keys are changed, and the policies evaluated in a particular time interval.

This use case features:

  • Integrating applications with Oracle Platform Security Services Common Audit Framework.

  • Defining application audit categories and events in security areas, and making the application audit-aware.

  • Setting the appropriate filter level in each application.

Auditing Business-Related Activity

The settings explained in this use case apply to all applications and components in a domain. Applications must record business-related activity in the context of a functional flow. Specifically, the application requires logging the users and the business actions performed by them in a particular time interval.

To implement this scenario, you create audit events based on business needs, and the application logs the event activity in the audit store. In addition, you generate audit reports from audit events, manage runtime audit policies, and modify audit event definitions, as needed.

This use case features:

  • Allowing applications to define business functional areas (as audit categories), business activities (as audit events in categories), and attributes in each category.

  • Registering applications at deployment, updating audit definitions, and deregistering applications after deployment.

  • Managing audit artifacts with Oracle Enterprise Manager Fusion Middleware Control (Fusion Middleware Control) or WebLogic Scripting Tool (WLST) commands.

Identity Propagation

The following sections describe identity propagation use cases:

Propagating the Executing User Identity

A client application in a container requires propagating the executing user identity to a web service over the Simple Object Access Protocol (SOAP). The web service may be running in the same domain (same or different Managed Server), or in a different domain.

For information about OWSM, see Securing Web Services and Managing Policies with Oracle Web Services Manager.

Propagating a User Identity

A client application in container requires propagating a user identity (distinct from the executing user identity) to a web service over SOAP.

In this use case, the application gets the specific identity to propagate from the credential store and uses OWSM ability to propagate the identity to a remote server.

For information about OWSM, see Securing Web Services and Managing Policies with Oracle Web Services Manager.

Propagating Identities Across Domains

A client application in container requires propagating a user identity (stored in the security store) to a different WebLogic Server domain.

For information about domain trust, see Enabling Trust Between WebLogic Server Domains in Administering Security for Oracle WebLogic Server.

Propagating Identities over HTTP

A client application in container requires propagating identities over HTTP. The recommended implementation is to use the OPSS trust service.

Administration and Management

The following sections describe administration and management use cases:

Application Requiring a Centralized Store

An application requires a central repository of policies, credentials, audit configuration, trusts, and keys, and a set of tools to manage it. To implement this use case, use OPSS services and the tools to manage security services.

Application Requiring a Custom Management Tool

An application requires a custom tool to manage externalized security data. To implement this use case, create a custom graphical user interface that calls OPSS APIs to display and manage security data in a context meaningful to the application.

Application Running in a Multiple Server Environment

An application running in a domain (where several server instances may be distributed across multiple machines) requires propagating security data changes when you initiate changes on the Administration Server and data on Managed Servers is refreshed based on caching policies. Changes must take effect in all components of the application regardless of where they are running. To implement this use case, use the OPSS MBeans or OPSS APIs to modify security data.

Integration

A product requires multiple WebLogic Server domains to run and these domains must share a single central security store. To implement this use case, use the reassociateSecurityStore command to join to a store in some other domain, and the OPSS support for several domains to share a centralized security store.

Joining to a security store is supported only when you create a new domain.

The OPSS Trust Service

The OPSS trust service uses the Identity Asserter to provide and validate tokens and allows applications to propagate identities across HTTP-enabled applications.

See also:

Trust Service Properties

updateTrustServiceConfig in WLST Command Reference for Infrastructure Security

Propagating Identities over HTTP

Note:

Oracle recommends that you implement identity propagation using the OPSS trust service as explained in Propagating Identities with the OPSS Trust Service.

Figure 16-2 illustrates the typical flow of identity propagation using HTTP:

  1. A client application in Domain1 requests a token for an authenticated user from Domain1's OPSS trust instance.
  2. The service accesses Domain1's keystore and generates a token for the client application.
  3. The client application encodes the token in an HTML header and dispatches an HTTP request to a Java servlet in Domain2. Domain 2's asserter intercepts the request and extracts the token.
  4. The asserter requests a validation of that token from Domain2's OPSS trust instance.
  5. The service accesses Domain2's keystore to validate the token and returns a response.
  6. Assuming that the validation is successful, the asserter sends the request to the Java servlet with the asserted identity.
  7. The Java servlet sends an HTTP response to the client application request.

Figure 16-2 Identity Propagation over HTTP

Description of Figure 16-2 follows
Description of "Figure 16-2 Identity Propagation over HTTP "

The ready-to-use configuration sets the key alias based on the server name.

Propagating Identities with the OPSS Trust Service

To propagate identities across multiple domains or across containers in a single domain, Oracle recommends that you use the OPSS trust service as explained in the following sections:

Propagating Identities Across Multiple WebLogic Server Domains

In this use case there are two different WebLogic Server domains: Domain1 and Domain2. The client application is running in Domain1, and the Java servlet is running in Domain2. The client application uses Domain1's service for token generation, and the Java servlet uses Domain2's service for token validation.

The following sections include examples and configurations to implement this use case:

Token Generation on the Client-Side Domain

On the client side (Domain1) where the token is generated:

Develop the Client Application

The client application can be a Java SE or Java EE application. The following example illustrates the client application:

// Authentication type name
public static final String AUTH_TYPE_NAME = "OIT";
// The authenticated username
String user = "weblogic"; 
// URL of the target application
URL url = "http://<host>:<port>/<destinationApp>"; 
//-----------------------------------------
JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext jpsCtx = ctxFactory.getContext();
final TrustService trustService = jpsCtx.getServiceInstance(TrustService.class);
final TokenManager tokenMgr = trustService.getTokenManager();
final TokenContext ctx = tokenMgr.createTokenContext(
    TokenConfiguration.PROTOCOL_EMBEDDED);
UsernameToken ut = WSSTokenUtils.createUsernameToken("wsuid", user);
GenericToken gtok = new GenericToken(ut);
ctx.setSecurityToken(gtok);
ctx.setTokenType(SAML2URI.ns_saml);
Map<String, Object> ctxProperties = ctx.getOtherProperties();
ctxProperties.put(TokenConstants.CONFIRMATION_METHOD,
    SAML2URI.confirmation_method_bearer);
 
AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
        try {
            tokenMgr.issueToken(ctx);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        return null;
    }
});
 
Token token = ctx.getSecurityToken();
String b64Tok = TokenUtil.encodeToken(token);
 
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setRequestProperty("Authorization", AUTH_TYPE_NAME + " " + b64Tok);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
StringBuilder sb = new StringBuilder();
 
String line = null;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
connection.disconnect();	
System.out.println(sb.toString());

Configure the Truststore

The truststore should be provisioned with a client certificate and a private key. The certificate is exported from the keystore and imported into the truststore. Both the keystore and the truststore, are managed by the keystore service (KSS) keystore in the client domain.

Note:

When you set the trust.keystoreType property to KSS, it is recommended not to use passwords for the keystore or the truststore. In this case, by default, the keystore and truststore are protected by codesource permissions and therefore do not require password protection.

The following script illustrates these tasks:

# Update following values with correct value
user = "<username>"
password = "<password>"
wlsurl = "t3(s)://<host>:<port>"
stripeName = "<stripeNmae>"
 
#-----------------------------------------------
ksName = "<trustservice_ks>"
tsName = "<trustservice_ts>"
aliasName = "<trustservice>"
issuerDN = "cn=" + aliasName
 
print "Stripe Name: " + stripeName
 
print "KeyStore Name: " + ksName
print "TrustStore Name: " + tsName
print "Alias Name: " + aliasName
print "Issuer DN: " + issuerDN
 
#-----------------------------------------------
connect(user, password, wlsurl)
 
svc = getOpssService(name='KeyStoreService')
svc.listKeyStores(appStripe=stripeName)

svc.createKeyStore(appStripe=stripeName, name=ksName, password="", permission=true)
svc.generateKeyPair(appStripe=stripeName, name=ksName, password="", dn=issuerDN, keysize="1024", alias=aliasName, keypassword="", algorithm="RSA")
svc.exportKeyStoreCertificate(appStripe=stripeName, name=ksName, password="", alias=aliasName, keypassword="", type="Certificate", filepath="./trustservice.cer")
 
svc.createKeyStore(appStripe=stripeName, name=tsName, password="", permission=true)
svc.importKeyStoreCertificate(appStripe=stripeName, name=tsName, password="", alias=aliasName, keypassword="", type="TrustedCertificate", filepath="./trustservice.cer")
 
svc.listKeyStores(appStripe=stripeName)
svc.listKeyStoreAliases(appStripe=stripeName, name=ksName, password="", type="Certificate")
exit()

Add a TrustServiceAccessPermission Grant

The following grant (in the application jazn-data.xml file) illustrates a codesource permission that allows clients to use trust methods:

<grant>
  <grantee>
    <codesource> 
       <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission> 
       <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
      <name>appId=*</name>
      <actions>issue</actions>
    </permission>
  </permissions>
</grant>

Add this grant to the security store with the grantPermission WLST command, or if the application is a Java EE application and the jazn-data.xml file is packed with the application, then have the grant migrated to the security store at application deployment.

See also:

grantPermission in WLST Command Reference for Infrastructure Security.

Configuring the Filter and the Interceptor

Configure the Provider

The following example illustrates trust provider properties:

<propertySet name="trust.provider.embedded">
	<property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<issuerName>"/>
  <property name="trust.provider.className" value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>
Server-Side or Token Validation Domain

On the server side (Domain2) where the token is validated:

Develop the Server Application

The Java servlet code first obtains the asserted user:

public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   String username = request.getRemoteUser();
   ServletOutputStream out = response.getOutputStream();
   out.print("Asserted username: " + username);
   out.close();
}

Configure web.xml

Set the login configuration method to CLIENT-CERT in the web.xml file:

<web-app id="WebApp_ID"
…
 <login-config>
   <auth-method>CLIENT-CERT</auth-method>
   <realm-name>Identity Assertion </realm-name>
 </login-config>
…
</web-app>

Configure the Asserter

Configure the asserter in one of the following ways:

  • Log in to Oracle WebLogic Server Administration Console and go to Security Realms, then to the Providers tab, then to Authentication, and then choose TrustServiceIdentityAsserter.

    This asserter calls trust methods to decode and validate the token from the incoming request, and passes the user name to WebLogic Server to establish the asserted subject.

  • Use a script like the following:

    connect("<username>","<password>","t3://<host>:<port>")
    edit()
    startEdit()
    realm = cmo.getSecurityConfiguration().getDefaultRealm()
    tsia = realm.lookupAuthenticationProvider("TSIA")
    if tsia != None:
        realm.destroyAuthenticationProvider(tsia)
    tsia = realm.createAuthenticationProvider("TSIA", "oracle.security.jps.wls.providers.trust.TrustServiceIdentityAsserter")
    save()
    activate()
    disconnect()

Provision the Keystore

Export the client certificate you provisioned in the Domain1's keystore and import it into the Domain2's truststore, as illustrated in the following example.

Note:

Import the certificate in the keystore with an alias that matches the client name. In case of multiple domains, the issuerName set during token generation on the client side is used as the alias name to search for the certificate name on the server side.

# Update following values with correct value
user = "<username>"
password = "<password>"
wlsurl = "t3(s)://<host>:<port>"
stripeName = "<stripeName>"
ksName = "<trustservice_ks>"
tsName = "<trustservice_ts>"
aliasName = "<trustservice>"
print "Importing certificate for : " + aliasName
print "Stripe Name: " + stripeName
print "TrustStore Name: " + tsName
print "Alias Name: " + aliasName
connect(user, password, wlsurl)
svc = getOpssService(name='KeyStoreService')
svc.listKeyStores(appStripe=stripeName)

# switch Trust service to using KSS
svc.createKeyStore(appStripe=stripeName, name=tsName, password="", permission=true)
svc.importKeyStoreCertificate(appStripe=stripeName, name=tsName, password="", alias=aliasName, keypassword="", type="TrustedCertificate", filepath="./trustservice.cer")
svc.listKeyStoreAliases(appStripe=stripeName, name=tsName, password="", type="TrustedCertificate")
exit()

Add Permissions

Use the grantPermission WLST command to add codesource grants to the application's jazn-data.xml file.

For example, the following codesource grant is required for the MyApp application to use trust methods:

<grant>
  <grantee
    <codesource> 
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission> 
     <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
      <name>appId=*</name>
      <actions>validate</actions>
    </permission>
  </permissions>
</grant>

See also:

grantPermission in WLST Command Reference for Infrastructure Security

Configure the Provider

The following example illustrates trust provider properties:

<propertySet name="trust.provider.embedded">
	<property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<issuerName>"/>
  <property name="trust.provider.className" value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>

If the provider is used only for token validation, then the aliasName and issuerName attributes are not used for token validation and are therefore optional. In this case to validate a token, the provider looks for the certificate using the name included in the token.

Propagating Identities Across Containers in a Single WebLogic Server Domain

In this use case the client and server applications run in the same domain, both applications can use the same keystore, and therefore it is not necessary to import the client certificate (into some other keystore). All other information remains identical to that explained in the multiple-domain scenario.

Trust Provider Properties

To configure the trust provider, use the following properties:

  • trust.keyStoreType

  • trust.keyStoreName

  • trust.trustStoreName

  • trust.aliasName

  • trust.issuerName

  • trust.provider.className

  • trust.clockSkew

  • trust.token.validityPeriod

  • trust.token.includeCertificate

The following example illustrates a trust provider configuration:

<propertySet name="trust.provider.embedded">
  <property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<aliasName>"/>
  <property name="trust.provider.className"       value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>

To modify the properties of the trust provider, use the updateTrustServiceConfig WLST command. For information about this command, see updateTrustServiceConfig in WLST Command Reference for Infrastructure Security.

Implementing a Custom Graphical User Interface

This section illustrates some of the operations needed when you implement, for example, a custom graphic UI to manage policies. The examples use the OPSS APIs and demonstrate how to:

  • Queue users in the identity store.

  • Queue application roles in the security store.

  • Queue the mapping of users and groups to application roles. Specifically, given a user identify all the application roles mapped to that user (Recall that the mapping of users and groups to application roles is a many-to-many relationship).

  • Create, read, update, and delete the mapping of users and groups to application roles.

This use case assumes that:

  • The identity store is an LDAP store.

  • The security store is an LDAP store.

  • The identity store contains the following hierarchy of users and groups:

    • The Mary, John, Tom, and Helen users.

    • The IT, Training, and Development groups.

    • The Training and Development groups, members of the IT group.

    • The Mary user, member of the Training group.

    • The Tom and John users, members of the Development development.

  • The security store contains the following application policies and hierarchy of application roles:

    • The ApplicationPolicy1 and ApplicationPolicy2 application policies.

    • The System Manager, System Developer, and System Analyst roles, application roles referenced in the policy ApplicationPolicy1. The System Manager role is a member of the System Developer role. The System Developer role is a member of the System Analyst role.

    • The Director, Instructor, and Lecturer roles are application roles referenced in the ApplicationPolicy2 policy. The Director role is a member of the Instructor role. The Instructor role is a member of the Lecturer role.

  • Application roles are mapped to users and groups:

    • The System Manager role is mapped to the Helen user.

    • The System Developer role is mapped to the Development group.

    • The Director role is mapped to the Tom user.

    • The Instructor role is mapped to the Training and Development groups.

Figure 16-3 illustrates this hierarchy of application roles, users and groups, and the mapping of application roles to users and groups.

Figure 16-3 Mapping of Application Roles to Users and Groups

Description of Figure 16-3 follows
Description of "Figure 16-3 Mapping of Application Roles to Users and Groups"

Note that this role hierarchy implies that a user in the System Manager role is also in the System Developer role, and similarly with the other roles. The role membership for each of the four users is next summarized:

  • User Tom is a member of the following application roles: System Developer, System Analyst, Director, Instructor, and Lecturer.

  • User Helen is a member of the following application roles: System Manager, System Developer, and System Analyst.

  • User Mary is a member of the following application roles: Instructor and Lecturer.

  • User John is a member of the following application roles: System Developer, System Analyst, Instructor, and Lecturer.

For the examples details, see the following sections:

Imports Assumed

The examples assume the following import statements:

import java.security.AccessController;
import java.security.Policy;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.security.auth.Subject;
import oracle.security.idm.Identity;
import oracle.security.idm.IdentityStore;
import oracle.security.idm.ObjectNotFoundException;
import oracle.security.idm.Role;
import oracle.security.idm.RoleManager;
import oracle.security.idm.SearchParameters;
import oracle.security.idm.SearchResponse;
import oracle.security.idm.SimpleSearchFilter;
import oracle.security.idm.User;
import oracle.security.idm.UserProfile;
import oracle.security.jps.ContextFactory;
import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.principals.JpsApplicationRole;
import oracle.security.jps.service.idstore.IdentityStoreService;
import oracle.security.jps.service.policystore.ApplicationPolicy;
import oracle.security.jps.service.policystore.PolicyObjectNotFoundException;
import oracle.security.jps.service.policystore.PolicyStore;
import oracle.security.jps.service.policystore.PolicyStoreException;
import oracle.security.jps.service.policystore.entitymanager.AppRoleManager;
import oracle.security.jps.service.policystore.info.AppRoleEntry;
import oracle.security.jps.service.policystore.search.AppRoleSearchQuery;
import oracle.security.jps.service.policystore.search.ComparatorType;
import oracle.security.jps.util.JpsAuth;
import weblogic.security.principal.PrincipalFactory;

Query Identity Store Example

The following example illustrates two queries to users in the identity store:

private void queryUsers() throws Exception {
        // Using IDM U/R to query ID store
        IdentityStore idmStore = idStore.getIdmStore();
 
        // Query an individual user by name
        User employee = idmStore.searchUser(USER_TOM);
        log("----------------------------------------------------------");
        log("### Query individual user (Tom) from ID store ###");
        log(USER_TOM + ": " + employee.getName() + " GUID: " +
            employee.getGUID());
        log();
 
        // Get all users whose name is not "Paul"
        SimpleSearchFilter filter =
            idmStore.getSimpleSearchFilter(UserProfile.NAME,
                                           SimpleSearchFilter.TYPE_NOTEQUAL,
                                           "Paul");
        SearchParameters sps =
            new SearchParameters(filter, SearchParameters.SEARCH_USERS_ONLY);
        SearchResponse result = idmStore.searchUsers(sps);
        log("----------------------------------------------------------");
        log("### Query all users (whose name is not Paul) from ID store ###");
        log("Found the following users:");
        while (result.hasNext()) {
            Identity user = result.next();
            log("\t user: " + user.getName() + ", GUID: " + user.getGUID());
        }
        log();
    }

Create Role Example

The following example illustrates how to create an application role and how to make a role a member of another role:

private void createAppRoles1() throws Exception {
        AppRoleManager arm1 = ap1.getAppRoleManager();
        log("----------------------------------------------------------");
        log("### Creating app roles in app policy1 with hierachy ###");
 
        AppRoleEntry sysAnalystRole =
            arm1.createAppRole(APP_ROLE_SYS_ANALYST, APP_ROLE_SYS_ANALYST,
                               APP_ROLE_SYS_ANALYST);
        AppRoleEntry sysDeveloperRole =
            arm1.createAppRole(APP_ROLE_SYS_DEVELOPER, APP_ROLE_SYS_DEVELOPER,
                               APP_ROLE_SYS_DEVELOPER);
        AppRoleEntry sysManagerRole =
            arm1.createAppRole(APP_ROLE_SYS_MANAGER, APP_ROLE_SYS_MANAGER,
                               APP_ROLE_SYS_MANAGER);
 
        ap1.addPrincipalToAppRole(sysManagerRole, APP_ROLE_SYS_DEVELOPER);
        ap1.addPrincipalToAppRole(sysDeveloperRole, APP_ROLE_SYS_ANALYST);
        log("### App roles in app policy #1 have been created ###");
        log();
    }

Query Roles Example

The following example illustrates several ways to query application roles:

private void queryAppRolesInApplicationPolicy1() throws Exception {
        AppRoleManager arm1 = ap1.getAppRoleManager();
 
        // Get role that matches a name
        AppRoleEntry are = arm1.getAppRole(APP_ROLE_SYS_MANAGER);
        log("----------------------------------------------------------");
        log("### Query app roles in application policy #1, by name ###");
        log("Found " + are.getName() + " by app role name.");
        log();
 
        // Get the role that matches a name exactly
        AppRoleSearchQuery q =
            new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME,
                                   false, ComparatorType.EQUALITY,
                                   APP_ROLE_SYS_ANALYST,
                                   AppRoleSearchQuery.MATCHER.EXACT);
        List<AppRoleEntry> arel = arm1.getAppRoles(q);
        log("### Query app roles in application policy #1, by exact query ###");
        log("Found " + arel.get(0).getName() + " by exact query.");
        log();
 
        // Get roles with names that begin with a given string
        q =
   new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME, false,
                          ComparatorType.EQUALITY,
                          APP_ROLE_SYS_DEVELOPER.subSequence(0, 7),
                          AppRoleSearchQuery.MATCHER.BEGINS_WITH);
        arel = arm1.getAppRoles(q);
        log("### Query app roles in app policy #1, by begins_with query ###");
        log("Found " + arel.get(0).getName() + " by begins_with query.");
        log();
 
        // Get roles with names that contain a given substring
        q =
   new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME, false,
                          ComparatorType.EQUALITY, "dummy",
                          AppRoleSearchQuery.MATCHER.ANY);
        arel = arm1.getAppRoles(q);
        log("### Query app roles in app policy #1, by matcher any ###");
        log("Found " + arel.size() + " app roles by matcher any.");
        for (AppRoleEntry ar : arel) {
            log("\t" + ar.getName());
        }
        log();
    }

Map Roles Example

The following example illustrates how to map application roles to users and groups:

private void assignAppRoleToUsersAndGroups() throws Exception {
        // Obtain the user/group principals
        IdentityStore idmStore = idStore.getIdmStore();
        User tom = idmStore.searchUser(USER_TOM);
        User helen = idmStore.searchUser(USER_HELEN);
 
        Role trainingRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_TRAINING);
        Role devRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_DEV);
 
        Principal tomPrincipal =
            PrincipalFactory.getInstance().createWLSUser(tom.getName(),
                                                         tom.getGUID(),
                                                         tom.getUniqueName());
        Principal helenPrincipal =
            PrincipalFactory.getInstance().createWLSUser(helen.getName(),
                                                         helen.getGUID(),
                                                         helen.getUniqueName());
        Principal trainingPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(trainingRole.getName(),
                                                          trainingRole.getGUID(),
                                                   trainingRole.getUniqueName());
        Principal devPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(devRole.getName(),
                                                          devRole.getGUID(),
                                                   devRole.getUniqueName());
 
        // Application policy #1
        log("----------------------------------------------------------");
        log("### Assigning appl roles to users and groups, app policy #1 ###");
        ap1.addPrincipalToAppRole(helenPrincipal, APP_ROLE_SYS_MANAGER);
        ap1.addPrincipalToAppRole(devPrincipal, APP_ROLE_SYS_DEVELOPER);
 
        // Application policy #2
        log("### Assigning app roles to users and groups, app policy #2 ###");
        ap2.addPrincipalToAppRole(tomPrincipal, APP_ROLE_DIRECTOR);
        ap2.addPrincipalToAppRole(devPrincipal, APP_ROLE_INSTRUCTOR);
        ap2.addPrincipalToAppRole(trainingPrincipal, APP_ROLE_INSTRUCTOR);
 
        log("### App roles have been assigned to users and groups ###");
        log();
    }

Get Roles that Contain a User Example

The following example illustrates how to get all the roles that contain a specified user:

private void showAppRoles() throws Exception {
        Subject tomSubject = getUserSubject(USER_TOM);
        Subject helenSubject = getUserSubject(USER_HELEN);
        Subject johnSubject = getUserSubject(USER_JOHN);
        Subject marySubject = getUserSubject(USER_MARY);
 
        Set<String> applications = new HashSet<String>();
        applications.add(APPLICATION_NAME1);
        applications.add(APPLICATION_NAME2);
        log("----------------------------------------------------------");
        log("### Query application roles for Tom ###");
        showAppRoles(applications, USER_TOM, tomSubject);
        log();
        log("### Query application roles for Helen ###");
        showAppRoles(applications, USER_HELEN, helenSubject);
        log();
        log("### Query application roles for John ###");
        showAppRoles(applications, USER_JOHN, johnSubject);
        log();
        log("### Query application roles for Mary ###");
        showAppRoles(applications, USER_MARY, marySubject);
        log();
    }
private Subject getUserSubject(String userName) throws Exception {
        Subject subject = new Subject();
 
        // Query users from ID store using user/role API,for user principal
        IdentityStore idmStore = idStore.getIdmStore();
        User user = idmStore.searchUser(userName);
        Principal userPrincipal =
            PrincipalFactory.getInstance().createWLSUser(user.getName(),
                                                         user.getGUID(),
                                                         user.getUniqueName());
        subject.getPrincipals().add(userPrincipal);
 
        // Query users from ID store using user/role API, for enterprise roles
        RoleManager rm = idmStore.getRoleManager();
        SearchResponse result = null;
        try {
            result = rm.getGrantedRoles(user.getPrincipal(), false);
        } catch (ObjectNotFoundException onfe) {
            // ignore
        }
 
        // Add group principals to the subject
        while (result != null && result.hasNext()) {
            Identity role = result.next();
            Principal groupPrincipal =
                PrincipalFactory.getInstance().createWLSGroup(role.getName(),
                                                              role.getGUID(),
                                                        role.getUniqueName());
            subject.getPrincipals().add(groupPrincipal);
        }
 
        // The subject now contains both user and group principals.
        return subject;
    }

private void showAppRoles(Set<String> applications, String user, Subject subject) {
        // Get all granted application roles for this subject
        Set<JpsApplicationRole> result = null;
        try {
            result = JpsAuth.getAllGrantedAppRoles(subject, applications);
        } catch (PolicyStoreException pse) {
            log(pse.toString());
        }
        if (result.size() <= 1) {
            log(user + " has " + result.size() + " application role.");
            if (result.size() == 1) {
                for (JpsApplicationRole ar : result) {
                    log("\tApplication role: " + ar.getName());
                }
            }
        } else {
            System.out.println(user + " has " + result.size() +
                               " application roles.");
            for (JpsApplicationRole ar : result) {
                log("\tApplication role: " + ar.getAppID() + "/" +
                    ar.getName());
            }
        }
    }

Delete Role Mapping Example

The following example illustrates how to remove the mapping of an application role to a group:

private void removeAppRoleForUserDirector() throws Exception {
        // Remove instructor role from Dev group
        log("----------------------------------------------------------");
        log("### Removing Instructor application role from Dev group ###");
 
        IdentityStore idmStore = idStore.getIdmStore();
        Role devRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_DEV);
        Principal devPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(devRole.getName(),
                                                          devRole.getGUID(),
                                                          devRole.getUniqueName());
        ap2.removePrincipalFromAppRole(devPrincipal, APP_ROLE_INSTRUCTOR);
        log("### Instructor app role has been removed from Dev group ###");
        log();
 
        log("----------------------------------------------------------");
        log("### Now query application roles for user John, again ###");
        Set<String> applications = new HashSet<String>();
        applications.add(APPLICATION_NAME1);
        applications.add(APPLICATION_NAME2);
        Subject johnSubject = getUserSubject(USER_JOHN);
        showAppRoles(applications, USER_JOHN, johnSubject);
        log();
    }

Securing Oracle ADF Applications

The following sections explain the typical tasks performed in Oracle ADF applications developed with Oracle JDeveloper:

The participants are the application product manager, developers, and security administrators.

Development Phase

In the development phase developers design the application to work with the full range of security options available in Oracle Fusion Middleware. Developers have access to a rich set of security services exposed by JDeveloper, the built-in Oracle ADF framework, and Oracle WebLogic Server, all of which ensure a consistent approach to security throughout the application's life span.

You use ADF Security Wizard (an authorization editor) and the expression language editor, all within JDeveloper. Additionally and optionally, you may use OPSS APIs to implement more complex security tasks. Thus, some parts of the application use declarative security, others use programmatic security, and they both rely on security features available in the development and runtime environment.

You also define a number of application entitlements and roles required to secure the application, and this data is kept in a source control system together with the application source code.

Deployment Phase

After you have developed the application, you test it in a staging environment before deploying it to a production environment. In a production environment, the application and runtime services are integrated with other security components, such as single sign-on, user provisioning, and audit.

The type of security services usually change with the phase: for example, during development you keep credentials in a file or Oracle wallet, but in a production environment you store them in an LDAP server.

In the deployment phase, you migrate the policies to the production security store, and map application roles to enterprise groups according to application policies.

Administration Phase

The administration phase starts after you have deployed the application to a production environment. In this phase, you manage day-to-day security tasks, such as granting users access to application resources, reviewing audit logs, responding to security incidents, and applying security patches.

Summary of Tasks per Participant per Phase

The following tables summarize the major responsibilities per participant in each of the security life cycle phases and Figure 16-4 illustrates the basic flow.

Figure 16-4 Application Life Cycle Phases

Description of Figure 16-4 follows
Description of "Figure 16-4 Application Life Cycle Phases"

Table 16-1 Security Tasks for the Application Architect

Phase Task

Development

Define high-level application roles based on functional security and data security requirements. Populate the initial security store.

Deployment

Define real-world customer scenarios for the QA (quality assurance) team to test.

Administration

Understand and identify the requirements to customize application policies. Consider defining templates for vertical industries.

Table 16-2 Security Tasks for the Application Developer

Phase Task

Development

Use tools and processes, specifically JDeveloper, to build the application and to create security data, such as application roles and permissions.

Use grants to specify data-level security.

Test the application using a local security store with users and roles.

Deployment

Assist the QA team to troubleshoot and resolve runtime issues.

Table 16-3 Security Tasks for the Application Security Administrator

Phase Task

Deployment

Use deployment services to migrate data in jazn-data.xml to the production security store.

Map application roles to enterprise groups so that security policies can be enforced.

Administration

Apply patches and upgrades software, as necessary.

Manage users and roles, as enterprise users and the application role hierarchy changes overtime.

Manage policies packed with the application and creates new ones.

Integrate with and manage the identity infrastructure.

Propagating Identities with JKS

The ready-to-use configuration sets the token name and the key alias based on the server name. To change these default values, use the procedures explained in Update Trust Parameters.

The following sections explain the propagation of identities over HTTP using Java Keystore (JKS):

Single Domain Scenario

In this scenario, the both client and Java servlet use the same service to generate and validate tokens. The following sections explain the tasks necessary to implement identity propagation when the client and Java servlet run in the same domain:

Create the Client Application

The following example illustrates a client application. Note that the jps-api.jar file and the osdt_ws_sx.jar, osdt_core.jar, osdt_xmlsec.jar, and osdt_saml2.jar files must be included in the class path.

// Authentication type name
public static final String AUTH_TYPE_NAME = "OIT";
// The authenticated username
String user = "weblogic"; 
// URL of the target application
URL url = "http://<host>:<port>/<destinationApp>"; 
//-----------------------------------------
JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext jpsCtx = ctxFactory.getContext();
final TrustService trustService = jpsCtx.getServiceInstance(TrustService.class);
final TokenManager tokenMgr = trustService.getTokenManager();
final TokenContext ctx = tokenMgr.createTokenContext(
    TokenConfiguration.PROTOCOL_EMBEDDED);
UsernameToken ut = WSSTokenUtils.createUsernameToken("wsuid", user);
GenericToken gtok = new GenericToken(ut);
ctx.setSecurityToken(gtok);
ctx.setTokenType(SAML2URI.ns_saml);
Map<String, Object> ctxProperties = ctx.getOtherProperties();
ctxProperties.put(TokenConstants.CONFIRMATION_METHOD,
    SAML2URI.confirmation_method_bearer);
 
AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
        try {
            tokenMgr.issueToken(ctx);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        return null;
    }
});
 
Token token = ctx.getSecurityToken();
String b64Tok = TokenUtil.encodeToken(token);
 
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setRequestProperty("Authorization", AUTH_TYPE_NAME + " " + b64Tok);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
StringBuilder sb = new StringBuilder();
 
String line = null;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
connection.disconnect();
System.out.println(sb.toString());
Configure the Keystore

Assuming that the server name is jrfServer_admin, the following command illustrates the creation of the keystore, represented by the generated default-keystore.jks file:

JAVA_HOME/bin/keytool -genkeypair 
  -alias orakey 
  -keypass welcome 
  -keyalg RSA 
  -dname "CN=jrfServer_admin,O=Oracle,C=US" 
  -keystore default-keystore.jks 
  -storepass password
 
# the generated file must be placed on the domain configuration location
cp default-keystore.jks ${domain.home}/config/fmwconfig

Make sure that the keystore service configured in the jps-config.xml file points to the generated default-keystore.jks:

<!-- KeyStore Service Instance -->
<serviceInstance name="keystore" 
    provider="keystore.provider"  location="./default-keystore.jks">
    <description>Default JPS Keystore Service</description>
    <property name="keystore.provider.type" value="file"/>
    <property name="keystore.file.path" value="./"/>
    <property name="keystore.type" value="JKS"/>
    <property name="keystore.csf.map" value="oracle.wsm.security"/>
    <property name="keystore.pass.csf.key" value="keystore-csf-key"/>
    <property name="keystore.sig.csf.key" value="sign-csf-key"/>
    <property name="keystore.enc.csf.key" value="enc-csf-key"/>
</serviceInstance >
Configure Maps and Keys

Create a map/key pair used to open the keystore and another map/key pair used to generate tokens. The following commands illustrate these operations with the createCred WLST command:

// JKS keystore opening password
createCred(map="oracle.wsm.security", key="keystore-csf-key", 
           user="keystore", password="password") 
 
// Private key password to issue tokens
createCred(map="oracle.wsm.security", key="sign-csf-key", 
           user="orakey", password="password")

For information about createCred, see Managing Credentials with WLST.

Configure a Grant

Add a system policy with a codesource grant, which allows the client application to use trust methods:

<grant>
  <grantee>
    <codesource>    
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission>          
<class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
        <name>appId=*</name>
        <actions>issue</actions>
     </permission>
    </permissions>
</grant>

You must stop and restart WebLogic Server for the grant to take effect.

Create the Java Servlet

The following example illustrates how a Java servlet obtains an asserted user name:

public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   String username = request.getRemoteUser();
   ServletOutputStream out = response.getOutputStream();
   out.print("Asserted username: " + username);
   out.close();
}
Configure web.xml

Set the appropriate login method in the web.xml file:

<web-app id="WebApp_ID"
…
 <login-config>
   <auth-method>CLIENT-CERT</auth-method>
   <realm-name>Identity Assertion</realm-name>
 </login-config>
…
</web-app>
Configure the Asserter

To configure the asserter:

  1. Copy the jps-wls-trustprovider.jar identity asserter file to the location ${domain.home}/lib/mbeantypes:

    cp ${common.components.home}/modules/oracle.jps_12.2.1/jps-wls-trustprovider.jar ${domain.home}/lib/mbeantypes
    
  2. Restart WebLogic Server.

  3. Use WebLogic Server Administration Console to configure the asserter:

    1. Log in as an administrator and go to Security Settings, then to Security Realms, then to Providers, then to the Authentication tab, and then click New. The Create a New Authentication Provider dialog is displayed.

    2. In this dialog, enter TrustServiceIdentityAsserter in the name text field, and choose TrustServiceIdentityAsserter from the pull-down list. Then click OK.

  4. Verify that a grant like the following is present in the security store. This grant is required so that the asserter can use OPSS trust methods:

    <grant>
        <grantee>
            <codesource>
                <url>file:${domain.home}/lib/mbeantypes/jps-wls-trustprovider.jar</url>
            </codesource>
        </grantee>
        <permissions>
            <permission>
                <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
                <name>appId=*</name>
                <actions>validate</actions>
            </permission>
        </permissions>
    </grant>
    

    Changes to the jps-config.xml file require that you restart the server.

Update Trust Parameters

This section explains how to modify the trust parameters in the jps-config.xml file by executing a script.

By default, the trust.aliasName and trust.issuerName parameters are set to the server name. To modify these values, adapt and use the following script:

import sys
 
wlsAdmin = 'weblogic'
wlsPwd ='password_value'
wlUrl='t3://localhost:7001'
issuer= 'issuer'
alias = 'alias'
 
print "OPSS Trust Service provider configuration management script.\n"
 
instance = 'trust.provider'
name = 'trust.provider.embedded'
cfgProps = HashMap()
cfgProps.put("trust.issuerName", issuer)
cfgProps.put("trust.aliasName", alias)
pm = PortableMap(cfgProps);
 
connect(wlsAdmin, wlsPwd, wlUrl)
domainRuntime()
 
params = [instance, name, pm.toCompositeData(None)]
sign = ["java.lang.String", "java.lang.String", "javax.management.openmbean.CompositeData"]
on = ObjectName("com.oracle.jps:type=JpsConfig")
mbs.invoke(on, "updateTrustServiceConfig", params, sign)
mbs.invoke(on, "persist", None, None)
 
print "Done.\n"

Multiple Domain Scenario

In this scenario there are two different domains: Domain1 and Domain2. The client application is running in Domain1, and the Java servlet is running in Domain2. It is assumed that these two domains have each a trust service properly configured as explained in the Single Domain Scenario. The client uses Domain1's trust service for token generation, and the Java servlet uses Domain2's trust service for token validation.

In Domain1, the client code and the following configurations are identical to those described in the Single Domain Scenario:

In Domain 2, the Java servlet code and web.xml configuration are identical to those described in the Single Domain Scenario:

  • The Java servlet code as illustrated in Create the Java Servlet.

  • The configuration of the web.xml file as illustrated in Configure web.xml.

  • The client certificate used to sign the token in Domain1 must be present in Domain2's keystore. To comply:

    1. Export the certificate from Domain 1's keystore:

      JAVA_HOME/bin/keytool -export
      -orakey orakey.cer
      -keystore default-keystore.jks
      -storepass password
      
    2. Import the certificate into Domain 2's keystore. Note that the alias used to import the certificate must match the name of the on the client side:

      JAVA_HOME/bin/keytool -importcert 
        -alias orakey 
        -keypass welcome 
        -keyalg RSA 
        -keystore default-keystore.jks 
        -storepass password
      
    3. Set the Domain2's keystore password in the (Domain2's) credential store with the createCred WLST command:

      createCred(map="oracle.wsm.security", key="keystore-csf-key", user="keystore", password="password")
      

    See createCred in WLST Command Reference for Infrastructure Security.

Domains Using Both Protocols

In this scenario, applications use either HTTP or SOAP, and not all applications in the domain use the same protocol. In such scenario, the keystore can be shared by HTTP and SOAP services.

The following sections explain the special configurations required in this case:

Single Domain Scenario

In this scenario, there is one keystore. The following example illustrates the configuration required for a certificate with orakey alias:

<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
     value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
    
    <!-- The alias used to get the signing certificate from JKS -->
    <property name="trust.aliasName" value="orakey"/> 
 
    <!-- The issuer name to add in the token used by the target
    trust service instance as an alias to pick up the corresponding certificate 
    to validate the token signature -->
    <property name="trust.issuerName" value="orakey"/>
</propertySet>
Multiple Domain Scenario

In this scenario, there are two domains and two keystores. The following example illustrates the configuration required in the domain that is issuing tokens for a certificate with orakey alias:

<!-- issuer domain truststore must have a signing certif. w. alias orakey -->
<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
        value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
 
    <!-- the signing certificate alias in local JKS -->
    <property name="trust.aliasName" value="orakey"/> 
    
    <!-- the token issuer's name -->
    <property name="trust.issuerName" value="domain1"/> 
</propertySet>

On the client side, the value of trust.issuerName can be same as trust.aliasName. However the name value can be overridden by setting a different value for trust.issuerName (as shown in the example). This name will be set in the token generated on the client side.

On the server side, if the server is used only for token validation, then it is not mandatory to set trust.aliasName and trust.issuerName. The name set during the token generation is used while looking for a certificate on the server side. Hence the certificate imported from the client should be exported on the server side with the client side name as the alias (domain1 in the example).

The following example illustrates the configuration required in the domain that is receiving tokens for a certificate with orakey alias:

<!- the recipient domain must have a token validation certificate 
for domain1, which is the one was used to sign the token with alias "domain1" -->
<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
        value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
    
    <!-- the signing certificate alias in local JKS -->
    <property name="trust.aliasName" value="orakey"/> 
 
    <!-- the token issuer's name -->
    <property name="trust.issuerName" value="domain2"/> 
</propertySet>