10.5 Advanced: Implement a Security Context Provider
If your authentication and authorization workflow requires custom logic, or if there's no out-of-the-box (OOTB) security context provider available for your application framework, you can build your own provider.
A custom provider bridges your application's security context and the Oracle client driver, enabling automatic propagation of the end-user security context payload to the database without modifying your application code.
The instructions in this section are primarily for the Oracle JDBC driver and Java-based application frameworks. If you are using a different client driver (such as python-oracledb or ODP.NET), apply the same principles using the equivalent provider interface and registration mechanism in your driver. See the respective driver documentation for API details.
10.5.1 Understand the Security Context Payload
Before building a provider, understand the components of the end-user security context payload that the database expects. Every payload must include the following mandatory components and may include optional components.
- End-user identity (mandatory): The end user's name as asserted in the IAM access token. For end users managed locally, this is the name of the end user created in the database.
- Database access token (mandatory): Authorizes the
application’s connection to the database. Obtain this token from your IAM
system using one of the following flows:
- Client credentials flow: The application authenticates as itself.
- On-behalf-of (OBO) flow: The application exchanges the end-user’s token for a database-access token.
- Data roles (optional): A list of additional data roles that the application can enable for the end-user security context, beyond those mapped to application roles in IAM and those enabled by default for the application identity.
- Context attributes (optional): A dictionary of application-defined key-value pairs to include in the security context. Used when application logic or data grants rely on custom end-user context attributes.
10.5.2 Understand the Driver’s Provider Interface
To propagate the end-user security context payload, the Oracle JDBC driver
defines a Service Provider Interface (SPI) named
EndUserSecurityContextProvider. Your custom provider must implement
this interface and its getEndUserSecurityContext() method.
getEndUserSecurityContext() before every
database operation on the connection. Your implementation must return an
EndUserSecurityContext object containing the end-user identity,
database-access token, and any optional data roles or attributes. The driver
piggybacks this payload to the database on the next round-trip. If the method
returns null, the driver proceeds without attaching a security context payload.
Note:
For other client drivers, use the equivalent provider interface. For example, the python-oracledb driver'send_user_sec_provider plug-in uses a configuration-driven
mechanism with middleware hooks. See the respective driver documentation for the
specific interface contract.
10.5.3 Build the Security Context Provider
Your provider implementation must perform three tasks each time the driver
calls getEndUserSecurityContext(). The following steps describe these tasks
for a JDBC provider. Adapt the approach to your client driver as needed.
10.5.4 Register the Provider with the Driver
The JDBC driver discovers your provider through the standard Java
ServiceLoader mechanism.
10.5.5 Configure the Driver to Use Your Provider
Set the oracle.jdbc.provider.endUserSecurityContext
connection property to the name of your provider.
This name is the value returned by your provider’s getName() method.
Set this property in your connection pool’s data source configuration.
# Activate the custom provider
spring.datasource.hikari.data-source-properties.\
oracle.jdbc.provider.endUserSecurityContext = my-custom-provider
Properties props = new Properties();
props.setProperty(
"oracle.jdbc.provider.endUserSecurityContext",
"my-custom-provider"
);
dataSource.setDataSourceProperties(props);
10.5.6 Support Privilege Elevation (Optional)
Some application operations require temporary elevated privileges. For example, reading all employees’ salary data to generate a summary report. To support this, your provider can accept additional data roles injected at runtime for the duration of a specific code block.
- Application code temporarily adds data roles (with a distinguishing prefix) to the framework’s security context before the database call.
- The provider reads the prefixed roles from the security context
and includes them in the
EndUserSecurityContextpayload. - After the method returns, the application restores the original security context.
To implement this pattern in your framework, use the equivalent of a method
interceptor or decorator that wraps the target method, augments the security context
with additional data roles, invokes the method, and restores the original context in
a finally block.
For the Spring Boot reference implementation of this pattern (using
GrantedAuthority and the @RunWithDataRoles
annotation), see the Oracle JDBC Extensions source code on GitHub.
10.5.7 Note for Other Client Drivers
If your application uses python-oracledb or ODP.NET instead of JDBC, the same architectural pattern applies: implement a component that extracts the end-user identity, acquires the database-access token, constructs the security context payload, and hooks into the driver’s connection life cycle. The specific interfaces, registration mechanisms, and configuration properties differ by driver.
For the python-oracledb driver, see the python-oracledb documentation.
For the ODP.NET driver, see the Oracle Data Provider for .NET documentation.