Secure Oracle E-Business Suite with Oracle IAM Asserter: A Complete Technical Guide

Oracle Identity & Access Management

Oracle IAM Asserter Integration with Oracle E-Business Suite — Complete Implementation Guide

📅 June 22, 2026🏷️ OIM · OAM · EBS · SSO · Asserter⏱ ~35 min read💡 Expert Level


📌 What This Guide CoversThis article is a complete, production-grade walkthrough of integrating Oracle Identity and Access Management (OIM/OAM) with Oracle E-Business Suite R12.2 using the EBS Asserter.             
You will configure OAM as the Identity Provider, deploy the EBS Asserter plugin, implement token-based SSO, set up user provisioning via OIM, and write the supporting PL/SQL and Java code required at every layer.

1. What Is the Oracle EBS Asserter?

The Oracle EBS Asserter (also called the Oracle E-Business Suite Asserter) is a J2EE web application that acts as a bridge between a modern identity provider — specifically Oracle Access Manager (OAM) — and Oracle EBS. It converts an OAM-issued token (OAM_ID cookie or OAuth 2.0 bearer token) into a valid ICX_SESSION inside EBS, giving the end user a seamless Single Sign-On experience without re-entering credentials.



The Asserter replaces the older mod_osso / Oracle SSO (OSSO) approach and is the recommended path for all EBS R12.2 deployments running OAM 12c PS3+. It supports:

  • SSO into EBS via OAM (SAML, OAuth 2.0, OpenID Connect)
  • Automatic EBS session creation tied to OAM authenticated identity
  • EBS responsibility and menu-level authorization
  • Deep link / bookmark support through the EBS Login URL
  • Logout propagation back to OAM (Single Logout — SLO)
⚠️ Version RequirementsMinimum: Oracle EBS R12.2.6 + OAM 12c (12.2.1.3+) + WebLogic Server 12.2.1.3+ + JDK 8u181+. Recommended: EBS R12.2.12, OAM 12.2.1.4, WLS 12.2.1.4, JDK 11. Apply MOS patch25764498(EBS Asserter) and review Doc ID2462012.1(Asserter Setup Guide).

2. Architecture Overview

The following diagram shows the complete authentication flow when a user accesses EBS through OAM using the EBS Asserter.



Authentication Flow Explanation

The numbered steps in the diagram correspond to:

  1.  User accesses EBS URL — request hits Oracle HTTP Server (OHS) with WebGate
  2.  WebGate intercepts the unauthenticated request and redirects to OAM login page
  3.  OAM authenticates the user (LDAP, Kerberos, or MFA) and issues OAM_ID cookie
  4.  OHS forwards the request with the token to the EBS Asserter application
  5.  Asserter calls back to OAM to validate the token and extract identity attributes
  6.  Asserter queries OID/LDAP to map the OAM identity to an EBS username
  7.  Asserter calls EBS APIs to create an ICX session and redirects the user into EBS
  8.  EBS reads/writes user session data from Oracle Database (FND_USER, ICX_SESSIONS)
  9.  Oracle Identity Manager (OIM) handles user provisioning to EBS in the background

3. Prerequisites & Component Versions

ComponentMin VersionRecommendedNotes
Oracle EBSR12.2.6R12.2.12AD/TXK delta patches applied
Oracle OAM12.2.1.312.2.1.4 BP05Oracle Access Manager 12c
Oracle OIM12.2.1.312.2.1.4Oracle Identity Manager 12c
OID / ODSEE11.1.1.912.2.1.4Or Active Directory via AD-OID sync
WebLogic Server12.2.1.312.2.1.4For Asserter deployment
Oracle HTTP Server12.1.312.2.1.4Hosts WebGate for OAM
WebGate12.2.1.312.2.1.4Must match OAM version
JDKJDK 8u181JDK 11.0.xWLS and Asserter runtime
EBS Asserter Patch25764498Latest via MOSMOS Doc ID 2462012.1
📋 Mandatory EBS Patches Before IntegrationApply25764498(EBS Asserter),14060571(EBS Integrated SSO Framework),17774755(ICX Cookie updates),19245498(REST framework for token exchange). Validate via: SELECT patch_name, patch_type, last_update_date FROM ad_applied_patches WHERE patch_name IN ('25764498','14060571');

4. Step 1 — Configure Oracle Internet Directory (OID) for EBS

OID acts as the LDAP directory that stores EBS user identities. OAM authenticates against OID, and the Asserter looks up the EBS username from the OID orclEBSUser attribute.

4.1 EBS–OID User Reconciliation Schema

🗄️ LDIF — OID Schema Extension for EBS Attributes
# ebs_oid_extension.ldif
# Extend OID schema to store EBS-specific attributes

dn: cn=subschemasubentry
changetype: modify
add: attributetypes
attributetypes: ( 2.16.840.1.113894.7.100.10
  NAME 'orclEBSUserName'
  DESC 'Oracle EBS FND_USER username'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )

