ORA-28001 根本原因是用户 expiry_date 已过期,与连接参数或驱动无关;需 DBA 执行 ALTER USER ... IDENTIFIED BY 重置密码以清除过期状态,仅解锁或改 profile 无效。
ORA-28001 报错的本质原因
这不是连接参数写错了,也不是 jdbc 驱动版本问题,而是 oracle 数据库在用户级持久化地记录了过期状态:expiry_date 字段已落在过去时间。哪怕你刚把 password_life_time 改成 unlimited,这个字段也不会自动更新——dba 常误以为“改了 profile 就万事大吉”,结果用户照样登不进去。
验证方法很简单:SELECT username, expiry_date, account_status FROM dba_users WHERE username = 'YOUR_USER';
如果 expiry_date 是个过去的日期(比如 2026-02-15 00:00:00),而当前是 2026-03-19,那这就是根源。
必须用 DBA 权限执行的修复操作
普通用户连登录都失败时,只能靠 DBA 登录后直接重置。注意:不是“解锁”就够了,必须显式重置密码或触发过期状态重置。
-
ALTER USER your_user IDENTIFIED BY new_password;—— 最直接,密码和过期状态一并清除 -
ALTER USER your_user PASSWORD EXPIRE;—— 不改密码,但强制下次登录时必须改;适合想保留原密码但绕过当前阻塞的场景 -
ALTER USER your_user ACCOUNT UNLOCK;—— 仅当account_status显示EXPIRED(GRACE)或LOCKED时才需要加这句,但单独执行无效
别用 identified by old_password 试图“恢复旧密码”——Oracle 不允许用旧密码绕过过期校验,会报 ORA-28007: password cannot be reused(如果启用了密码历史策略)。
profile 修改只影响未来,不修复历史过期
想一劳永逸?可以改默认策略,但得清楚它的作用边界:
-
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;—— 之后新建的用户、以及尚未触发过期的用户,不再受 180 天限制 - 但所有
expiry_date已过期的用户,仍需逐个执行ALTER USER ... IDENTIFIED BY才能恢复 - 生产环境慎用
UNLIMITED;更稳妥的是设为180或90,再配合定期巡检脚本自动提醒
查当前策略:SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_LIFE_TIME';
JDBC 连接报 ORA-28001 的特别处理
Java 应用启动就崩,不是代码问题,是连接池预检失败。常见于 Spring Boot + HikariCP 场景:
- 错误日志里一定含
java.sql.SQLException: ORA-28001: the password has expired - 别急着改
application.yml里的密码——先确认数据库侧用户是否真已修复 - 改完 DBA 操作后,务必重启应用(连接池缓存了失败连接,不会自动重试新密码)
- 若用 Oracle Wallet 管理凭据,记得同步更新 wallet 内的凭证,否则照样报错
真正容易被忽略的点:有些 DBA 修完用户密码,忘了检查 account_status 是否仍是 EXPIRED(GRACE)——这种状态虽然能登录,但 3 次内不改密就会锁死,得补一句 ALTER USER ... IDENTIFIED BY 才算彻底闭环。










