![](/img/trans.png)
[英]Oracle - ORA-06502: PL/SQL: numeric or value error (DBMS_OUTPUT)
[英]Oracle DBMS_LDAP.open_ssl in PL/SQL shows error: ORA-31202: SSL handshake failed
我們已經切換到新的 Microsoft ADFS 服務器,現在我們必須使用 LDAPS(端口 636 上的 LDAP over SSL)。 但是在 PL/SQL 包中通過添加 DBMS_LDAP.open_ssl(基於這里)我得到:
ORA-31202: DBMS_LDAP: LDAP client/server error: SSL handshake failed
我的故障排除指導我對連接進行 tcpdump 調試,我發現 Oracle (12.1.0.2) DBMS_LDAP 在 SSL 握手時僅使用以下三個密碼套件,這些套件都非常舊且不安全,並且不受最新的 Microsoft AD 支持。 甚至我用 ldap.google.com:636 嘗試了另一個 12c db (12.1.0.2.0) 並收到相同的錯誤和相同的密碼套件。
Version: TLS 1.2 (0x0303)
Cipher Suite: TLS_DH_anon_WITH_3DES_EDE_CBC_SHA (0x001b)
Cipher Suite: TLS_DH_anon_WITH_RC4_128_MD5 (0x0018)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Oracle 知識表明很多人都遇到過這個問題(Doc ID 19285025.8,Doc ID 1561121.1),唯一的建議是補丁“19285025”。 我們已經完成了這個補丁,但仍然沒有進展。 我們找到了 Oracle 文檔( 這里)來展示如何在“netmagr”的幫助下配置安全套接字層和添加密碼套件,但最終我知道這僅適用於 oracle DB 連接,但它沒有影響。 現在的問題是? 1. 如何解決 DBMS_LDAP.open_ssl 的“SSL 握手失敗”? 我們如何為 DBMS_LDAP.open_ssl 設置不同的密碼套件? 2. 任何使用 LDAPS 的替代 PL/SQL 包? 或者我們必須使用Java包並將其加載到數據庫中?
我已切換到java過程而不是Oracle DBMS_LDAP。 它運行良好,沒有SSL問題(除了擴展它的java的力量)。
SET SERVEROUTPUT ON SIZE 5000;
CALL dbms_java.set_output(5000);
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED LDAP AS
import javax.naming.*;
import javax.naming.directory.*;
import java.util.Hashtable;
/**
* Java LDAP Package by ATK, 9/9/2016
*/
class ldap {
public static int ldap_auth(String username, String my_password, String ldap_server) {
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldap_server ); //example "ldap://ldap.yourcompany.com:636"
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=" + username + ",OU=users,DC=company,DC=com");
env.put(Context.SECURITY_CREDENTIALS, my_password);
try {
// Create initial context
DirContext ctx = new InitialDirContext(env);
System.out.println("Connection Successful.");
ctx.close();
return 0;
} catch (NamingException e) {
System.out.println("LDAP Connection: FAILED");
e.printStackTrace();
return -1;
}
}
};
--show errors java source ldap ; -- to check class compile
CREATE OR REPLACE FUNCTION ldap_auth (username in varchar2, my_password in varchar2, ldap_server in varchar2) RETURN NUMBER
AS LANGUAGE JAVA
NAME 'ldap.ldap_auth (java.lang.String, java.lang.String, java.lang.String) return int';
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldap.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldapqa.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldapdev.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.53:636', 'connect,resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.54:636', 'connect,resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.55:636', 'connect,resolve' );
現在你可以測試它:
SET SERVEROUTPUT ON SIZE 5000
CALL dbms_java.set_output(0);
declare
l_ret int ;
begin
l_ret := ldap_auth ('myUser', 'myPassword', 'ldap://lds.companyDomain.com:636');
DBMS_OUTPUT.put_line('Return = ' || l_ret );
end;
我很欣賞這是一篇舊帖子,但作為參考,事實證明 DBMS_LDAP 宣傳的密碼套件取決於open_ssl函數的sslauth
參數。
當sslauth
設置為1
(無身份驗證)時,只會TLS_DH_anon_xxx
密碼套件。 當使用2
或3
(1 或 2 路身份驗證)時,所有密碼套件都將被廣告(OCI 中的 vanilla 19c ATP 數據庫中的 25 個套件)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.