attributetypes: ( 2.16.840.1.113894.7.100.11
  NAME 'orclEBSPersonID'
  DESC 'EBS HR Person ID (PER_ALL_PEOPLE_F.PERSON_ID)'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

# Example user entry with EBS attributes
dn: cn=JDOE,cn=Users,dc=example,dc=com
changetype: modify
add: orclEBSUserName
orclEBSUserName: JDOE
-
add: orclEBSPersonID
orclEBSPersonID: 10048
-
add: mail
mail: jdoe@example.com
💻 Shell — Apply LDIF to OID
# Apply schema extension to OID
ldapmodify \
  -h oid-server.example.com \
  -p 389 \
  -D "cn=orcladmin" \
  -w "OID_Admin_Password" \
  -f ebs_oid_extension.ldif

# Verify extension applied
ldapsearch \
  -h oid-server.example.com -p 389 \
  -D "cn=orcladmin" -w "OID_Admin_Password" \
  -b "cn=Users,dc=example,dc=com" \
  -s sub "(orclEBSUserName=JDOE)" \
  orclEBSUserName orclEBSPersonID mail

# Bulk-load existing EBS users into OID using EBS-OID Provisioning Tool
java -jar ebsOIDSync.jar \
  --ebs-jdbc "jdbc:oracle:thin:@ebsdb:1521/EBSPROD" \
  --ebs-user APPS \
  --ebs-pass "APPS_PASSWORD" \
  --oid-host oid-server.example.com \
  --oid-port 389 \
  --oid-dn  "cn=orcladmin" \
  --oid-pass "OID_Admin_Password" \
  --base-dn "cn=Users,dc=example,dc=com" \
  --mode FULL_SYNC

4.2 EBS-OID Reconciliation PL/SQL Package

🗄️ PL/SQL — EBS-OID Sync Package
CREATE OR REPLACE PACKAGE APPS.xx_iam_oid_sync_pkg AS

  -- Sync a single EBS user to OID via DBMS_LDAP
  PROCEDURE sync_user_to_oid(
    p_user_name  IN VARCHAR2,
    p_action     IN VARCHAR2 DEFAULT 'UPSERT'  -- UPSERT | DELETE
  );

  -- Full reconciliation of all active EBS users to OID
  PROCEDURE full_reconcile(
    p_log_id  OUT NUMBER
  );

  -- Get OID DN for a given EBS username
  FUNCTION get_oid_dn(
    p_ebs_user  IN VARCHAR2
  ) RETURN VARCHAR2;

END xx_iam_oid_sync_pkg;
/

CREATE OR REPLACE PACKAGE BODY APPS.xx_iam_oid_sync_pkg AS

  -- OID connection constants
  gc_oid_host    CONSTANT VARCHAR2(100) := 'oid-server.example.com';
  gc_oid_port    CONSTANT PLS_INTEGER  := 389;
  gc_bind_dn     CONSTANT VARCHAR2(200) := 'cn=orcladmin';
  gc_bind_pwd    CONSTANT VARCHAR2(100) := 'OID_Admin_Password';
  gc_base_dn     CONSTANT VARCHAR2(200) := 'cn=Users,dc=example,dc=com';

  FUNCTION get_oid_dn(p_ebs_user IN VARCHAR2) RETURN VARCHAR2 IS
  BEGIN
    RETURN 'cn=' || UPPER(p_ebs_user) || ',' || gc_base_dn;
  END;

  PROCEDURE sync_user_to_oid(
    p_user_name IN VARCHAR2,
    p_action    IN VARCHAR2 DEFAULT 'UPSERT'
  ) IS
    l_session   DBMS_LDAP.session;
    l_message   DBMS_LDAP.message;
    l_retval    PLS_INTEGER;
    l_dn        VARCHAR2(500);
    l_attrs     DBMS_LDAP.mod_array;
    l_fnd_rec   FND_USER%ROWTYPE;
    l_email     VARCHAR2(240);
    l_person_id NUMBER;
  BEGIN
    -- Fetch EBS user data
    SELECT * INTO l_fnd_rec
    FROM   FND_USER
    WHERE  USER_NAME = UPPER(p_user_name);

    l_dn := get_oid_dn(p_user_name);

    -- Connect to OID via DBMS_LDAP
    DBMS_LDAP.use_exception := TRUE;
    l_session := DBMS_LDAP.init(gc_oid_host, gc_oid_port);
    l_retval  := DBMS_LDAP.simple_bind_s(l_session, gc_bind_dn, gc_bind_pwd);

    IF p_action = 'DELETE' THEN
      l_retval := DBMS_LDAP.delete_s(l_session, l_dn);

    ELSE  -- UPSERT
      -- Get employee email and person_id from HR
      BEGIN
        SELECT email_address, employee_id
        INTO   l_email, l_person_id
        FROM   FND_USER
        WHERE  USER_NAME = UPPER(p_user_name);
      EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END;

      -- Build LDAP attribute modification array
      l_attrs := DBMS_LDAP.create_mod_array(5);

      DBMS_LDAP.populate_mod_array(
        l_attrs, DBMS_LDAP.MOD_REPLACE, 'orclEBSUserName',
        DBMS_LDAP.string_collection(p_user_name));

      DBMS_LDAP.populate_mod_array(
        l_attrs, DBMS_LDAP.MOD_REPLACE, 'mail',
        DBMS_LDAP.string_collection(NVL(l_email, p_user_name || '@example.com')));

      IF l_person_id IS NOT NULL THEN
        DBMS_LDAP.populate_mod_array(
          l_attrs, DBMS_LDAP.MOD_REPLACE, 'orclEBSPersonID',
          DBMS_LDAP.string_collection(TO_CHAR(l_person_id)));
      END IF;

      DBMS_LDAP.populate_mod_array(
        l_attrs, DBMS_LDAP.MOD_REPLACE, 'cn',
        DBMS_LDAP.string_collection(UPPER(p_user_name)));

      DBMS_LDAP.populate_mod_array(
        l_attrs, DBMS_LDAP.MOD_REPLACE, 'objectClass',
        DBMS_LDAP.string_collection('top', 'person', 'inetOrgPerson', 'orclUser'));

      -- Try modify first, then add if entry doesn't exist
      BEGIN
        l_retval := DBMS_LDAP.modify_s(l_session, l_dn, l_attrs);
      EXCEPTION
        WHEN OTHERS THEN
          l_retval := DBMS_LDAP.add_s(l_session, l_dn, l_attrs);
      END;

      DBMS_LDAP.free_mod_array(l_attrs);
    END IF;

    -- Unbind LDAP session
    l_retval := DBMS_LDAP.unbind_s(l_session);

  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        l_retval := DBMS_LDAP.unbind_s(l_session);
      EXCEPTION WHEN OTHERS THEN NULL; END;
      RAISE_APPLICATION_ERROR(-20001,
        'OID Sync failed for [' || p_user_name || '] - ' || SQLERRM);
  END sync_user_to_oid;

  PROCEDURE full_reconcile(p_log_id OUT NUMBER) IS
    l_success NUMBER := 0;
    l_error   NUMBER := 0;
  BEGIN
    FOR r IN (
      SELECT user_name
      FROM   fnd_user
      WHERE  NVL(end_date, SYSDATE + 1) > SYSDATE
    ) LOOP
      BEGIN
        sync_user_to_oid(r.user_name, 'UPSERT');
        l_success := l_success + 1;
      EXCEPTION WHEN OTHERS THEN
        l_error := l_error + 1;
      END;
    END LOOP;

    -- Return log summary
    p_log_id := l_success * 1000 + l_error; -- encode in return
    COMMIT;
  END full_reconcile;

END xx_iam_oid_sync_pkg;
/

5. Step 2 — Install & Configure OAM WebGate on OHS

WebGate is an OHS plugin that intercepts every HTTP request and enforces OAM authentication policies. It replaces the older mod_osso module.

1
Install WebGate on OHS ServerCopy the WebGate installer to the OHS server and run the installer as the Oracle OS user.
2
Register WebGate with OAMUse the OAM Admin Console to create a new WebGate registration and generate configuration artifacts.
3
Configure WebGate for EBS URLsDefine protection policies for the EBS URL space, excluding public resources like images and logon pages.
💻 Shell — Install OAM WebGate 12c on OHS
# Set environment
export ORACLE_HOME=/u01/oracle/ohs12c
export WG_INSTALL=/u01/oracle/webgate_install

# Run WebGate installer in silent mode
java -jar $WG_INSTALL/webgate_12.2.1.4.0_linux64.jar \
  -silent \
  -responseFile $WG_INSTALL/webgate_response.rsp

# webgate_response.rsp content:
# [ENGINE]
# Response File Version=1.0.0.0.0
# [VARIABLES]
# ORACLE_HOME=/u01/oracle/ohs12c
# COMPONENT_PATHS=WebGate
# OHS_ORACLE_HOME=/u01/oracle/ohs12c
# OHS_INSTANCE=/u01/oracle/ohs12c/instances/ohs1

# Register WebGate with OAM using WLST
$ORACLE_HOME/oracle_common/common/bin/wlst.sh register_webgate.py

# register_webgate.py script:
# connect('weblogic','WLS_Password','t3://oam-server:7001')
# registerNewAgent(agentName='EBS_WebGate_Agent',
#   agentType='WebGate',
#   hostIdentifier='ebsweb01.example.com:443',
#   autoCreatePolicy=True,
#   protectedResources=['/OA_HTML/...', '/forms/...'])

# Copy generated artifacts to OHS WebGate directory
cp /tmp/wg_artifacts/ObAccessClient.xml \
   $ORACLE_HOME/webgate/ohs/config/

cp /tmp/wg_artifacts/cwallet.sso \
   $ORACLE_HOME/webgate/ohs/config/

# Restart OHS
$ORACLE_HOME/bin/opmnctl restartproc ias-component=ohs1

5.1 OHS WebGate Configuration for EBS

⚙️ XML — OHS mod_webgate.conf for EBS Protection
# /u01/oracle/ohs12c/instances/ohs1/config/OHS/ohs1/mod_webgate.conf

<IfModule webgate_module>

  # WebGate configuration file location
  WebGateConfigFileLocation /u01/oracle/ohs12c/webgate/ohs/config

  # EBS Application protected resource policies
  <Location /OA_HTML>
    require valid-user
    AuthType Oblix
    OblixAuth on
    OblixHeaderVars OBUSERDN,OBOAMSESSIONCOOKIENAME
  </Location>

  <Location /forms>
    require valid-user
    AuthType Oblix
    OblixAuth on
  </Location>

  # EBS Asserter endpoint — must be unprotected (handles token validation)
  <Location /ebsasserter>
    Satisfy Any
    Allow from all
    OblixAuth off
  </Location>

  # Exclude static EBS resources from OAM protection
  <Location /OA_MEDIA>
    Satisfy Any
    Allow from all
    OblixAuth off
  </Location>

  <Location /OA_HTML/AppsLocalLogin.jsp>
    Satisfy Any
    Allow from all
    OblixAuth off
  </Location>

</IfModule>
https://oam-server.example.com:7001/oamconsole — Application Security → Agents
Oracle Access Manager Administration Console
weblogic | 12.2.1.4 | Sign Out
Application Security
Agents
Authentication Policies
Authorization Policies
Application Domains
Identity Federation
Identity Providers
Search Results — WebGate Agents
Agent NameTypeHost IdentifierStateActions
EBS_WebGate_AgentWebGateebsweb01.example.com:443ActiveEdit
HR_Portal_WebGateWebGatehrportal.example.com:443ActiveEdit
Create WebGate
Download Config Files
Fig 2. OAM Admin Console — WebGate Agents list showing EBS_WebGate_Agent registered and Active

6. Step 3 — Deploy the EBS Asserter on WebLogic

The EBS Asserter is a WAR file that runs inside a WebLogic managed server (or standalone WLS instance). It handles token validation and EBS ICX session creation.

💻 Shell — Prepare and Deploy EBS Asserter WAR
# Extract EBS Asserter patch artifacts
unzip p25764498_R12.2.0_Generic.zip -d /u01/oracle/ebs_asserter
cd /u01/oracle/ebs_asserter

# Edit the Asserter configuration BEFORE deployment
vi config/asserter.properties

6.1 EBS Asserter Properties File

⚙️ Properties — asserter.properties (Core Configuration)
##=============================================================
## Oracle EBS Asserter — asserter.properties
## Location: WEB-INF/classes/asserter.properties inside WAR
##=============================================================

## EBS Database Connection (for ICX session creation)
ebs.jdbc.url=jdbc:oracle:thin:@ebsdb01.example.com:1521/EBSPROD
ebs.jdbc.user=APPS
ebs.jdbc.password={AES}encrypted_apps_password_here
ebs.jdbc.pool.minSize=5
ebs.jdbc.pool.maxSize=20

## OAM Token Service Configuration
oam.server.host=oam-server.example.com
oam.server.port=14100
oam.token.validate.url=http://oam-server.example.com:14100/oam/services/rest/auth/api/v1/session/jwt/validate
oam.webgate.agent.name=EBS_WebGate_Agent
oam.webgate.password={AES}encrypted_webgate_password

## OID/LDAP for username resolution
ldap.host=oid-server.example.com
ldap.port=389
ldap.bind.dn=cn=orcladmin
ldap.bind.password={AES}encrypted_oid_password
ldap.user.base.dn=cn=Users,dc=example,dc=com
ldap.user.search.filter=(uid={USERNAME})
ldap.ebs.username.attr=orclEBSUserName

## EBS URL Configuration
ebs.base.url=https://ebsweb01.example.com
ebs.apps.servlet.agent=https://ebsweb01.example.com/OA_HTML/RF.jsp
ebs.login.url=https://ebsweb01.example.com/OA_HTML/OA.jsp?OAFunc=OAHOMEPAGE
ebs.logout.url=https://ebsweb01.example.com/OA_HTML/AppsLogout.jsp

## OAM Logout (Single Logout) URL
oam.logout.url=https://oam-server.example.com/oam/server/logout

## Asserter Cookie Settings
asserter.cookie.name=EBS_IAM_SSO_TOKEN
asserter.cookie.domain=.example.com
asserter.cookie.path=/
asserter.cookie.secure=true
asserter.cookie.httpOnly=true
asserter.session.timeout.mins=480

## EBS Responsibility Mapping (OAM Role → EBS Responsibility)
role.mapping.enabled=true
role.map.CN=EBS_SYSADMIN,OU=Groups=SYSTEM_ADMINISTRATOR|FND
role.map.CN=EBS_GL_USERS,OU=Groups=GENERAL_LEDGER_USER|SQLGL
role.map.CN=EBS_PO_BUYERS,OU=Groups=PURCHASING_BUYER|PO
role.map.CN=EBS_HR_MANAGERS,OU=Groups=HR_MANAGER|PER

## Logging
asserter.log.level=INFO
asserter.log.file=/u01/oracle/ebs_asserter/logs/asserter.log
asserter.audit.enabled=true

6.2 Deploy Asserter WAR via WLST

🐍 WLST — Deploy EBS Asserter to WebLogic
# deploy_asserter.py — WLST deployment script
connect('weblogic', 'WLS_Password', 't3://wls-server.example.com:7001')

deploy(
    appName    = 'EBSAsserter',
    path       = '/u01/oracle/ebs_asserter/ebsAsserter.war',
    targets    = 'EBSAsserterServer',
    stageMode  = 'stage',
    planPath   = '/u01/oracle/ebs_asserter/plan.xml'
)

startApplication('EBSAsserter')

# Verify deployment
print(get('/AppDeployments/EBSAsserter/State'))
# Expected output: STATE_ACTIVE

disconnect()
exit()
https://wls-server.example.com:7001/console — Deployments → EBSAsserter
Oracle WebLogic Server Administration Console 12.2.1.4
weblogic | Domain: oam_domain | Sign Out
Domain Structure
oam_domain
Deployments
Services
Security Realms
Servers
Summary of Deployments — EBSAsserter Details
Application Name:
EBSAsserter
Type:
Web Application (WAR)
State:
Active
Health:
✓ OK
Target Server:
EBSAsserterServer
Context Root:
/ebsasserter
Deployed On:
Jun 26, 2026 10:42:18 UTC
Test Application
Stop
Update
Fig 3. WebLogic Admin Console — EBSAsserter WAR deployed and Active on EBSAsserterServer

7. Step 4 — EBS Asserter Core Integration Code

The Asserter application contains a servlet that orchestrates the full SSO flow. Below is the core Java servlet and the PL/SQL package it calls to create EBS ICX sessions.

7.1 EBS Asserter Java Servlet

☕ Java — EBSAsserterServlet.java
package oracle.apps.ebs.iam.asserter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.sql.*;
import oracle.jdbc.pool.OracleDataSource;

/**
 * Oracle EBS IAM Asserter Servlet
 * Validates OAM token and creates EBS ICX session for SSO.
 * Deployed at: /ebsasserter/asserter
 */
public class EBSAsserterServlet extends HttpServlet {

  private static final String OAM_COOKIE_NAME  = "OAM_ID";
  private static final String EBS_SSO_COOKIE    = "EBS_IAM_SSO_TOKEN";
  private AssertorConfig      config;
  private OAMTokenValidator   tokenValidator;
  private LDAPUserResolver    ldapResolver;
  private EBSSessionCreator   sessionCreator;

  @Override
  public void init(ServletConfig cfg) throws ServletException {
    super.init(cfg);
    config         = new AssertorConfig("/WEB-INF/classes/asserter.properties");
    tokenValidator = new OAMTokenValidator(config);
    ldapResolver   = new LDAPUserResolver(config);
    sessionCreator = new EBSSessionCreator(config);
    log("EBS Asserter Servlet initialized. OAM Host: " + config.getOamHost());
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    processAssertion(req, res);
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    processAssertion(req, res);
  }

  private void processAssertion(HttpServletRequest req, HttpServletResponse res)
      throws IOException {

    String requestedUrl = req.getParameter("requestUrl");
    String oamCookieVal = getCookieValue(req, OAM_COOKIE_NAME);
    String oamHeader    = req.getHeader("OAM_REMOTE_USER");

    // ── Step 1: Extract identity from OAM ──────────────────
    OAMIdentity identity = null;
    if (oamCookieVal != null) {
      identity = tokenValidator.validateCookie(oamCookieVal);
    } else if (oamHeader != null) {
      identity = tokenValidator.validateHeader(oamHeader);
    }

    if (identity == null || !identity.isValid()) {
      log("Asserter: No valid OAM token. Redirecting to OAM login.");
      res.sendRedirect(config.getOamLoginUrl() +
                       "?request_url=" + encodeUrl(req.getRequestURL().toString()));
      return;
    }

    log("Asserter: Valid OAM identity: " + identity.getUid());

    // ── Step 2: Resolve EBS username from OID ─────────────
    String ebsUsername = ldapResolver.resolveEBSUsername(identity.getUid());

    if (ebsUsername == null) {
      log("Asserter: No EBS username found in OID for: " + identity.getUid());
      res.sendError(HttpServletResponse.SC_FORBIDDEN,
                    "User not authorized: no EBS account found.");
      return;
    }

    log("Asserter: OID-resolved EBS username: " + ebsUsername);

    // ── Step 3: Resolve EBS responsibility from OAM groups ─
    String respKey  = resolveResponsibility(identity.getGroups());
    String appName  = resolveAppName(identity.getGroups());

    // ── Step 4: Create EBS ICX session ─────────────────────
    EBSSession ebsSession = sessionCreator.createSession(
        ebsUsername, respKey, appName,
        req.getRemoteAddr()
    );

    if (ebsSession == null || ebsSession.getSessionId() == null) {
      log("Asserter: EBS session creation failed for: " + ebsUsername);
      res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    "Failed to create EBS session.");
      return;
    }

    log("Asserter: EBS ICX session created: " + ebsSession.getSessionId());

    // ── Step 5: Set EBS cookies and redirect ───────────────
    setEBSCookies(res, ebsSession, config.getCookieDomain());

    String redirectUrl = (requestedUrl != null)
        ? requestedUrl
        : config.getEbsLoginUrl()
          + "?icx_ticket=" + ebsSession.getSessionId();

    // Write audit log
    AuditLogger.log(ebsUsername, identity.getUid(),
                    req.getRemoteAddr(), "SSO_SUCCESS", redirectUrl);

    res.sendRedirect(redirectUrl);
  }

  private void setEBSCookies(HttpServletResponse res, EBSSession sess, String domain) {
    Cookie icxCookie = new Cookie("ICX_SESSION_TICKET", sess.getSessionId());
    icxCookie.setDomain(domain);
    icxCookie.setPath("/");
    icxCookie.setSecure(true);
    icxCookie.setHttpOnly(true);
    icxCookie.setMaxAge(-1); // session cookie
    res.addCookie(icxCookie);

    Cookie ssoToken = new Cookie(EBS_SSO_COOKIE, sess.getSsoToken());
    ssoToken.setDomain(domain);
    ssoToken.setPath("/");
    ssoToken.setSecure(true);
    ssoToken.setHttpOnly(true);
    ssoToken.setMaxAge(sess.getTimeoutSecs());
    res.addCookie(ssoToken);
  }

  private String resolveResponsibility(java.util.List<String> groups) {
    for (String grp : groups) {
      String mapped = config.getRoleMapping(grp);
      if (mapped != null) return mapped.split("\\|")[0];
    }
    return config.getDefaultResponsibilityKey();
  }

  private String resolveAppName(java.util.List<String> groups) {
    for (String grp : groups) {
      String mapped = config.getRoleMapping(grp);
      if (mapped != null && mapped.contains("|"))
        return mapped.split("\\|")[1];
    }
    return "FND";
  }

  private String getCookieValue(HttpServletRequest req, String name) {
    Cookie[] cookies = req.getCookies();
    if (cookies == null) return null;
    for (Cookie c : cookies)
      if (name.equals(c.getName())) return c.getValue();
    return null;
  }

  private String encodeUrl(String url) {
    try { return java.net.URLEncoder.encode(url, "UTF-8"); }
    catch (Exception e) { return url; }
  }
}

