Introduction
This article shows how to configure a WebLogic Server JDBC data source to connect to Oracle Autonomous Database by using an OCI IAM database token. The data source has no database user name or password. OCI IAM issues a short-lived database token, the Oracle JDBC Thin driver reads it from the WebLogic operating-system account, and the database maps the IAM group to a global database user.
The configuration was validated with WebLogic Server 14.1.2.0.0 and Oracle JDBC Thin 23.26.0.0.0, a WebLogic cluster, an Autonomous Database running Oracle AI Database 26ai, a cluster-targeted Generic Data Source, and a small web application that writes and reads rows. The same pattern applies to a standalone managed server and to other supported WebLogic Server releases when they use a compatible Oracle JDBC Thin driver.
IAM database tokens require a TCPS connection and expire after one hour. The host must refresh them before expiry. See Authenticating and Authorizing IAM Users for Oracle AI Database.
In This Series
This is Part 1 of the Passwordless JDBC with OCI IAM Tokens series:
- WebLogic Server and Autonomous Database 26ai (this article)
- WebLogic Server and Oracle AI Database on OCI (planned)
- Operating OCI IAM Token Authentication for WebLogic JDBC Data Sources (planned)
The first two articles show the database-specific setup. The third focuses on the shared production concerns: token renewal, pooling behavior, monitoring, and troubleshooting.
What This Article Configures
- An IAM user is placed in an IAM group.
- Autonomous Database maps that group to a global database user.
- The oracle OS account on every WebLogic host is configured with OCI CLI and an API key for that IAM user.
- OCI CLI writes a database token and paired private key under ~/.oci/db-token.
- A wallet TNS alias contains TOKEN_AUTH=OCI_TOKEN.
- The WebLogic data source uses that alias and the wallet directory. It does not contain a database password.
- A host-side cron job refreshes the token every 30 minutes.
Replace values in angle brackets with values from your environment.
Prerequisites
You need:
- The file-based TOKEN_AUTH=OCI_TOKEN flow in this article requires Oracle JDBC Thin 19.16 or later. WebLogic Server 12.2.1.4, 14.1.1, 14.1.2, and 15.1.1 include supported Oracle JDBC Thin versions when the latest applicable Oracle JDBC for Fusion Middleware JDBC 23.26.x/19.x Bundle Patch for that WebLogic Server release is applied. Confirm the exact installed driver version in your environment; if it is older than 19.16, apply the latest corresponding Bundle Patch. See (KA1182) Critical Patch Update (CPU) Patch Advisor for Oracle Fusion Middleware to identify the patch for the WebLogic Server release. The patch updates the JDBC drivers bundled with WebLogic Server to the upgraded driver versions.
- An Autonomous Database with IAM external authentication enabled.
- An extracted Autonomous Database wallet on every host that can run an application using the data source.
- An OCI IAM user with an uploaded API public key and membership in the IAM group mapped to the database schema.
- Permission to install OCI CLI and create a root-managed cron file on every WebLogic managed-server host.
This article assumes WebLogic runs as the oracle OS user. Do not run the token process as root: the JDBC driver needs access to the token files through the same OS account that runs WebLogic.
1. Configure IAM and the Database Mapping
Enable OCI IAM external authentication for Autonomous Database as an appropriate database administrator:
BEGIN
DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION(type => 'OCI_IAM');
END;
/
Confirm the result:
SHOW PARAMETER identity_provider_type
The value should be OCI_IAM.
Map the IAM group to a global database user. A shared mapping is practical for an application service account because every group member maps to the same application schema:
CREATE USER <hello_app_schema>
IDENTIFIED GLOBALLY AS 'IAM_GROUP_NAME=<iam_group_name>';
GRANT CREATE SESSION TO <hello_app_schema>;
Grant only the object privileges the application needs. For a small example that creates its own table:
GRANT CREATE TABLE TO <hello_app_schema>;
ALTER USER <hello_app_schema> QUOTA UNLIMITED ON DATA;
CREATE TABLE hello_messages (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
message VARCHAR2(1000) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
created_by VARCHAR2(512)
DEFAULT SYS_CONTEXT('USERENV', 'AUTHENTICATED_IDENTITY') NOT NULL
);
Create an IAM policy that permits the group to request and use database tokens:
Allow group <iam_group_name> to use database-connections in tenancy
You can restrict the policy to a compartment or a single Autonomous Database when that fits the deployment model. The IAM documentation describes both database-connections and autonomous-database-family policy options.
2. Install and Configure OCI CLI on Each WebLogic Host
Install OCI CLI under the oracle account. These locations are used here:
/home/oracle/bin/oci
/home/oracle/lib/oci-cli
/home/oracle/.oci/config
/home/oracle/.oci/<api_key_private_file>
Configure a dedicated OCI CLI profile. The private API key and configuration file must be readable only by oracle:
[<oci_profile>]
user=<iam_user_ocid>
fingerprint=<api_key_fingerprint>
key_file=/home/oracle/.oci/<api_key_private_file>
tenancy=<tenancy_ocid>
region=<region>
Generate a token as the WebLogic OS user:
sudo -u oracle /home/oracle/bin/oci iam db-token get --profile <oci_profile>
OCI CLI writes these files by default:
/home/oracle/.oci/db-token/token
/home/oracle/.oci/db-token/oci_db_key.pem
Protect this directory. The token and paired key allow database access for the mapped IAM principal, so only the operating-system account that runs WebLogic should be able to read them. Set ownership and restrictive permissions after you configure the OCI CLI:
sudo chown -R oracle:oracle /home/oracle/.oci
sudo chmod 700 /home/oracle/.oci
sudo chmod 700 /home/oracle/.oci/db-token
sudo chmod 600 /home/oracle/.oci/config
sudo chmod 600 /home/oracle/.oci/<api_key_private_file>
sudo chmod 600 /home/oracle/.oci/db-token/token
sudo chmod 600 /home/oracle/.oci/db-token/oci_db_key.pem
Do not place this directory in shared storage, deployment archives, backups, support bundles, configuration repositories, or diagnostic output. The refresh log should also be readable only by oracle:
sudo chmod 600 /home/oracle/.oci/db-token/refresh.log
3. Configure the Wallet TNS Alias
Download and extract the Autonomous Database wallet on every managed-server host. In this example the wallet directory is:
/u01/app/oracle/adb-wallet/<adb_name>
Start with a standard low-service alias from the wallet tnsnames.ora and add TOKEN_AUTH=OCI_TOKEN in its SECURITY section. Retain the host and service name supplied by your wallet:
<adb_iam_low> =
(description=
(retry_count=20)(retry_delay=3)
(address=(protocol=tcps)(port=1522)(host=<adb_host>))
(connect_data=(service_name=<adb_low_service>))
(security=(ssl_server_dn_match=yes)(TOKEN_AUTH=OCI_TOKEN)))
TOKEN_LOCATION is not needed when OCI CLI and the JDBC driver use the default ~/.oci/db-token directory under the same oracle account. Set it only when you deliberately store the token elsewhere. A token setting in the connect descriptor takes precedence over file-level defaults.
4. Refresh the Token Automatically
Database tokens expire after one hour. Create this script as /home/oracle/bin/refresh-adb-db-token:
#!/usr/bin/env bash
set -euo pipefail
export PATH=/home/oracle/bin:/usr/bin:/bin
exec /home/oracle/bin/oci iam db-token get --profile <oci_profile>
On hardened images, oracle may not be allowed to use crontab. Use a root-managed file named /etc/cron.d/adb-db-token-refresh instead:
*/30 * * * * oracle /usr/bin/flock -n /home/oracle/.oci/db-token/.refresh.lock /home/oracle/bin/refresh-adb-db-token >> /home/oracle/.oci/db-token/refresh.log 2>&1
This runs twice an hour, well inside the one-hour token lifetime. flock prevents overlapping refreshes. Verify the job in the same user context:
sudo -u oracle /bin/bash -lc \
'/usr/bin/flock -n /home/oracle/.oci/db-token/.refresh.lock \
/home/oracle/bin/refresh-adb-db-token \
>> /home/oracle/.oci/db-token/refresh.log 2>&1'
5. Create a Cluster-Targeted WebLogic Data Source
The data source does not set a database user or password. The Thin URL resolves the token-enabled alias and oracle.net.tns_admin identifies the wallet.
This online WLST example creates and targets a Generic Data Source to a cluster. Store WebLogic administrator credentials in environment variables, not in the script:
from java.lang import String
from jarray import array
from weblogic.management.configuration import TargetMBean
import os
admin_url = 't3s://<admin_host>:<admin_port>'
cluster_name = '<cluster_name>'
data_source_name = 'HelloAppDataSource'
wallet_dir = '/u01/app/oracle/adb-wallet/<adb_name>'
connect(os.environ['WLS_USER'], os.environ['WLS_PWD'], admin_url)
edit()
startEdit()
if getMBean('/JDBCSystemResources/' + data_source_name) is None:
jdbc = cmo.createJDBCSystemResource(data_source_name)
resource = jdbc.getJDBCResource()
resource.setName(data_source_name)
driver = resource.getJDBCDriverParams()
driver.setDriverName('oracle.jdbc.OracleDriver')
driver.setUrl('jdbc:oracle:thin:@<adb_iam_low>')
driver.getProperties().createProperty('oracle.net.tns_admin').setValue(wallet_dir)
resource.getJDBCDataSourceParams().setJNDINames(
array(['jdbc/HelloAppDataSource'], String))
jdbc.setTargets(array([getMBean('/Clusters/' + cluster_name)], TargetMBean))
save()
activate(block='true')
disconnect()
exit()
Run it with the domain WLST installation:
export WLS_USER=<weblogic_administrator>
export WLS_PWD=<weblogic_administrator_password>
<middleware_home>/oracle_common/common/bin/wlst.sh configure_datasource.py
The ATP Database use with WebLogic Server article also uses the TNS alias plus oracle.net.tns_admin pattern. The important difference here is that this data source does not provide a database password. TOKEN_AUTH=OCI_TOKEN directs the JDBC driver to the token files.
6. Use the Data Source from a Web Application
For a Java EE web application, declare a resource reference in WEB-INF/web.xml:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0">
<resource-ref>
<res-ref-name>jdbc/HelloAppDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Map it to the global WebLogic JNDI name in WEB-INF/weblogic.xml:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
<resource-description>
<res-ref-name>jdbc/HelloAppDataSource</res-ref-name>
<jndi-name>jdbc/HelloAppDataSource</jndi-name>
</resource-description>
</weblogic-web-app>
The application uses a normal JNDI lookup:
DataSource dataSource = (DataSource) new InitialContext()
.lookup("java:comp/env/jdbc/HelloAppDataSource");
try (Connection connection = dataSource.getConnection()) {
// Use the connection normally.
}
Deploy the application to the cluster rather than to one managed server.
The datasource configuration is the same for Jakarta EE applications, but use the Jakarta APIs and deployment descriptors appropriate to the WebLogic Server release and application framework. The IAM token configuration remains outside the application code.
7. Verify the End-to-End Connection
Confirm the host can create a fresh token:
sudo -u oracle /home/oracle/bin/oci iam db-token get --profile <oci_profile>
Test the application through its load balancer:
curl -k -X POST \
--data-urlencode 'message=Hello from IAM token authentication' \
https://<load_balancer_ip>/hello-db/hello-db
curl -k https://<load_balancer_ip>/hello-db/hello-db
Verify the identity from a token-authenticated database session:
SELECT
USER,
SYS_CONTEXT('USERENV', 'AUTHENTICATED_IDENTITY') AS authenticated_identity,
SYS_CONTEXT('USERENV', 'AUTHENTICATION_METHOD') AS authentication_method
FROM dual;
For the group mapping in this article, USER is the global database user, AUTHENTICATED_IDENTITY is the IAM user, and AUTHENTICATION_METHOD is TOKEN_GLOBAL.
Troubleshooting
ORA-01017: invalid credential or not authorized
Check that:
- identity_provider_type is OCI_IAM.
- The IAM user belongs to the mapped group.
- The global database user has the correct IAM_GROUP_NAME value.
- The TNS descriptor contains TOKEN_AUTH=OCI_TOKEN.
- The token and oci_db_key.pem exist under ~/.oci/db-token and are owned by the WebLogic operating-system account.
OCI CLI returns NotAuthorizedOrNotFound
The IAM principal needs a policy that allows use of database connections. Check the policy scope and confirm that the public API key is uploaded to the IAM user.
The application fails after about one hour
The token expired or the refresh job did not run. A fresh physical JDBC connection made after expiry fails with ORA-25708. Existing connections already borrowed from the WebLogic pool can remain usable until the pool needs to create or replace a physical connection, so use a fresh-connection test to validate the refresh behavior. Check:
sudo -u oracle tail -n 50 /home/oracle/.oci/db-token/refresh.log
sudo systemctl status crond
sudo cat /etc/cron.d/adb-db-token-refresh
A standalone JDBC test reports an SSO or wallet keystore error
When testing outside WebLogic, include the JDBC driver and wallet/PKI libraries, such as oraclepki.jar, osdt_core.jar, and osdt_cert.jar, on the test class path. Validate the WebLogic data source as the authoritative application test.
Summary
WebLogic Server can use an Autonomous Database data source without storing a database password in the data source definition, provided it uses a compatible Oracle JDBC Thin driver. The key pieces are the IAM group-to-global-user mapping, a token-enabled TNS alias, OCI CLI running under the WebLogic OS account, and a reliable token refresh job on every host that can service the application. The application continues to use a standard data source; the IAM token details remain outside application code.
