ORA-01017是Oracle服务端明确拒绝认证,非连接问题,根源在凭据(大小写/BOM/空格/引号)、账户状态(LOCKED/EXPIRED)、权限(CREATE SESSION缺失)、PDB服务名错误或SQLNET协议不兼容。

ORA-01017 不是连接不通,而是 Oracle 服务端明确拒绝了认证——TCP 已通,问题一定出在凭据、状态或协议层。盲目重置密码或改防火墙没用。
确认 SEC_CASE_SENSITIVE_LOGON 是否为 TRUE
Oracle 11g 起默认开启密码大小写敏感,SEC_CASE_SENSITIVE_LOGON = TRUE 意味着:用户名不加双引号时自动转大写(User Id=abc 实际查的是 ABC),密码必须字节级完全一致——大小写、空格、BOM、末尾换行符全算。
- 用
SHOW PARAMETER sec_case_sensitive_logon查当前值;返回TRUE就是它在作祟 - Windows 下从记事本或邮件复制密码,极易带 UTF-8 BOM 或隐藏换行,
sqlplus看不出,但Oracle.ManagedDataAccess会严格传入并比对失败 - 临时验证可执行:
ALTER SYSTEM SET sec_case_sensitive_logon = FALSE SCOPE=BOTH,再立即重设一次密码(哪怕内容不变):ALTER USER scott IDENTIFIED BY "TiGeR@123"
检查 .NET 或 Java 连接字符串中的引号与转义
Oracle.ManagedDataAccess 和 ojdbc8 对引号极其敏感,错一处就导致凭据被截断或标准化,最终送进数据库的密码根本不是你写的那个。
- 用户名含小写字母或下划线?必须加英文双引号:
User Id="my_user",否则 Oracle 当作MY_USER - 密码含
@、/、:、$等字符?必须用英文双引号包裹:Password="Pass@123" - C# 普通字符串里反斜杠要双写:
Password="pass\word";更稳妥用逐字字符串:@'User Id=scott; Password="TiGeR@123"; Data Source=orcl;' - 从
appsettings.json或环境变量读取?务必调用.Trim(),尤其 Windows 配置文件易带 BOM 或尾部空格
排查账户状态与 CREATE SESSION 权限缺失
Oracle 在认证流程中统一返回 ORA-01017,即使真实原因是账户锁死、过期或缺少 CREATE SESSION 权限——它不会告诉你“账号被锁”,只说“凭据无效”。
- 用
sqlplus / as sysdba登录后查:SELECT username, account_status, expiry_date FROM dba_users WHERE username = 'SCOTT' - 若状态为
LOCKED:ALTER USER scott ACCOUNT UNLOCK;若为EXPIRED & LOCKED,直接ALTER USER scott IDENTIFIED BY "newpass" ACCOUNT UNLOCK - 确认权限:
SELECT * FROM dba_sys_privs WHERE grantee = 'SCOTT' AND privilege = 'CREATE SESSION';缺失则补:GRANT CREATE SESSION TO scott - Oracle 12c+ 注意 PDB:确保连接串指向的是 PDB 服务名(如
orclpdb),而非 CDB root
验证客户端与服务端协议兼容性(SQLNET.ALLOWED_LOGON_VERSION_SERVER)
从 Oracle 12.2 开始,旧版客户端(如 12.1c)可能因密码哈希协议不匹配,在认证阶段就被拒绝,表现为 ORA-01017。
- 检查服务端
$ORACLE_HOME/network/admin/sqlnet.ora是否设置了SQLNET.ALLOWED_LOGON_VERSION_SERVER - 若客户端较老(如 11g/12.1),需设为兼容值:
SQLNET.ALLOWED_LOGON_VERSION_SERVER=10或11 - 修改后必须重启监听:
lsnrctl stop && lsnrctl start - 设置后建议重设用户密码,确保新哈希按兼容协议生成
最常被忽略的是:密码本身没错,但传输过程中被引号、BOM、空格或协议协商悄悄改写了。验证时永远优先用 sqlplus 命令行直连,绕过所有中间层干扰——这是定位真因的唯一可靠起点。


















