Hola Amig@s,
Si queremos validar un usuario AD (usuario de directorio activo) utilizando Oracle PLSQL podemos hacerlo mediante ciertas funciones que tiene el paquete DBMS_LDAP.
Lo bueno de este sistema es que tendremos la gestión de todos los usuarios desde un solo sitio, es decir desde el AD. Esto normalmente se conoce como SSO o Single Sign On. Hay varias formas de validar Oracle contra un AD, una es LDAP, otra es ADFS.
En este artículo trataremos la forma de hacerlo con LDAP.
Lo primero es crear la ACL para el servidor AD.
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (acl => 'a.xml',
description => 'Regla para permitir la conexión a un servidor externo',principal => 'USER', --Aquí va el usuario del esquema en el que queremos activarlois_grant => TRUE,
privilege => 'connect',
start_date => SYSTIMESTAMP,
end_date => NULL);
DBMS_NETWORK_ACL_ADMIN.add_privilege (acl => 'a.xml',
principal => 'USER', --Aquí va el usuario del esquema en el que queremos activarlois_grant => TRUE,
privilege => 'resolve',
position => NULL,
start_date => NULL,
end_date => NULL);
DBMS_NETWORK_ACL_ADMIN.assign_acl (acl => 'a.xml',
host => '192.168.1.215', --Aquí va el servidor al que debemos dar paso para el usuario de bbdd.
lower_port => 389, --Aquí definimos el puerto inicial o si lo ponemos a null todos los puertos son validos.
upper_port => NULL); --Aquí si va a NULL se toma como limite el puerto lower.
COMMIT;
END;
Recuerden que deben reemplazar el host y el USER por vuestra configuración.
Ahora bien, el siguiente código, es un ejemplo que al ejecutarlo, devolverá toda la información relacionada con el usuario.
El código no es mío, está basado en el disponible en Oracle Base https://oracle-base.com/articles/9i/ldap-from-plsql-9i solo lo he modificado un poco para adaptarlo a la prueba.
DECLARE
-- Adjust as necessary.
l_ldap_host VARCHAR2(256) := '192.168.1.215';
l_ldap_port VARCHAR2(256) := '389'; --cuidado hay que crear la acl.
l_ldap_user VARCHAR2(256) := 'prueba@TESTAD.local'; --usuario de prueba del dominio
l_ldap_passwd VARCHAR2(256) := 'prueba456';
l_ldap_base VARCHAR2(256) := 'CN=Users,DC=TESTAD,DC=local';
l_userinfo VARCHAR2(256) := 'prueba'; --usuario para el filtro
l_retval PLS_INTEGER;
l_session DBMS_LDAP.session;
l_attrs DBMS_LDAP.string_collection;
l_message DBMS_LDAP.message;
l_entry DBMS_LDAP.message;
l_attr_name VARCHAR2(256);
l_ber_element DBMS_LDAP.ber_element;
l_vals DBMS_LDAP.string_collection;
BEGIN
-- Choose to raise exceptions.
DBMS_LDAP.USE_EXCEPTION := TRUE;
--esto es importante, sino devuelve un ora-12703
DBMS_LDAP.UTF8_CONVERSION := false;
-- Connect to the LDAP server.
l_session := DBMS_LDAP.init(hostname => l_ldap_host,
portnum => l_ldap_port);
l_retval := DBMS_LDAP.simple_bind_s(ld => l_session,
dn => l_ldap_user,
passwd => l_ldap_passwd);
-- Get all attributes
l_attrs(1) := '*'; -- retrieve all attributes
-- para ver todos los atributos, mirar aqui. https://www.manageengine.com/products/ad-manager/help/csv-import-management/active-directory-ldap-attributes.html
l_retval := DBMS_LDAP.search_s(ld => l_session,
base => l_ldap_base,
scope => DBMS_LDAP.SCOPE_SUBTREE,
filter => 'sAMAccountName='||l_userinfo,
attrs => l_attrs,
attronly => 0,
res => l_message);
IF DBMS_LDAP.count_entries(ld => l_session, msg => l_message) > 0 THEN
-- Get all the entries returned by our search.
l_entry := DBMS_LDAP.first_entry(ld => l_session,
msg => l_message);
<< entry_loop >>
WHILE l_entry IS NOT NULL LOOP
-- Get all the attributes for this entry.
DBMS_OUTPUT.PUT_LINE('---------------------------------------');
l_attr_name := DBMS_LDAP.first_attribute(ld => l_session,
ldapentry => l_entry,
ber_elem => l_ber_element);
<< attributes_loop >>
WHILE l_attr_name IS NOT NULL LOOP
-- Get all the values for this attribute.
l_vals := DBMS_LDAP.get_values (ld => l_session,
ldapentry => l_entry,
attr => l_attr_name);
<< values_loop >>
FOR i IN l_vals.FIRST .. l_vals.LAST LOOP
DBMS_OUTPUT.PUT_LINE('ATTIBUTE_NAME: ' || l_attr_name || ' = ' || SUBSTR(l_vals(i),1,200));
END LOOP values_loop;
l_attr_name := DBMS_LDAP.next_attribute(ld => l_session,
ldapentry => l_entry,
ber_elem => l_ber_element);
END LOOP attibutes_loop;
l_entry := DBMS_LDAP.next_entry(ld => l_session,
msg => l_entry);
END LOOP entry_loop;
END IF;
-- Disconnect from the LDAP server.
l_retval := DBMS_LDAP.unbind_s(ld => l_session);
DBMS_OUTPUT.PUT_LINE('L_RETVAL: ' || l_retval);
END;
/
Como podrán ver lo que estamos haciendo es consultar contra el AD si el usuario prueba existe, si existe devolverá toda la información referente al usuario.
La salida del dbms output será similar a esta:
ATTIBUTE_NAME: objectClass = top
ATTIBUTE_NAME: objectClass = person
ATTIBUTE_NAME: objectClass = organizationalPerson
ATTIBUTE_NAME: objectClass = user
ATTIBUTE_NAME: cn = Usuario de Prueba
ATTIBUTE_NAME: sn = -
ATTIBUTE_NAME: description = Usuario de prueba para ver si se comunica con Oracle
ATTIBUTE_NAME: physicalDeliveryOfficeName = Laguna del marquez de bravia
ATTIBUTE_NAME: givenName = Usuario
ATTIBUTE_NAME: displayName = Usuario de Pruebaa
ATTIBUTE_NAME: uSNCreated = 12755
ATTIBUTE_NAME: memberOf = CN=Remote Desktop Users,CN=Builtin,DC=TESTAD,DC=local
ATTIBUTE_NAME: memberOf = CN=Users,CN=Builtin,DC=TESTAD,DC=local
ATTIBUTE_NAME: uSNChanged = 12798
ATTIBUTE_NAME: streetAddress = aqui mismo
...
Et voila!
Ya tenemos iteracción con un AD desde Oracle Plsql. Con esta información luego se puede establecer un sistema de validación, básicamente buscando una propiedad y comparándola.
Espero que les haya resultado útil.
0 comentarios:
Publicar un comentario