ORA-28040|高版本数据库客户端连接问题

1,076 阅读3分钟

大家好,我是 JiekeXu,很高兴又和大家见面了,今天和大家一起聊聊 高版本数据库客户端连接问题,欢迎点击上方蓝字关注我,标星或置顶,更多干货第一时间到达!

前几日通过 ADG 的switchover 模式迁移了一套 19c 的 RAC 环境,迁移后一切正常,主备库均可正常提供服务,备库正常同步,不过为了节省资源,又是测试环境,则将其备库关机回收资源了,大约一周后的时间,有开发的小伙伴找来说他的程序执行报错了,扔来了如下的错误代码。ORA-28040:No matching authentication protocol 没有匹配的认证协议。

2021-06-17 14:44:24.551 ERROR [,,] 7 [,null] --- [Druid-ConnectionPool-Create-1658589699] com.alibaba.druid.pool.DruidDataSource   : create connection SQLException, url: jdbc:oracle:thin:@192.168.221.123:11521/test, errorCode 28040, state 99999
java.sql.SQLExceptionORA-28040No matching authentication protocol
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:283)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:278)
        at oracle.jdbc.driver.T4CTTIoauthenticate.receiveOsesskey(T4CTTIoauthenticate.java:293)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:357)
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)

看到这里就想到了是客户端兼容性设置问题。应该是使用了 11g 的客户端访问 19c 的数据库造成的不兼容性,但我已经在 sqlnet.ora 文件中配置好了如下内容,按理说不会报错了。

在Oracle 19c服务器端的oracle用户下:

cd $ORACLE_HOME/network/admin目录下 新建文件sqlnet.ora

vi sqlnet.ora
SQLNET.ALLOWED_LOGON_VERSION_SERVER=11
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=11

不需重启数据库和监听,新的连接就可以正常连接了。

SQLNET.ALLOWED_LOGON_VERSION_SERVER控制可以连接到19c数据库的客户端版本(client —>oracle 19c db )

SQLNET.ALLOWED_LOGON_VERSION_CLIENT: 控制19c数据库可以连到哪些版本的数据库(oracle 19c db —>其它版本的oracle db),例如:控制通过DB LINK可连接到哪些版本的oracle库。

该参数用来限制可以连接到数据库服务器上的最小客户端版本,比如设置值为10,即10g,11g等以上客户端版本可以连接到数据库服务器上,在不是指的时候是用默认值的,导致低版本连接不上高版本的数据库。

这里说的 8,10,11 版本指的是 dba_users.password_versions 的版本。

所以问题还在于客户端的兼容性,由于开发人员的 jdk 以及 jdbc 驱动版本过低导致,前面由于惯性设置的 11 不能满足需求,故需将其修改为最低版本 8 即可,当把两台 RAC 的 sqlnet.ora 修改为 8 后,开发程序立马可以连接了。

JiekeXu:/u01/app/oracle/product/19.0.0.0/dbhome_1/network/admin(test1)$ more sqlnet.ora
SQLNET.EXPIRE_TIME=1
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8

关于 SQLNET.EXPIRE_TIME=1 参数的说明可以点击查看此文。

今天在一微信群里还看到了有人讨论说使用如下参数 SQLNET.ALLOWED_LOGON_VERSION=8

,但是殊不知,此参数已经在 12c 废弃了,取而代之的是 SQLNET.ALLOWED_LOGON_VERSION_SERVER 和 SQLNET.ALLOWED_LOGON_VERSION_CLIENT

_你有可能看到过这样的解决方案:__在Oracle 12c中d的sqlnet.ora文件添加:_SQLNET.ALLOWED_LOGON_VERSION=8__其实也是可以解决问题的,但由于这个参数在12c已经废弃了,而是用__SQLNET.ALLOWED_LOGON_VERSION_CLIENT__和__SQLNET.ALLOWED_LOGON_VERSION_SERVER__代替。如果继续使用该参数,会在告警日志中无穷无尽的报“ Using deprecated SQLNET.ALLOWED_LOGON_VERSION parameter.”

以前在运维中遇到过开发人员使用 PLSQL 连接数据库报错提示:“登陆失败,登陆信息不正确”或“ORA-28040:没有匹配的验证协议”。

或者 SQLPLUS 登录报错:ORA-28040: No matching authentication protocol,ORA-12162: TNS:net service name is incorrectly specified

这是因为已安装了 Oracle 11g 客户端,配置好环境变量,用 PL/SQL Developer 登录数据库提示出来的,解决方案就是在 Oracle 19c 服务器端 oracle 用户目录下(非 Grid 用户):

cd $ORACLE_HOME/network/admin 目录下 新建文件 sqlnet.ora
vi sqlnet.ora
SQLNET.ALLOWED_LOGON_VERSION_SERVER=10
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=10

然后在服务器端,DBA 身份登录,重新修改密码。

sqlplus / as sysdba

alter session set container=pdb; --如果使用pdb需要切换到pdb修改。

alter user username1 identified by password;

这种情况下配置完服务器端的 sqlnet.ora文件后,务必要重新修改密码,否则仍登录失败,会报密码错误。

最后 附最全客户端支持矩阵

图片.png 好了,今天的文章就到此为止了。如果此文对您有帮助,欢迎点赞、在看与转发,写作不易,举手之劳,便是对我最大的支持,也能让更多的人受益。


参考文档:

Client / Server Interoperability Support Matrix for Different Oracle Versions (Doc ID 207303.1)
After a Database Upgrade to 12c for E-Business Suite, JDeveloper Connections Fail With Error "ORA-28040 no matching authentication protocol" (Doc ID 2125856.1)