7.2 EBS Session Creator — PL/SQL Bridge

🗄️ PL/SQL — EBS ICX Session Creation Package
CREATE OR REPLACE PACKAGE APPS.xx_iam_asserter_pkg AS

  -- Create ICX session for SSO user (called by Java Asserter via JDBC)
  PROCEDURE create_icx_session(
    p_user_name     IN  VARCHAR2,
    p_resp_key      IN  VARCHAR2,
    p_app_name      IN  VARCHAR2,
    p_ip_address    IN  VARCHAR2,
    x_session_id    OUT VARCHAR2,
    x_sso_token     OUT VARCHAR2,
    x_return_status OUT VARCHAR2,
    x_error_msg     OUT VARCHAR2
  );

  -- Validate an existing ICX session (heartbeat check)
  FUNCTION validate_icx_session(
    p_session_id IN VARCHAR2,
    p_ip_address IN VARCHAR2
  ) RETURN VARCHAR2;  -- Returns 'Y' or 'N'

  -- Terminate ICX session (for SLO)
  PROCEDURE terminate_icx_session(
    p_session_id    IN  VARCHAR2,
    x_return_status OUT VARCHAR2
  );

  -- Get session information
  PROCEDURE get_session_info(
    p_session_id    IN  VARCHAR2,
    x_user_name     OUT VARCHAR2,
    x_resp_name     OUT VARCHAR2,
    x_last_connect  OUT DATE,
    x_return_status OUT VARCHAR2
  );

