必须先查 os_authent_prefix 参数值再创建用户:若为 ops$(默认)则需建 ops$alice,若为空字符串则直建 alice;参数修改后须重启数据库才生效,且仅支持 sqlplus / 本地连接。

查 os_authent_prefix 再动手,别直接写 CREATE USER
CREATE USER ops$alice IDENTIFIED EXTERNALLY; 报 ORA-01994?八成是 os_authent_prefix 没对上。它不是开关,而是拼接规则:Oracle 拿到系统登录名(比如 alice)后,会自动加这个前缀再去数据库里找用户。
先执行:SHOW PARAMETER os_authent_prefix
- 如果值是
ops$(默认)或其它非空字符串(如xx$),你必须建带前缀的用户:CREATE USER ops$alice IDENTIFIED EXTERNALLY; - 如果值是空字符串(
''),说明前缀已禁用,可直用系统名:CREATE USER alice IDENTIFIED EXTERNALLY;
改参数必须重启:ALTER SYSTEM SET os_authent_prefix='' SCOPE=SPFILE;,改完不重启等于没改。
Linux/Unix 下用户名必须严格匹配 getlogin() 返回值
Oracle 不会“猜”你的系统用户名——它调用 getlogin() 拿到什么,就去数据库里查什么。比如你当前 OS 用户是 alice,但 os_authent_prefix 是 ops$,那它只认 ops$alice,alice 这个用户根本不会被匹配。
- 确认当前 OS 用户:
id或whoami - Oracle 启动用户(通常是
oracle)必须有权限读/etc/passwd或接入 PAM/LDAP,否则第一步就失败 - 建完用户立刻授权:
GRANT CREATE SESSION TO ops$alice;,否则连sqlplus /都进不去
Windows 域用户要显式带 DOMAINuser 格式,且前缀通常得清空
Windows 返回的登录名是 MISdragon 这种格式。如果 os_authent_prefix 是默认 ops$,Oracle 会去查 ops$MISdragon —— 这既非法(含反斜杠)、又超长,必然失败。
- 正确做法:把前缀设为空:
ALTER SYSTEM SET os_authent_prefix='' SCOPE=SPFILE;,再重启 - 建用户时用双反斜杠转义:
CREATE USER "MIS\dragon" IDENTIFIED EXTERNALLY; - 连接必须是本地、且当前 Windows 登录就是
MISdragon:sqlplus /@ORCL - SQL Developer 或 JDBC 远程连接走的是 TCP/IP 协议,默认绕过 OS 认证,一定报 ORA-01017
连接方式错了,一切白搭:只能用 sqlplus /,不能带用户名
sqlplus alice@ORCL 永远失败,哪怕用户存在、权限齐全。因为带用户名的连接触发 Oracle 密码校验流程,而 IDENTIFIED EXTERNALLY 用户根本没有密码。
- 唯一合法连接方式:
sqlplus /@ORCL(本地 IPC 或 Unix 域套接字) - Oracle 此时才调用系统接口拿当前 UID/GID,再按
os_authent_prefix规则拼出用户名去匹配 - tnsnames.ora 里别加
SERVER=SHARED或其他特殊配置,否则可能跳过本地认证路径
最易被忽略的点:外部认证不是“免密登录”,而是把验证权完全交给操作系统——这意味着它天然绑定本地环境、大小写敏感、依赖系统级权限配置,任何一环断开,错误都发生在底层,不会提示具体哪步错了。











