使用IAM令牌认证无钱包连接Oracle Autonomous Database 23ai失败(ORA-12529错误)
看起来你在尝试用实例主体认证+无钱包TLS方式连接Oracle ADW 23ai时碰了壁,遇到了ORA-12529这个“连接请求被过滤规则拒绝”的错误。我帮你梳理几个最可能的排查方向,结合你的代码来分析:
先明确错误根源
ORA-12529本质是数据库的TNS listener拒绝了你的连接请求,通常和权限配置、令牌有效性、连接参数、网络规则这几类问题有关,咱们一个个来排查:
1. 确认ADW是否开启了IAM数据库认证
这是最基础的前提——如果你的ADW实例没开启IAM认证,所有令牌连接都会被直接拒绝。你可以登录OCI控制台,找到目标ADW实例的「数据库设置」页面,检查「IAM数据库认证」选项是否处于启用状态。如果没开,先把这个开关打开,等待配置生效后再试。
2. 检查IAM令牌的范围是否准确
你的代码里用了通配符范围"urn:oracle:db::id::*",虽然理论上通配符可以匹配所有数据库,但很多租户的权限策略会限制通配符的使用,建议换成目标ADW的具体OCID试试,格式是:
.scope("urn:oracle:db::id:<你的ADW实例OCID>")
你可以在ADW实例的详情页复制到这个OCID,替换后重新生成令牌。
3. 核对实例主体的权限策略
你的OCI实例需要有连接ADW的权限,确保动态组和策略配置正确:
- 首先,动态组要正确包含你的应用所在实例(比如通过实例OCID或标签匹配);
- 然后,在OCI策略里添加类似这样的规则:
这个策略要明确授权实例主体可以访问目标ADW。allow dynamic-group <你的动态组名称> to use autonomous-databases in compartment <你的 compartment 名称> where target.resource.id = '<ADW实例OCID>'
4. 修正JDBC URL的关键参数
你的代码里有两个可能的JDBC配置问题:
- 端口错误:ADW的TCPS默认端口是
1522,而不是1521!你的代码里如果默认用1521,或者连接字符串里的端口不对,会直接导致连接被拒绝。建议在buildJdbcUrl方法里明确指定1522端口:return String.format( "jdbc:oracle:thin:@(description=(retry_count=20)(retry_delay=3)" + "(address=(protocol=tcps)(host=%s)(port=%s))" + "(connect_data=(service_name=%s))" + "(security=(ssl_server_dn_match=no)))", host, "1522", serviceName ); - 驱动版本兼容性:确保你用的Oracle JDBC驱动版本是19.13及以上(JDK17推荐用ojdbc11,对应23ai的最新驱动版本),旧版本不支持无钱包的IAM令牌连接。
5. 检查代码里的令牌参数配置
你的代码里写了props.put(OracleConnection.CONNECTION_PROPERTY_TOKEN_AUTHENTICATION, "OCI_TOKEN");——这里的"是HTML转义字符,实际代码里应该用普通的双引号"OCI_TOKEN",如果代码里真的保留了转义字符,会导致参数识别错误,直接修正成:
props.put(OracleConnection.CONNECTION_PROPERTY_TOKEN_AUTHENTICATION, "OCI_TOKEN");
另外,可以在代码里加日志,打印生成的公钥PEM和获取到的令牌内容(注意不要泄露敏感信息),确认公钥格式标准、令牌是有效的JWT(可以用JWT解码工具查看声明是否正确)。
6. 排查网络安全规则
最后,确保你的应用所在OCI实例的安全组允许出站访问ADW的1522端口,同时ADW所在VCN的安全规则也要允许来自实例的入站连接。如果有防火墙或NACL限制,也会导致连接被拒绝。
总结排查顺序
我建议你按照这个优先级来排查:
- 确认ADW的IAM认证已开启;
- 修正JDBC URL的端口为1522;
- 替换令牌范围为具体ADW OCID;
- 检查实例主体的权限策略;
- 修正代码里的参数转义问题;
- 核对网络安全规则。
内容来源于stack exchange