END xx_iam_asserter_pkg;
/

CREATE OR REPLACE PACKAGE BODY APPS.xx_iam_asserter_pkg AS

  PROCEDURE create_icx_session(
    p_user_name     IN  VARCHAR2,
    p_resp_key      IN  VARCHAR2,
    p_app_name      IN  VARCHAR2,
    p_ip_address    IN  VARCHAR2,
    x_session_id    OUT VARCHAR2,
    x_sso_token     OUT VARCHAR2,
    x_return_status OUT VARCHAR2,
    x_error_msg     OUT VARCHAR2
  ) IS
    l_user_id   NUMBER;
    l_resp_id   NUMBER;
    l_app_id    NUMBER;
    l_session   ICX_SESSIONS%ROWTYPE;
    l_token     VARCHAR2(2000);
  BEGIN
    x_return_status := 'S';  -- Success default

    -- 1. Validate EBS user account is active
    BEGIN
      SELECT user_id
      INTO   l_user_id
      FROM   fnd_user
      WHERE  user_name       = UPPER(p_user_name)
      AND    NVL(end_date, SYSDATE+1) > SYSDATE;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        x_return_status := 'E';
        x_error_msg     := 'EBS user not found or inactive: ' || p_user_name;
        RETURN;
    END;

    -- 2. Get responsibility and application IDs
    BEGIN
      SELECT r.responsibility_id, r.application_id
      INTO   l_resp_id, l_app_id
      FROM   fnd_responsibility_vl r
      JOIN   fnd_application a ON a.application_id = r.application_id
      WHERE  r.responsibility_key    = p_resp_key
      AND    a.application_short_name = p_app_name
      AND    NVL(r.end_date, SYSDATE+1) > SYSDATE
      AND    ROWNUM = 1;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        x_return_status := 'E';
        x_error_msg := 'Responsibility not found: ' || p_resp_key || ' / ' || p_app_name;
        RETURN;
    END;

    -- 3. Check user has the responsibility assigned
    DECLARE
      l_cnt NUMBER;
    BEGIN
      SELECT COUNT(1) INTO l_cnt
      FROM   fnd_user_resp_groups_direct
      WHERE  user_id           = l_user_id
      AND    responsibility_id  = l_resp_id
      AND    responsibility_application_id = l_app_id
      AND    NVL(end_date, SYSDATE+1) > SYSDATE;

      IF l_cnt = 0 THEN
        x_return_status := 'E';
        x_error_msg := 'User '||p_user_name||' lacks responsibility: '||p_resp_key;
        RETURN;
      END IF;
    END;

    -- 4. Initialize FND Global context
    FND_GLOBAL.apps_initialize(
      user_id          => l_user_id,
      resp_id          => l_resp_id,
      resp_appl_id     => l_app_id
    );

    -- 5. Create ICX session using ICX_SEC API
    x_session_id := ICX_SEC.getsessioncookie(
                      p_session_id   => NULL,  -- creates new
                      p_user_id      => l_user_id,
                      p_responsibility_id     => l_resp_id,
                      p_resp_appl_id          => l_app_id,
                      p_security_group_id     => 0,
                      p_language_code         => 'US',
                      p_date_format           => 'DD-MON-RRRR',
                      p_nls_language          => 'AMERICAN',
                      p_nls_numeric_characters=> '.,'
                    );

    IF x_session_id IS NULL THEN
      x_return_status := 'E';
      x_error_msg     := 'ICX_SEC.getsessioncookie returned NULL';
      RETURN;
    END IF;

    -- 6. Update session with IP address for security
    UPDATE icx_sessions
    SET    last_connect       = SYSDATE,
           counter            = counter + 1,
           proxy_user_id      = l_user_id,
           mode_code          = 'SSOEXT',
           disabled_flag      = 'N'
    WHERE  session_id         = x_session_id;

    -- 7. Generate SSO audit token (base64 of session+timestamp)
    x_sso_token := UTL_RAW.cast_to_varchar2(
                     UTL_ENCODE.base64_encode(
                       UTL_RAW.cast_to_raw(
                         x_session_id || '|'
                         || TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')
                         || '|' || p_user_name
                       )
                     )
                   );

    -- 8. Write IAM SSO audit record
    INSERT INTO xx_iam_sso_audit_log (
      log_id, user_name, session_id, sso_token,
      ip_address, login_time, resp_key, status
    ) VALUES (
      xx_iam_sso_audit_seq.NEXTVAL,
      p_user_name, x_session_id, x_sso_token,
      p_ip_address, SYSDATE, p_resp_key, 'LOGGED_IN'
    );

    COMMIT;
    x_return_status := 'S';

  EXCEPTION
    WHEN OTHERS THEN
      ROLLBACK;
      x_return_status := 'E';
      x_error_msg     := SQLERRM;
  END create_icx_session;

  FUNCTION validate_icx_session(
    p_session_id IN VARCHAR2,
    p_ip_address IN VARCHAR2
  ) RETURN VARCHAR2 IS
    l_valid VARCHAR2(1);
  BEGIN
    SELECT CASE WHEN COUNT(1) > 0 THEN 'Y' ELSE 'N' END
    INTO   l_valid
    FROM   icx_sessions
    WHERE  session_id    = p_session_id
    AND    disabled_flag = 'N'
    AND    last_connect >= SYSDATE - (1/24) * 8; -- 8-hour timeout
    RETURN l_valid;
  END;

  PROCEDURE terminate_icx_session(
    p_session_id    IN  VARCHAR2,
    x_return_status OUT VARCHAR2
  ) IS
  BEGIN
    UPDATE icx_sessions
    SET    disabled_flag = 'Y',
           last_connect  = SYSDATE
    WHERE  session_id   = p_session_id;

    -- Update audit log
    UPDATE xx_iam_sso_audit_log
    SET    status = 'LOGGED_OUT', logout_time = SYSDATE
    WHERE  session_id = p_session_id;

    COMMIT;
    x_return_status := 'S';
  EXCEPTION
    WHEN OTHERS THEN
      ROLLBACK;
      x_return_status := 'E';
  END;

  PROCEDURE get_session_info(
    p_session_id    IN  VARCHAR2,
    x_user_name     OUT VARCHAR2,
    x_resp_name     OUT VARCHAR2,
    x_last_connect  OUT DATE,
    x_return_status OUT VARCHAR2
  ) IS
  BEGIN
    SELECT fu.user_name, rv.responsibility_name, s.last_connect
    INTO   x_user_name, x_resp_name, x_last_connect
    FROM   icx_sessions s
    JOIN   fnd_user fu
           ON fu.user_id = s.user_id
    JOIN   fnd_responsibility_vl rv
           ON rv.responsibility_id = s.responsibility_id
    WHERE  s.session_id = p_session_id;
    x_return_status := 'S';
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      x_return_status := 'E';
  END;

