Oracle 12c移行後に発生する「ORA-28040」を回避する方法
Oracle 12c移行後に発生する「ORA-28040」を回避する方法です。
ORA-28040: No matching authentication protocol
ORA-28040: 一致する認証プロトコルがありません
先日、Oracle 12c(12.2)への移行案件を対応しました。Webアプリで使われているデータベースで、Oracle 11gからの移行となります。
新環境の構築にあたり、sqlplusで接続して作業している時には問題はありませんでした。ところが、Webアプリを起動したところ「ORA-28040」が発生し、接続ができませんでした。
どうもOracle 12c以降、低いバージョンのOracleクライアント(JDBC ThinおよびOCIを含む)では接続できないようです。
Webアプリ自体は非常に古いもので、初期構築から10年以上が経過しています。JDBCドライバは、ojdbc14.jarを利用していました。バージョンが古いと接続できないのかと思い、ojdbc8.jarを導入してもNGでした。おそらくラップしているフレームワークが新しい認証方法に対応していないからじゃないかと推測しました。
ここでは Oracle 12c移行後に発生する「ORA-28040」を回避する方法 を紹介します。
同様の現象はOracle 19cへの移行でも発生しています。
目次
ORA-28040が発生する原因
まず、ORA-28040が発生する原因を抑えておきましょう。
Oracle 12c(12.2)では、低いバージョンのOracleクライアントから接続した場合、認証プロトコルでエラーとなりORA-28040が発生します。これは、ojdbc14.jarなど、古いOracle JDBCドライバを使用しているときにも同じエラーが発生します。
ORA-28040の解決策
ORA-28040の解決策は、sqlnet.oraの「SQLNET.ALLOWED_LOGON_VERSION_SERVER」と「SQLNET.ALLOWED_LOGON_VERSION_CLIENT」のパラメータの値を、システムでサポートされている最小バージョンのソフトウェアと一致する値に設定することで解決できます。
また、Java側での解決も可能です。プロパティ「oracle.jdbc.allowedLogonVersion」を設定して、JDBC Thinドライバーの使⽤時にクライアントが必要とする最⼩限の認証プロトコルを構成できます。
SQLNET.ALLOWED_LOGON_VERSION_SERVERとは?
「SQLNET.ALLOWED_LOGON_VERSION_SERVER」とは、簡単にいえば「接続時の認証強度を強くしたり弱くしたりできるパラメータ」といったところです。JDBC ThinおよびOCIを含むクライアントからの接続に適⽤されます。
Oracle公式サイトには下記のような記載がありました。
Oracle Databaseインスタンスへの接続時に認められる最低限の認証プロトコルを設定します。
docs.oracle.com
「SQLNET.ALLOWED_LOGON_VERSION_SERVER」で設定できるパラメータは「6種類」です。
パスワード バージョン | 説明 |
---|---|
12a | Oracle Database 12cリリース12.1.0.2以上の認証プロトコル(最も強力な保護) |
12 | Oracle Database 12c リリース12.1の認証プロトコル(デフォルトおよび推奨値) |
11 | Oracle Database 11gの認証プロトコル |
10 | Oracle Database 10gの認証プロトコル |
9 | Oracle9i Databaseの認証プロトコルの場合 |
8 | Oracle8i Databaseの認証プロトコルの場合 |
今回は「sqlnet.ora」へ下記の修正をすることで解決できました。
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
こうすることにより、すべてのパスワード・バージョンが認められます。
SQLNET.ALLOWED_LOGON_VERSION_CLIENTとは?
「SQLNET.ALLOWED_LOGON_VERSION_CLIENT」とは、簡単にいえば「データベースリンク接続時の認証強度を強くしたり弱くしたりできるパラメータ」といったところです。OCIクライアントにのみ影響されます。
Oracle公式サイトには下記のような記載がありました。
Oracle Databaseインスタンスへの接続時に、サーバーがクライアントの役割を果している場合(データベース・リンクでの接続など)に、クライアントに認められる最低限の認証プロトコルを設定します。
docs.oracle.com
プロパティ「oracle.jdbc.allowedLogonVersion」を設定する方法
下記のコードで検証ができます。JDK8が必要です。
OracleDataSource ods = new OracleDataSource();
ods.setURL(jdbcURL);
ods.setUser("<USERNAME>");
ods.setPassword("<PASSWORD>");
Properties props = new Properties();
props.put("oracle.jdbc.allowedLogonVersion", 12);
ods.setConnectionProperties(props);
Connection con = ods.getConnection();
値は「SQLNET.ALLOWED_LOGON_VERSION_CLIENT」と同じで、12a、12、11などにすることができます。 このプロパティはバージョン12.1で導⼊されました。
この方法は、フレームワークを使ったWebアプリだと現実的ではないかなーっと思っています。
設定したパラメータ
今回のOracle 12c移行では、Webアプリの構成が古いというのと、古いOracleからのDBリンクも多用しているシステムであることから、結局下記を設定しました。
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
うーん、せっかくの機能を使いきれないのは残念・・・。
まとめ
Oracle 12c移行後に発生する「ORA-28040」を回避する方法を紹介しました。
認証強化は大切ですが、これによりアプリケーションが動かなくなっては本末転倒ですね。パラメータ設定時は十分に検証してからおこなう必要があると共に、アプリケーション側の改善も常におこなっていくことが重要だなと感じました。
この記事が同様のトラブルに悩んでいる方のお役に立てればうれしいですね。
おつかれさまでした。