升级到 Oracle 19c 后,不少团队会遇到一个棘手的登录故障:直接设置 sec_case_sensitive_logon=false,结果几乎所有用户登录都报 ORA-01017 错误。很多人第一反应是参数未生效,但真相往往更复杂——这其实是 sec_case_sensitive_logon 与 SQLNET.ALLOWED_LOGON_VERSION_SERVER 之间的一场“隐性冲突”。要彻底解决 Oracle 19c 密码大小写敏感问题,必须同步调低密码协议版本,再重置用户密码,任何一个环节都不能遗漏。

为什么 sec_case_sensitive_logon=false 在 Oracle 19c 里会导致登录被锁死
问题的根源在于 Oracle 19c 的默认密码安全策略。它将 SQLNET.ALLOWED_LOGON_VERSION_SERVER 默认设为 12 或 12a,强制使用 SHA-512 密码哈希(即 12C 密码版本)。而 12C 版本硬性规定:密码必须区分大小写。当你强行关闭 sec_case_sensitive_logon,相当于告诉数据库“忽略大小写”,但底层的密码校验机制依然坚持“必须大小写敏感”,结果是所有密码验证都被拒绝,连 sys 用户都可能无法登录。
建议先检查当前配置状态:
SELECT name, value FROM v$parameter WHERE name IN ('sec_case_sensitive_logon', 'sqlnet.allowed_logon_version_server');
再确认用户密码版本:
SELECT username, password_versions FROM dba_users WHERE username = 'SCOTT';
如果返回值中包含 12C,说明已经陷入“强密码 + 大小写强制”的闭环,单独修改参数无异于隔靴搔痒,无法解决 ORA-01017 问题。
必须同步调整 SQLNET.ORA 中的协议版本
数据库参数调整后还不够,客户端连接时也必须匹配旧的协议版本。编辑数据库服务器端的 $ORACLE_HOME/network/admin/sqlnet.ora,添加这两项:
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8(推荐8,也可用11,但不要使用12)SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
注意:8 表示兼容从 Oracle 8i 开始的旧密码格式(即 10G 版本),它不强制大小写校验;而 11 虽保留部分兼容性,但可能触发 11G 密码版本,带来额外风险。修改后无需重启监听,所有新连接将立即按新规则进行协商。
Profile 的 PASSWORD_VERIFY_FUNCTION 必须清空
即使协议版本已降级,如果用户 profile 中还绑定了 ora12c_strong_verify_function,那么重设密码时仍会强制进行大小写验证。这就像关掉了大门,但后门依然敞开。
先查询用户的 profile:
SELECT profile FROM dba_users WHERE username = 'SCOTT';
然后清空密码验证函数(以 DEFAULT profile 为例):
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION NULL;
这一步如果跳过,后续执行 ALTER USER ... IDENTIFIED BY xxx 时,要么报错,要么悄悄将大小写检查重新激活。
重设密码时严禁使用双引号
这是一个容易被忽略的技术细节。如果升级前创建用户时用了双引号(例如 CREATE USER scott IDENTIFIED BY "Tiger"),那么密码在数据字典中会被标记为“强制大小写”,无论怎么修改参数、profile,都无法绕过这个限制。
安全的重设方式如下(全部小写、不加引号):
ALTER USER scott IDENTIFIED BY tiger;
以下做法是绝对禁止的:
ALTER USER scott IDENTIFIED BY "Tiger";
一旦执行后者,该用户将永久锁定在大小写敏感模式中,只能删除重建,或者接受严格的大小写输入。
最后,务必执行 ALTER SYSTEM FLUSH SHARED_POOL;,清空 PL/SQL 认证缓存,避免旧密码哈希残留引发登录异常。
归根结底,Oracle 19c 关闭密码大小写敏感时出现的 ORA-01017 错误,并非单一参数开关能解决,而是密码版本、协议版本、profile 函数、建库方式这四个要素环环相扣。漏掉其中任意一环,登录失败的问题就会像幽灵一样反复出现。