END xx_iam_asserter_pkg;
/

7.3 Audit Log DDL

🗄️ SQL — IAM SSO Audit Table & Sequence
-- IAM SSO Audit Log Table
CREATE TABLE APPS.xx_iam_sso_audit_log (
  log_id        NUMBER          NOT NULL,
  user_name     VARCHAR2(100)   NOT NULL,
  session_id    VARCHAR2(200)   NOT NULL,
  sso_token     VARCHAR2(2000),
  ip_address    VARCHAR2(45),
  login_time    DATE            DEFAULT SYSDATE,
  logout_time   DATE,
  resp_key      VARCHAR2(100),
  status        VARCHAR2(30)    DEFAULT 'LOGGED_IN',
  oam_uid       VARCHAR2(200),
  user_agent    VARCHAR2(500),
  created_by    NUMBER          DEFAULT -1,
  creation_date DATE            DEFAULT SYSDATE,
  CONSTRAINT xx_iam_sso_audit_pk PRIMARY KEY (log_id)
);

CREATE SEQUENCE APPS.xx_iam_sso_audit_seq
  START WITH 1 INCREMENT BY 1 NOCYCLE NOCACHE;

CREATE INDEX APPS.xx_iam_sso_audit_idx1
  ON APPS.xx_iam_sso_audit_log(user_name, login_time);

