如何使用 APEX_LDAP 包在 Oracle Apex 中使用 MEMBER_OF2 函数
How to use the MEMBER_OF2 function in Oracle Apex using the APEX_LDAP package
由于我使用 LDAP 将 Microsoft Active Directory 与我的 Apex 应用程序链接在一起,因此我正在尝试检索当前从 Active Directory 登录的用户的组。
这是文档:https://docs.oracle.com/cd/E59726_01/doc.50/e39149/apex_ldap.htm#AEAPI242
这是我的代码我在页面加载时的动态操作,我正在尝试检索当前用户所属的所有组的 VARCHAR2,并将其放入仅显示字段:
BEGIN
:P1_NEW := APEX_LDAP.MEMBER_OF2(
p_username => v('APP_USER'),
p_pass => 'mypassword',
p_auth_base => 'DOMAIN\',
p_host => 'XX.X.XXX.XX',
p_port => 389);
END;
但是当我加载我的页面时,出现这个错误
Ajax call returned server error ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 for Execute PL/SQL Code.
我的代码有什么问题?预先感谢您的帮助。
托马斯
我认为您使用了错误的 API 包 APEX_LDAP。我在自己的环境中以不同的方式执行此操作,但我使用的是企业版:
- Oracle 数据库版本 19c
- Oracle Apex 版本 20.1
- Oracle Oracle Rest 数据服务版本 20.4
我有一个身份验证模式,可以针对我自己公司的 LDAP 服务器进行登录。该身份验证模式替换了默认的 Apex 本地管理用户。
应用程序 --> 共享组件 --> 身份验证模式 --> 自定义
function fn_val_user_pwd_ldap (
p_username in varchar2,
p_password in varchar2
)
return boolean
is
l_ldap_host varchar2(100) := 'myldaphost.com';
l_ldap_port number := 389 ;
begin
if APEX_LDAP.AUTHENTICATE(
p_username =>p_username,
p_password =>p_password,
p_search_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port)
then
dbms_application_info.set_action(null);
return true;
else
apex_util.set_authentication_result(p_code => 110);
apex_util.set_custom_auth_status(p_status => 'Username or password incorrect.');
dbms_application_info.set_action(null);
return false;
end if;
end;
然后,我使用相同的身份验证方法使用 post 身份验证过程来检索 LDAP 中的组。我更喜欢这种方式,因为它在身份验证后执行,但您也可以使用动态操作来执行。
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => ':APP_USER',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => 'myldaphost.com',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
我们不使用 SSL 与 LDAP 服务器进行内部通信,因为此应用程序是 Intranet。所以参数p_use_ssl
默认为N.
正如我在你自己的问题的评论部分告诉你的,我认为参数p_auth_base指的是你自己的LDAP服务器的LDIF格式,而不是指AD的域名。
更新
让我向您展示它是如何工作的。 (当然,我隐藏了自己公司的敏感信息)。有时可能会出现获取不到组信息为null的情况。我在这里不确定是否是 LDAP 授权问题而不是 APEX 包本身的问题
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED ECHO ON
DECLARE
is_ok boolean;
l_mes varchar2(2000);
l_val varchar2(4000);
l_ldap_host varchar2(100) := 'myldapserver.com';
l_ldap_port number := 389 ;
BEGIN
if APEX_LDAP.AUTHENTICATE(
p_username =>'X329097',
p_password =>'********',
p_search_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port )
then
is_ok := true;
l_mes := 'Username and Password Correct' ;
dbms_output.put_line(l_mes);
else
l_mes := 'Username and Password Invalid' ;
dbms_output.put_line(l_mes);
end if;
if is_ok
then
l_val := APEX_LDAP.MEMBER_OF2(
p_username => 'X329097',
p_pass => '*********',
p_auth_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port);
dbms_output.put_line(l_val);
end if;
END;
/
Username and Password Correct
SC_APEX_ADMIN:SC_ORACLE_ADMIN
PL/SQL procedure successfully completed.
我尝试添加您的功能,但我无法再从登录页面访问我的应用程序。我试过 SQL 命令,这是我得到的
DECLARE
VAL BOOLEAN;
BEGIN
IF APEX_LDAP.AUTHENTICATE(
p_username => 'thomas.tirole',
p_password => 'mypassword',
p_search_base => 'OU=Users,OU=Domain,DC=domain,DC=ch',
p_host => 'xx.x.xxx.xx',
p_port => 389
) THEN
dbms_output.put_line('AUTENTHICATED');
ELSE
DBMS_OUTPUT.PUT_LINE('NOT AUTHENTICATED');
END IF;
END;
---------------------------------------
NOT AUTHENTICATED
Statement processed.
0.00 seconds
如果我尝试在 SQL 命令上执行 MEMBER_OF2 功能,这就是我得到的结果:
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => 'thomas.tirole',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Domain,DC=domain,DC=ch', -- SAME WITH DOMAIN\
p_host => 'xx.x.xxx.xx',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
---------------------------------------
ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 508
ORA-06512: à "SYS.DBMS_SYS_ERROR", ligne 86
ORA-06512: à "SYS.DBMS_LDAP", ligne 1487
ORA-06512: à "SYS.DBMS_LDAP", ligne 79
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 85
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 172
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 214
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 235
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 464
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 523
ORA-06512: à ligne 4
ORA-06512: à "SYS.DBMS_SQL", ligne 1721
由于我使用 LDAP 将 Microsoft Active Directory 与我的 Apex 应用程序链接在一起,因此我正在尝试检索当前从 Active Directory 登录的用户的组。
这是文档:https://docs.oracle.com/cd/E59726_01/doc.50/e39149/apex_ldap.htm#AEAPI242
这是我的代码我在页面加载时的动态操作,我正在尝试检索当前用户所属的所有组的 VARCHAR2,并将其放入仅显示字段:
BEGIN
:P1_NEW := APEX_LDAP.MEMBER_OF2(
p_username => v('APP_USER'),
p_pass => 'mypassword',
p_auth_base => 'DOMAIN\',
p_host => 'XX.X.XXX.XX',
p_port => 389);
END;
但是当我加载我的页面时,出现这个错误
Ajax call returned server error ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 for Execute PL/SQL Code.
我的代码有什么问题?预先感谢您的帮助。
托马斯
我认为您使用了错误的 API 包 APEX_LDAP。我在自己的环境中以不同的方式执行此操作,但我使用的是企业版:
- Oracle 数据库版本 19c
- Oracle Apex 版本 20.1
- Oracle Oracle Rest 数据服务版本 20.4
我有一个身份验证模式,可以针对我自己公司的 LDAP 服务器进行登录。该身份验证模式替换了默认的 Apex 本地管理用户。
应用程序 --> 共享组件 --> 身份验证模式 --> 自定义
function fn_val_user_pwd_ldap (
p_username in varchar2,
p_password in varchar2
)
return boolean
is
l_ldap_host varchar2(100) := 'myldaphost.com';
l_ldap_port number := 389 ;
begin
if APEX_LDAP.AUTHENTICATE(
p_username =>p_username,
p_password =>p_password,
p_search_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port)
then
dbms_application_info.set_action(null);
return true;
else
apex_util.set_authentication_result(p_code => 110);
apex_util.set_custom_auth_status(p_status => 'Username or password incorrect.');
dbms_application_info.set_action(null);
return false;
end if;
end;
然后,我使用相同的身份验证方法使用 post 身份验证过程来检索 LDAP 中的组。我更喜欢这种方式,因为它在身份验证后执行,但您也可以使用动态操作来执行。
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => ':APP_USER',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => 'myldaphost.com',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
我们不使用 SSL 与 LDAP 服务器进行内部通信,因为此应用程序是 Intranet。所以参数p_use_ssl
默认为N.
正如我在你自己的问题的评论部分告诉你的,我认为参数p_auth_base指的是你自己的LDAP服务器的LDIF格式,而不是指AD的域名。
更新
让我向您展示它是如何工作的。 (当然,我隐藏了自己公司的敏感信息)。有时可能会出现获取不到组信息为null的情况。我在这里不确定是否是 LDAP 授权问题而不是 APEX 包本身的问题
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED ECHO ON
DECLARE
is_ok boolean;
l_mes varchar2(2000);
l_val varchar2(4000);
l_ldap_host varchar2(100) := 'myldapserver.com';
l_ldap_port number := 389 ;
BEGIN
if APEX_LDAP.AUTHENTICATE(
p_username =>'X329097',
p_password =>'********',
p_search_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port )
then
is_ok := true;
l_mes := 'Username and Password Correct' ;
dbms_output.put_line(l_mes);
else
l_mes := 'Username and Password Invalid' ;
dbms_output.put_line(l_mes);
end if;
if is_ok
then
l_val := APEX_LDAP.MEMBER_OF2(
p_username => 'X329097',
p_pass => '*********',
p_auth_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port);
dbms_output.put_line(l_val);
end if;
END;
/
Username and Password Correct
SC_APEX_ADMIN:SC_ORACLE_ADMIN
PL/SQL procedure successfully completed.
我尝试添加您的功能,但我无法再从登录页面访问我的应用程序。我试过 SQL 命令,这是我得到的
DECLARE
VAL BOOLEAN;
BEGIN
IF APEX_LDAP.AUTHENTICATE(
p_username => 'thomas.tirole',
p_password => 'mypassword',
p_search_base => 'OU=Users,OU=Domain,DC=domain,DC=ch',
p_host => 'xx.x.xxx.xx',
p_port => 389
) THEN
dbms_output.put_line('AUTENTHICATED');
ELSE
DBMS_OUTPUT.PUT_LINE('NOT AUTHENTICATED');
END IF;
END;
---------------------------------------
NOT AUTHENTICATED
Statement processed.
0.00 seconds
如果我尝试在 SQL 命令上执行 MEMBER_OF2 功能,这就是我得到的结果:
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => 'thomas.tirole',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Domain,DC=domain,DC=ch', -- SAME WITH DOMAIN\
p_host => 'xx.x.xxx.xx',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
---------------------------------------
ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 508
ORA-06512: à "SYS.DBMS_SYS_ERROR", ligne 86
ORA-06512: à "SYS.DBMS_LDAP", ligne 1487
ORA-06512: à "SYS.DBMS_LDAP", ligne 79
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 85
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 172
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 214
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 235
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 464
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 523
ORA-06512: à ligne 4
ORA-06512: à "SYS.DBMS_SQL", ligne 1721