User Impersonation → OIC Basic Authentication (userid)¶
Folder: user_impersonation_oic_basic_oauth/
Impersonation pattern for OIC integrations secured with the Basic Authentication trigger policy: the caller supplies real EBS username/password, OIC validates it against its BASIC_AUTH security policy, and its EBS Adapter invoke connection passes that same credential straight through to EBS. The EBS API call runs as that specific user, not a shared service account.
This is the token_factory target_tool="userid" reference. It's a different mechanism from E2E Identity Propagation → OIC, which propagates a Bearer token to OIC's own MCP server via a connectivity agent and a fixed OIC integration user. Here there's no Bearer token exchange with OIC at all — the credential OIC's EBS Adapter uses is the caller's own EBS password, forwarded as HTTP Basic Auth.
Why userid, and what it actually checks¶
An IDCS access token never carries a password — token_factory can't hand this pattern anything to authenticate the EBS Adapter call with. What it can do is confirm the caller is who they claim to be:
from auth.token_factory import TokenFactory
factory = TokenFactory()
result = factory.get_token(caller_access_token, "userid", scope=oauth_scope)
user_id = result["user_id"]
The backend rejects the request if the EBS username supplied in the form doesn't match user_id (case-insensitive). This doesn't authenticate the EBS password itself — only EBS/OIC can do that — but it closes an obvious gap: without this check, a user logged into the app as themselves could type in someone else's EBS username and password and have the app forward them without objection. With it, the app only ever forwards EBS credentials that claim to belong to the same identity IDCS just verified.
Architecture¶
Browser ──► FastAPI backend (port 8000)
│ OAuth2 authorization code flow (IDCS), CSRF-protected
│ Establishes who the caller is; EBS username/password
│ collected separately in the form (never derived from IDCS)
▼
TokenFactory.get_token(caller_token, "userid", scope=...) → user_id
│ reject if ebs_username != user_id
▼
requests.post(OIC_BASIC_AUTH_ENDPOINT_URL, auth=(ebs_username, ebs_password))
│ Authorization: Basic base64(ebs_username:ebs_password)
▼
OIC integration (Basic Authentication trigger)
│ BASIC_AUTH security policy validates the credential
│ EBS Adapter invoke connection passes it through
▼
Oracle E-Business Suite (acting as ebs_username)
Stand-in for the not-yet-deployed OIC endpoint¶
stub_oic_basic_auth_server/ is a minimal local endpoint that decodes the incoming Authorization: Basic header and simulates a Create Supplier response — but has no real credential store to validate against (unlike real EBS/OIC, which would reject a bad password). Everything upstream of it — IDCS login, CSRF protection, and the TokenFactory userid resolution and identity-match check — is real. Point OIC_BASIC_AUTH_ENDPOINT_URL at the real integration URL once deployed and delete this directory.
HTTPS is mandatory in any real deployment
HTTP Basic Auth sends username:password base64-encoded, not encrypted — base64 is trivially reversible. This pattern runs over plain HTTP on localhost for local development only.
Token Flow¶
- User clicks Login →
/loginissues a single-use, randomstatevalue and redirects to IDCS/oauth2/v1/authorize - IDCS authenticates user → redirects to
/callback?code=...&state=... - Backend validates
state(CSRF protection), exchangescodeforaccess_token - Backend redirects to
/#access_token=<token>(URL fragment); UI stores it inlocalStorageand pre-fills the EBS username field from/whoami - User enters their EBS password and submits Create Supplier
- Backend resolves the caller's identity via
TokenFactory'suseridflow and rejects the request if the submittedebs_usernamedoesn't match - Backend calls the OIC endpoint with
Authorization: Basic base64(ebs_username:ebs_password); OIC'sBASIC_AUTHpolicy validates it and its EBS Adapter connection passes the same credential through to EBS
When to use: EBS integrations where the target EBS environment relies on per-user Basic Authentication rather than IDCS-federated identity propagation, and true credential impersonation (not a shared account) is required.