CREATE INDEX APPS.xx_iam_sso_audit_idx2
  ON APPS.xx_iam_sso_audit_log(session_id);

COMMENT ON TABLE APPS.xx_iam_sso_audit_log
  IS 'IAM Asserter SSO Session Audit Log - tracks all SSO login/logout events';

-- Grant access for Asserter's JDBC user
GRANT INSERT, UPDATE, SELECT ON APPS.xx_iam_sso_audit_log TO apex_ebs_user;
GRANT SELECT ON APPS.xx_iam_sso_audit_seq TO apex_ebs_user;

8. Step 5 — Oracle Identity Manager (OIM): EBS User Provisioning

OIM automates user lifecycle management — creating, modifying, and deactivating EBS accounts when HR events occur (new hire, role change, termination). The EBS connector for OIM communicates via a JDBC connector or the EBS SOAP/REST APIs.

8.1 OIM EBS Connector Configuration

https://oim-server.example.com:14000/identity — Provisioning → Application Instances
Oracle Identity Manager — Self Service Console
xelsysadm | 12.2.1.4 | Sign Out
Administration
Provisioning
Users
Roles
Reconciliation
Connectors
Catalog
Application Instances — Oracle EBS R12 Connector
Application Instance:
OracleEBS_PROD
Connector Version:
12.2.1.3.0 (EBS R12 Connector)
IT Resource:
EBSProdDB
Status:
Active
Provisioning Policy:
On-Demand + Automated (via Role Policy)
Reconciliation:
Full Recon: Daily 02:00 | Incremental: Every 15 min
✅ Last Reconciliation: Jun 26, 2026 02:00:14 — 2,841 users synced, 3 created, 1 disabled, 0 errors
Fig 4. Oracle Identity Manager — EBS R12 Connector Application Instance showing Active provisioning

8.2 OIM Custom Event Handler for EBS Provisioning

☕ Java — OIM PostProcessHandler for EBS User Create
package oracle.apps.ebs.iam.oim;

import oracle.iam.platform.kernel.vo.EventResult;
import oracle.iam.platform.kernel.vo.Orchestration;
import oracle.iam.platform.kernel.spi.PostProcessHandler;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.provisioning.api.ProvisioningService;
import oracle.iam.platform.OIMClient;

import java.sql.*;
import java.util.*;

/**
 * OIM Post-Process Event Handler
 * Triggered after a new OIM user is created.
 * Automatically provisions EBS FND_USER account.
 */
public class EBSUserProvisionHandler implements PostProcessHandler {

  private static final String EBS_RESOURCE_NAME = "OracleEBSProd";

  @Override
  public EventResult execute(long processId, long eventId, Orchestration orch) {
    try {
      HashMap<String, Object> params = orch.getParameters();
      String uid       = (String) params.get("usr_login");
      String email     = (String) params.get("usr_email");
      String firstName = (String) params.get("usr_first_name");
      String lastName  = (String) params.get("usr_last_name");
      String empNumber = (String) params.get("usr_emp_no");

      // Call EBS to create the FND_USER account
      provisionEBSUser(uid, email, firstName, lastName, empNumber);

      // Assign default OAM group (maps to EBS responsibility)
      assignDefaultOAMGroup(uid, "CN=EBS_GENERAL_USERS,OU=Groups,DC=example,DC=com");

      return new EventResult();  // Success

    } catch (Exception e) {
      System.err.println("EBSUserProvisionHandler failed: " + e.getMessage());
      return new EventResult();  // Non-blocking — log but don't fail user creation
    }
  }

  private void provisionEBSUser(String uid, String email,
      String first, String last, String empNo) throws Exception {

    Connection conn = getEBSConnection();
    CallableStatement cs = conn.prepareCall(
        "{ call APPS.FND_USER_PKG.CreateUser("
      + "  x_user_name         => ?,"
      + "  x_owner             => 'CUST',"
      + "  x_unencrypted_password => ?,"
      + "  x_start_date        => sysdate,"
      + "  x_end_date          => null,"
      + "  x_email_address     => ?,"
      + "  x_description       => ?,"
      + "  x_employee_id       => ?"
      + ") }"
    );

    cs.setString(1, uid.toUpperCase());
    cs.setString(2, "Welcome#1Temp");  // Force change on first login
    cs.setString(3, email);
    cs.setString(4, first + " " + last + " (IAM Provisioned)");
    if (empNo != null) cs.setInt(5, Integer.parseInt(empNo));
    else cs.setNull(5, Types.INTEGER);

    cs.execute();
    conn.commit();
    cs.close();
    conn.close();

    System.out.println("OIM→EBS: User provisioned: " + uid);
  }

