代理权限必须由被代理用户主动授予,正确语法为alter user 被代理用户 grant connect through 代理用户;授权后通过proxy_users视图验证,登录时authenticated_identity返回真实认证账号。
代理权限必须由被代理用户主动授予,不是“给谁授权”,而是“谁授权给谁”
很多人卡在第一步:执行 alter user 时语法写反,导致报错 ora-00922: missing or invalid option。关键在于——代理关系的发起方是被代理用户(如应用 schema 用户 zlhis),不是代理用户(如中间层连接池账号 u1118)。
错误写法:ALTER USER U1118 GRANT CONNECT THROUGH ZLHIS(Oracle 直接拒绝解析)
正确写法:ALTER USER ZLHIS GRANT CONNECT THROUGH U1118
- 必须用被代理用户的账号(
ZLHIS)登录后执行该语句,SYS 或 DBA 不能越权代授 - 如果
ZLHIS是schema only账户(无密码、不可直接登录),它仍可执行此授权,前提是已赋予ALTER USER权限 - 授权后立即生效,无需重启实例或刷新缓存
验证代理关系是否生效,只看 PROXY_USERS 视图
PROXY_USERS 是唯一权威来源,它不依赖会话状态,只反映当前有效的代理映射。别查 DBA_USERS 或 ALL_USERS,它们不会显示代理信息。
执行:SELECT * FROM PROXY_USERS WHERE CLIENT = 'U1118' AND PROXY = 'ZLHIS'
- 有结果 → 授权成功;空结果 → 没授权、拼写错误、或已被
REVOKE(注意:撤销也是ALTER USER ZLHIS REVOKE CONNECT THROUGH U1118) -
CLIENT字段是代理用户(真正认证者),PROXY字段是被代理用户(权限归属者) - 视图里没有
ENABLED列——只要行存在,就代表启用中
登录后怎么拿到真实用户名?AUTHENTICATED_IDENTITY 是唯一可信字段
用 U1118[ZLHIS] 方式登录后,USER、SESSION_USER、SYS_CONTEXT('USERENV', 'PROXY_USER') 全部返回 ZLHIS。但审计和业务逻辑常需知道“到底是谁连进来的”。
唯一不可伪造的是:SELECT SYS_CONTEXT('USERENV', 'AUTHENTICATED_IDENTITY') FROM DUAL → 返回 U1118
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
CLIENT_IDENTIFIER默认为空,必须由应用层显式调用setClientIdentifier()(JDBC)或OCIAttrSet()(OCI)设置,否则拿不到 - 不要依赖
OS_USER或HOST,它们在中间层转发场景下已失真 - 如果用了连接池(如 UCP 或 Hikari),确保每次借出连接后都重置
CLIENT_IDENTIFIER,否则可能残留上一个用户的值
代理登录的实际连接字符串怎么写?JDBC 和 sqlplus 差异很大
sqlplus 支持原生代理语法,JDBC 则依赖驱动版本和连接属性,写错就直连失败或静默降级为普通登录。
sqlplus 示例:sqlplus U1118[ZLHIS]/password@db_alias
JDBC URL 示例(Oracle JDBC 19c+):jdbc:oracle:thin:@//host:port/service?proxyClient=U1118&proxyUser=ZLHIS
- JDBC 必须同时传
proxyClient和proxyUser,缺一不可;旧版驱动( - 连接池配置里若设了
connectionInitSql,注意它会在代理身份建立前执行,此时USER还是U1118,不是ZLHIS - tnsnames.ora 中不能对代理连接做 service_name 别名映射,必须用完整地址或 SCAN VIP
代理链路本身不加密,也不校验中间层是否篡改 CLIENT_IDENTIFIER。如果你的应用没走 JDBC 的 setClientIdentifier(),又依赖这个字段做权限判断,那等于把安全控制交给了不可信的中间层。










