如何使用 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。我在自己的环境中以不同的方式执行此操作,但我使用的是企业版:

  1. Oracle 数据库版本 19c
  2. Oracle Apex 版本 20.1
  3. 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