  private void assignDefaultOAMGroup(String uid, String groupDN) {
    // Add user to OAM/OID group via LDAP — triggers OAM policy assignment
    // Implementation uses JNDI DirContext (omitted for brevity)
    System.out.println("OIM: Assigned default OAM group to: " + uid);
  }

  private Connection getEBSConnection() throws Exception {
    return DriverManager.getConnection(
        "jdbc:oracle:thin:@ebsdb01.example.com:1521/EBSPROD",
        "APPS", System.getenv("EBS_APPS_PWD")
    );
  }

  @Override public void initialize(HashMap<String,String> p) {}
  @Override public boolean cancel(long a, long b, Orchestration o) { return false; }
  @Override public void compensate(long a, long b, Orchestration o) {}
}

8.3 EBS Responsibility Sync PL/SQL

🗄️ PL/SQL — OIM to EBS Responsibility Assignment Sync
CREATE OR REPLACE PROCEDURE APPS.xx_iam_assign_responsibility(
  p_user_name  IN VARCHAR2,
  p_resp_key   IN VARCHAR2,
  p_app_name   IN VARCHAR2,
  p_action     IN VARCHAR2 DEFAULT 'GRANT', -- GRANT | REVOKE
  x_status     OUT VARCHAR2,
  x_message    OUT VARCHAR2
) AS
  l_user_id NUMBER;
  l_resp_id NUMBER;
  l_app_id  NUMBER;
BEGIN
  -- Lookup user
  SELECT user_id INTO l_user_id
  FROM   fnd_user WHERE user_name = UPPER(p_user_name);

  -- Lookup responsibility
  SELECT r.responsibility_id, r.application_id
  INTO   l_resp_id, l_app_id
  FROM   fnd_responsibility_vl r
  JOIN   fnd_application a ON a.application_id = r.application_id
  WHERE  r.responsibility_key    = p_resp_key
  AND    a.application_short_name = p_app_name
  AND    ROWNUM = 1;

  IF p_action = 'GRANT' THEN
    -- Add responsibility using FND_USER_PKG
    FND_USER_PKG.ADDRESP(
      username    => UPPER(p_user_name),
      resp_appl   => p_app_name,
      responsibility => p_resp_key,
      security_group => 'STANDARD',
      description => 'Assigned by OIM IAM Integration',
      start_date  => SYSDATE,
      end_date    => NULL
    );

  ELSIF p_action = 'REVOKE' THEN
    -- End-date the responsibility assignment
    UPDATE fnd_user_resp_groups_direct
    SET    end_date = SYSDATE - 1/(24*60)
    WHERE  user_id                 = l_user_id
    AND    responsibility_id       = l_resp_id
    AND    responsibility_application_id = l_app_id;
  END IF;

  COMMIT;
  x_status  := 'S';
  x_message := p_action || ' SUCCESS: ' || p_resp_key || ' for ' || p_user_name;

EXCEPTION
  WHEN NO_DATA_FOUND THEN
    x_status  := 'E';
    x_message := 'User or responsibility not found: ' || p_user_name || ' / ' || p_resp_key;
  WHEN OTHERS THEN
    ROLLBACK;
    x_status  := 'E';
    x_message := SQLERRM;
END xx_iam_assign_responsibility;
/

9. Step 6 — OAM Authentication & Authorization Policies for EBS

Define OAM policies that protect EBS URL patterns and specify what authentication strength is required for each resource.

⚙️ XML — OAM Application Domain Policy for EBS (REST export format)
<ApplicationDomain
  name="EBS_R12_Production"
  description="OAM Policies for Oracle EBS R12.2 SSO via Asserter">

  <Resources>
    <Resource type="HTTP" host="ebsweb01.example.com"
               port="443" pattern="/"
               authzPolicy="EBS_AuthZ_Policy"
               authnPolicy="EBS_AuthN_Policy"/>

    <!-- Unprotected resources (no auth needed) -->
    <Resource type="HTTP" pattern="/OA_HTML/AppsLocalLogin.jsp"
               protected="false"/>
    <Resource type="HTTP" pattern="/OA_MEDIA/**"
               protected="false"/>
    <Resource type="HTTP" pattern="/ebsasserter/**"
               protected="false"/>

    <!-- Higher-security resources require MFA -->
    <Resource type="HTTP" pattern="/OA_HTML/OA.jsp?OAFunc=OAGLADMINPAGE"
               authnPolicy="EBS_AuthN_MFA_Policy"/>
  </Resources>

  <AuthenticationPolicies>
    <AuthenticationPolicy name="EBS_AuthN_Policy">
      <AuthenticationScheme ref="LDAPScheme"/>
      <!-- On success: redirect to EBS Asserter -->
      <SuccessURL>https://ebsweb01.example.com/ebsasserter/asserter</SuccessURL>
      <FailureURL>https://oam-server.example.com/oam/server/obrareq.cgi</FailureURL>
    </AuthenticationPolicy>

    <AuthenticationPolicy name="EBS_AuthN_MFA_Policy">
      <AuthenticationScheme ref="MFAOTPScheme"/>
      <SuccessURL>https://ebsweb01.example.com/ebsasserter/asserter</SuccessURL>
    </AuthenticationPolicy>
  </AuthenticationPolicies>

  <AuthorizationPolicies>
    <AuthorizationPolicy name="EBS_AuthZ_Policy">
      <Conditions>
        <Condition type="IdentityAssertion">
          <Attribute name="memberOf"
                     value="CN=EBS_USERS,OU=Groups,DC=example,DC=com"/>
        </Condition>
        <Condition type="IPAddress">
          <AllowedRange>10.0.0.0/8</AllowedRange>
          <AllowedRange>192.168.0.0/16</AllowedRange>
        </Condition>
      </Conditions>
      <ResponseAttrs>
        <!-- OAM headers passed to OHS/Asserter after successful authZ -->
        <Header name="OAM_REMOTE_USER"    type="ldap"  attr="uid"/>
        <Header name="OAM_USER_DN"        type="ldap"  attr="dn"/>
        <Header name="OAM_EBS_USERNAME"   type="ldap"  attr="orclEBSUserName"/>
        <Header name="OAM_GROUPS"         type="ldap"  attr="isMemberOf"/>
        <Header name="OAM_USER_EMAIL"     type="ldap"  attr="mail"/>
        <Cookie name="OAM_ID"             domain=".example.com"/>
      </ResponseAttrs>
    </AuthorizationPolicy>
  </AuthorizationPolicies>

