ora-01017是认证失败而非连接失败,问题必在凭据传递或服务端校验环节;需检查.net连接字符串引号/转义、sec_case_sensitive_logon设置、账户状态与create session权限、pdb服务名匹配及驱动版本兼容性。
ora-01017 不是连接失败,而是连接已通、认证被拒——.net 程序能走到这一步,说明网络、监听器、tns 解析全都没问题,问题一定出在凭据传递或服务端校验环节。
检查 .NET 连接字符串里的 Password 是否被截断或标准化
Oracle.ManagedDataAccess 对引号和转义极其敏感,不加或错加双引号会导致密码字段被提前截断或空格/大小写被抹平:
- 密码含
@、/、:、$、%等字符时,必须用英文双引号包裹:Password="MyP@ss!2024"; - C# 普通字符串中反斜杠需双写:
Password="pass\word";;更稳妥用逐字字符串:@'User Id=scott; Password="MyP@ss!2024"; Data Source=orcl;' - 从
appsettings.json或环境变量读取时,务必调用.Trim()——Windows 上 UTF-8 BOM 和末尾换行符常被忽略,但 Oracle 会严格比对字节 - 用户名含小写字母或下划线?必须加双引号:
User Id="my_user";,否则 Oracle 按MY_USER查找
确认 SEC_CASE_SENSITIVE_LOGON 是否为 TRUE
Oracle 12c+ 默认开启密码大小写敏感,而 .NET 驱动不会做任何兼容性转换,直接传原始字节给服务端比对:
- 执行
SHOW PARAMETER sec_case_sensitive_logon;,若返回TRUE,则Password="tiger"和Password="Tiger"是两个完全不同的凭证 - 用 SQL*Plus 在应用服务器本机验证:
sqlplus "scott/Tiger@orcl"(带双引号) vssqlplus scott/tiger@orcl(不带)——前者成功后者失败,基本锁定该问题 - 临时关闭验证仅用于定位:
ALTER SYSTEM SET sec_case_sensitive_logon = FALSE SCOPE=BOTH;,执行后无需重启,新连接立即生效 - 关闭后建议重设一次密码:
ALTER USER scott IDENTIFIED BY "Tiger";,避免旧哈希与新策略不兼容
排查账户状态和权限是否“伪装”成密码错误
Oracle 在认证链末端统一返回 ORA-01017,不区分真实原因。即使密码完全正确,以下情况也会触发该错误:
- 账户状态非
OPEN:查SELECT username, account_status FROM dba_users WHERE username = 'SCOTT';,若为EXPIRED & LOCKED或LOCKED(TIMED),需执行ALTER USER scott ACCOUNT UNLOCK;和重置密码 - 缺少
CREATE SESSION权限:新建用户后常遗漏此步,查SELECT privilege FROM dba_sys_privs WHERE grantee = 'SCOTT';,缺失则补授:GRANT CREATE SESSION TO scott; - 连接池复用坏连接:默认开启连接池,首次认证失败的连接句柄可能被缓存复用,后续
Open()仍报 ORA-01017;临时加Pooling=false; Connection Timeout=5;可隔离问题
验证 PDB 服务名是否匹配且驱动版本兼容
12c+ 多租户环境下,连错容器或驱动协议不匹配,也会表现为 ORA-01017:
- 确认 TNSNAMES.ORA 中的服务名指向的是 PDB(如
PDBORCL),而非 CDB$ROOT;用lsnrctl status查当前注册的服务列表 - JDBC URL 必须用
//host:port/service_name格式(如jdbc:oracle:thin:@//db:1521/pdborcl),不能用:SID格式(如@db:1521:orcl) - .NET 应用若用 Oracle.ManagedDataAccess,必须匹配服务端版本:Oracle 19c/21c 要求至少 v21.x 驱动;旧版驱动(如 v19.10)无法完成 12c+ 密码哈希协商,即使密码一字不差也退回到 ORA-01017
- 检查项目中是否混入多个驱动版本(尤其 NuGet 和 GAC 同时存在),优先保留最新版并清理旧引用
最易被忽略的是:密码本身没错,但传给 Oracle 的那一串字节,因引号缺失、BOM 干扰、大小写策略错配或驱动协议降级,已经不是数据库里存的那个值了。验证必须回归到 SQL*Plus 命令行——它绕过所有中间层,是最接近 Oracle 认证引擎的真实信道。











