必须显式授予create session权限,否则java应用无法建立连接;grant select any table on schema hr to bob仅控制可查对象范围,不替代登录能力,漏授前者会导致ora-01031错误。
不能靠 grant select any table on schema 代替连接权限,java 应用连都连不上,更别提查表。
ORA-01031 报错根本不是权限没给全,而是连会话都没建起来
常见现象是 Spring Boot 启动报 ORA-01031: insufficient privileges,日志里还看到 JDBC 连接失败。这时候翻来覆去检查 GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB 是白忙——这条只管“能查什么”,不管“能不能登录”。
必须显式执行:
-
GRANT CREATE SESSION TO BOB(推荐,最小权限) - 或
GRANT CONNECT TO BOB(23c 中CONNECT角色已降权,等价于只含CREATE SESSION,但语义不如前者清晰)
漏掉这一条,spring.datasource.username=BOB 就永远卡在认证阶段,授权再细也没用。
SELECT ANY TABLE ON SCHEMA 和旧版 SELECT ANY TABLE 的区别必须分清
旧方式 GRANT SELECT ANY TABLE TO BOB 是全局穿透的:BOB 能查 HR.EMPLOYEES、FINANCE.TRANSACTIONS、甚至 SYS.OBJ$——完全违背最小权限原则。
而 GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB 是严格边界控制的:
- 只覆盖
HR下当前及未来新建的表、视图(不含物化视图、序列、过程等) - 不自动赋予
INSERT/UPDATE/DELETE权限;23c 当前也不支持INSERT ANY TABLE ON SCHEMA - 若需跨多个 schema(如 HR + FINANCE),必须分别授权:
GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB和GRANT SELECT ANY TABLE ON SCHEMA FINANCE TO BOB
Java 应用查不到新表?先排除这三类低级干扰
Schema 级权限本应自动生效,但实际开发中常因以下原因“查不到”:
- SQL 写成
SELECT * FROM EMPLOYEES(没带 schema 前缀),而当前 session 的current_schema不是 HR ——Oracle 默认不会跨 schema 搜索,必须写成SELECT * FROM HR.EMPLOYEES - 应用层用了二级缓存(如 MyBatis 的
cache-ref或 Hibernate 的二级缓存),缓存了旧的元数据或空结果集,重启应用或清缓存即可 - 刚授完权就立刻查,但 Oracle 的权限生效有极短延迟(通常毫秒级),极少情况需手动刷新 shared pool:
ALTER SYSTEM FLUSH SHARED_POOL(生产环境慎用)
Spring Boot 多 schema 场景下,别碰默认 schema 切换
有人试图在 application.yml 里配 spring.datasource.schema=HR 或用 ALTER SESSION SET CURRENT_SCHEMA = HR,这是危险操作:
- 连接池中连接复用时,
CURRENT_SCHEMA状态不可控,可能污染后续请求 - 权限模型仍以登录用户(如 BOB)为准,切换
CURRENT_SCHEMA不改变其可访问对象范围 - 正确做法是 SQL 中显式写
HR.EMPLOYEES,配合GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB,权限与访问路径一一对应,无歧义
真正容易被忽略的是:Schema 级权限只解决“查哪些表”,不解决“怎么查得安全”。如果 HR 下有敏感字段(如 SALARY),还得叠加 DBMS_REDACT 动态脱敏策略,否则权限再细,数据照样裸奔。