</ApplicationDomain>
✅ Single Logout (SLO) ConfigurationFor SLO, OAM must call the EBS Asserter's /ebsasserter/logout endpoint on logout, which triggers xx_iam_asserter_pkg.terminate_icx_session() in EBS. Configure the OAM Logout URL in the Agent registration to include: https://ebsweb01.example.com/ebsasserter/logout?returnUrl={logoutReturnUrl}

10. Troubleshooting Common IAM Asserter Issues

Error / SymptomRoot CauseResolution
Asserter returns HTTP 403OAM group not in Asserter role mapping or user missing orclEBSUserName in OIDCheck asserter.properties role.map entries; run LDAP search to verify orclEBSUserName attribute
ICX_SEC.getsessioncookie returns NULLEBS FND_USER is end-dated, or responsibility end-datedQuery SELECT * FROM fnd_user WHERE user_name='XX' and SELECT * FROM fnd_user_resp_groups_direct
OAM_ID cookie missing in AsserterWebGate not forwarding OAM cookie headers; OHS mod_webgate config errorCheck mod_webgate.conf; verify OblixHeaderVars includes OBOAMSESSIONCOOKIENAME
Login loop (redirect storm)Asserter URL is OAM-protected; should be unprotectedAdd /ebsasserter/** as unprotected resource in OAM Application Domain
OIM provisioning fails with ORA-20001FND_USER_PKG.CreateUser duplicate username or missing required fieldsCheck SELECT * FROM fnd_user WHERE user_name='XX' for duplicates; verify all required params
EBS session expires too fastICX profile ICX: Session Timeout set too lowSet via: FND_PROFILE.SAVE('ICX_SESSION_TIMEOUT','480','SITE'); (480 = 8 hours)
Kerberos SSO not workingWebGate Kerberos scheme not configured in OAMConfigure KerberosScheme in OAM Admin Console and ensure SPN is registered: setspn -A HTTP/ebsweb01.example.com svc_oam

Diagnostic Queries

🔍 SQL — IAM / EBS Asserter Diagnostic Queries
-- 1. Check ICX active sessions for a user
SELECT s.session_id,
       fu.user_name,
       s.last_connect,
       s.disabled_flag,
       s.mode_code,
       r.responsibility_name
FROM   icx_sessions s
JOIN   fnd_user fu ON fu.user_id = s.user_id
JOIN   fnd_responsibility_vl r
       ON r.responsibility_id = s.responsibility_id
WHERE  fu.user_name = 'SYSADMIN'
AND    s.disabled_flag = 'N'
ORDER BY s.last_connect DESC;

-- 2. Check IAM SSO audit log
SELECT user_name, session_id, ip_address,
       login_time, logout_time, resp_key, status
FROM   xx_iam_sso_audit_log
WHERE  login_time >= SYSDATE - 1
ORDER BY login_time DESC
FETCH FIRST 50 ROWS ONLY;

-- 3. EBS users without OID mapping (need sync)
SELECT u.user_name, u.email_address, u.creation_date
FROM   fnd_user u
WHERE  NVL(u.end_date, SYSDATE+1) > SYSDATE
AND    u.user_name NOT IN (
         -- Simulated: replace with actual OID sync verification table
         SELECT ebs_user_name FROM xx_oid_sync_log
         WHERE  sync_status = 'SUCCESS'
       )
ORDER BY u.user_name;

-- 4. ICX session timeout profile value
SELECT profile_option_value
FROM   fnd_profile_option_values
JOIN   fnd_profile_options USING (profile_option_id)
WHERE  profile_option_name = 'ICX_SESSION_TIMEOUT'
AND    level_id = 10001;  -- SITE level

-- 5. OIM provisioned users (last 7 days)
SELECT user_name, email_address,
       TO_CHAR(creation_date,'DD-MON-YYYY HH24:MI') created,
       description
FROM   fnd_user
WHERE  description LIKE '%IAM Provisioned%'
AND    creation_date >= SYSDATE - 7
ORDER BY creation_date DESC;

11. Summary, Security Checklist & Next Steps

✅ Integration Completed — You Have Configured:OID schema extension → LDAP user sync package → OAM WebGate on OHS → EBS Asserter deployment on WLS → ICX session creation PL/SQL → Java Asserter servlet → OIM provisioning handler → OAM Application Domain policies → Audit logging → SLO

Security Hardening Checklist

ItemRequiredNotes
Asserter properties passwords encrypted✅ MandatoryUse OPSS CSF KeyStore or OWallet for credential storage
HTTPS enforced on all EBS/OAM URLs✅ MandatoryTLS 1.2+ only; disable TLS 1.0/1.1
WebGate uses certificate-based trust✅ MandatoryConfigure OAM + WebGate with OWallet certs, not passwords
ICX session timeout ≤ 8 hours✅ RecommendedProfile: ICX_SESSION_TIMEOUT = 480
OAM MFA for sensitive EBS functions⭐ RecommendedApply MFAOTPScheme to GL/Finance/Admin URLs
Audit log purge policy✅ MandatoryRetain IAM audit logs ≥ 90 days; archive to cold storage
OIM role approval workflow⭐ RecommendedManager approval before EBS responsibility assignment

Recommended Next Steps

  • Configure Oracle Adaptive Authentication (OAA) for risk-based MFA on EBS login
  • Integrate Oracle Privileged Account Manager (OPAM) for DBA / privileged EBS accounts
  • Implement OIM Role Catalog with self-service EBS responsibility requests
  • Set up OAM Token Relay for EBS ISG REST API OAuth 2.0 client credential flows
  • Configure SAML 2.0 federation via OAM as IdP for cross-domain EBS access
  • Deploy Oracle Identity Governance (OIG) Certification Campaigns for periodic EBS access reviews
📚 ReferencesMOS Doc ID2462012.1(EBS Asserter Setup) ·1388152.1(OAM WebGate EBS) ·1540075.1(OIM EBS Connector) ·2277035.1(EBS SSO Integration Guide) · Oracle OAM Admin Guide 12.2.1.4 · Oracle OIM Connector Guide 12.2.1.3
Oracle IAMOAM 12cOIM 12cEBS AsserterOracle EBS R12.2SSOWebGateOID/LDAPICX SessionsPL/SQLJavaFND_USER_PKGOAM PoliciesSLOMFA

A

AppsDBA Workshop - SYED ZAHEER

Service Delivery Director, Oracle EBS DBA, IAM Architect, and Security Specialist with 20+ years in Oracle Implementations, OAM/OIM integrations, and enterprise identity governance across MENA and global enterprises.

🌐www.techvisions.com.sa  |  @AppsDBAWorkshop


 

Comments

Popular posts from this blog

Installation of Oracle Applications R12.1.1 on Linux and vmware

ntp service in Maintenance mode Solaris 10

Oracle AVDF Installation and Setup Document