Hasta hace bien poco existía poca información de como y cuando se usa el gateway en una infraestructura de identidad.
Dentro del paquete del producto que descargamos nos encontramos con un gateway.zip, pero en muchas ocasiones desconocemos como usarlo. Mediante este post intentaremos exclarecer un poco su funcionalidad.
Hay que tener en cuenta que el gateway es una pasarela de integración para varios productos (Lotus Domino, Active Directory, Remedy y SAP). Dentro de sus peculiaridades es que las funciones o clases de C++ están dentro del sistema y tiene muchas limitaciones. Eso quiere decir que por mucho que queramos ampliar las operaciones a realizar en nuestro recurso, no podrá en un primer momento, nada más que las operaciones definidas en el gateway.
Active Directory
En el caso de Active Directory (AD a partir de ahora) nos proporciona las operaciones de provisión (y account List, o generación del accountIndex). Eso quiere decir que realiza las operaciones de gestión de usuarios (incluida su password, pasando la password a gestionarse desde IdM). Si la gestión de password se ha de realizar desde AD, entonces hemos de ampliar la solución incluyendo un segundo producto externo (Password Sync) que trataremos en otro post.
Con esta solución podremos hacer cargas mediante ActiveSync (cargamos y utilizamos el changelog de las operaciones y no toda la base de datos), o la reconciliación (ya sea incremental o total, que usa la base de datos de AD como referente).
Pues bien, el gateway se ha de instalar en todos los controladores de dominio que queramos gestionar. Teniendo en cuenta que el sistema por defecto no nos proporciona ninguna solución de banlanceo. O sea que bien utilizamos un balanceador externo, o debemos hacer una operación manual para gestionar nuestro recurso y cambiarle la IP, ya que nuestros workflows estarán referenciados al nombre del recurso y no nos valdrá la solución de generar un nuevo recurso.
Por lo cual si disponemos de una arquitectura con 3 controladores de dominio y un balanceador pondríamos la IP del balanceador en nuestra configuración de recurso, y es el balanceador el que debe realizar la conexión entre los AD. Posteriormente mediante replicaciones mantendremos la integridad. Es importante mantener la integridad a la hora de realizar las operaciones de reconciliación y Active Sync, ya que es ahora el balanceador el destino de la operación.
Bien pues todo esto es válido si no existen relaciones de confianza o subdominios en nuestra solución. ¿Porqué?.
Porque el software del gateway implementa el protocolo de LDAP V2 y no sabe seguir recursiones. Esto produce time-outs interminables que hacen que nuestro active Sync o reconciliación no funcione.
La mejor solución que podemos implementar (o que a mi se me ocurre) es sustituir la operación de búsqueda de nuestro recurso y usar la búsqueda a través de JNDI utilizando LDAP v3.
import com.waveset.util.EncryptedData;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import com.sun.idm.logging.trace.Trace;
import com.sun.idm.logging.trace.TraceManager;
import java.util.Collections;
/**
*
* @author nologin
*/
public class LDAPUtils {
//public final static String GROUPS_SEARCH_CTX = “OU=Seguridad,OU=Grupos,OU=Usuarios,DC=test-empresa,DC=testinternal,DC=empresa,DC=test”;
private static Trace trace = TraceManager.getTrace(LDAPUtils.class.getName());
/** Creates a new instance of ADUtils */
public LDAPUtils() {}
private static NamingEnumeration<SearchResult> executeQuery(String server, String userName, String password, int scope, String baseDN, String filter, String[] attrs){
DirContext ctx = null;
NamingEnumeration<SearchResult> out = null;
//System.out.println(“Atributos: servidor: ” + server+ “\nuser: ” + userName + “\npasswd: ” + password + “\nbaseDN: ” + baseDN + “\nfiltro: ” + filter);
//for(String atr: attrs)
// System.out.println(“Atributo: ” + atr);
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.jndi.ldap.LdapCtxFactory”);
String url = “ldap://” + server + “:389″;
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_PRINCIPAL, userName);
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialDirContext(env);
}catch(NamingException ne){
//System.out.println(“Error creando contexto inicial”);
trace.info1(“executeQuery”, “Error creando contexto inicial”);
ne.printStackTrace();
}
try{
SearchControls constraints = new SearchControls();
constraints.setSearchScope(scope);
constraints.setReturningAttributes(attrs);
out = ctx.search(baseDN, filter, constraints);
}catch(NamingException ne){
//System.out.println(“Busqueda incorrecta”);
trace.info1(“executeQuery”, “Busqueda incorrecta”);
ne.printStackTrace();
}
return out;
}
/**Metodo que obtiene el resultado de una busqueda realizada en un Directorio Activo.
*
* @param server IP o Nombre del AD
* @param userName Nombre del usuario de conexion
* @param password password encriptada del usuario de conexion
* @param baseDN contexto base sobre el cual realizar la busqueda
* @param filter filtro a aplicar en la busqueda
* @param attrsList lista de atributos a obtener
* @param scope entero que define los niveles de la búsqueda.
* OBJECT_SCOPE = 0;
* ONELEVEL_SCOPE = 1;
* SUBTREE_SCOPE = 2;
* @return
*/
public static ArrayList<String> getADNameList(String server, String userName, EncryptedData password, String baseDN, String filter, ArrayList attrsList, int scope){
ArrayList<String> out2 = null;
String attrs [] = (String []) attrsList.toArray (new String [attrsList.size ()]);
String passwdDecrypt = password.decryptToString();
NamingEnumeration<SearchResult> out = executeQuery(server, userName, passwdDecrypt, scope, baseDN, filter, attrs);
if(out != null){
out2 = new ArrayList<String>();
while (out.hasMoreElements()) {
try{
SearchResult sr = (SearchResult) out.next();
Attributes attributes = sr.getAttributes();
if(attributes != null){
try{
out2.add((String)attributes.get(attrs[0]).get());
}catch(NullPointerException npe){
trace.info1(“executeQuery”, “Error listando los atributos “+ attrs.toString());
npe.printStackTrace();
}
}
}catch(NamingException ne){
trace.info1(“generateADNameList”, “Error navengando en el resultado de la busqueda”);
ne.printStackTrace();
}
}
}
return out2;
}
public static ArrayList<String> getAttribute(String server, String userName, EncryptedData password, String baseDN, String filter, String attr, int scope){
ArrayList<String> out2 = null;
String attrs [] = {attr};
String passwdDecrypt = password.decryptToString();
NamingEnumeration<SearchResult> out = executeQuery(server, userName, passwdDecrypt, scope, baseDN, filter, attrs);
if(out != null){
while (out.hasMoreElements()) {
try{
SearchResult sr = (SearchResult) out.next();
Attributes attributes = sr.getAttributes();
if(attributes != null){
try{
out2 = (ArrayList<String>)Collections.list(attributes.get(attrs[0]).getAll());
}catch(NullPointerException npe){
trace.info1(“executeQuery”, “Error listando los atributos “+ attrs.toString());
npe.printStackTrace();
}
}
}catch(NamingException ne){
trace.info1(“generateADNameList”, “Error navengando en el resultado de la busqueda”);
ne.printStackTrace();
}
}
}
return out2;
}
Y utilizar la solución utilizandola en nuestras reglas que invoquen al desarrollo anterior.
<!DOCTYPE Configuration PUBLIC ‘waveset.dtd’ ‘waveset.dtd’>
<!– MemberObjectGroups=”#ID#All” authType=”EndUserLibrary” extensionClass=”Library” lastMod=”7″ lastModifier=”Configurator” name=”Active Directory Utilities”–>
<Configuration authType=’EndUserLibrary’ name=Active Directory Utilities’ creator=’Configurator’ createDate=” lastModifier=’Configurator’ lastModDate=’ ‘ lastMod=’7′>
<Extension>
<Library>
<Comments>Libreria que contiene utilidades para Active Directory</Comments>
<Rule name=’getGroupsfromAD’>
<block>
<defvar name=’resourceName’>
<rule name=’Active Directory Utilities:getNameActiveDirectory’/>
</defvar>
<defvar name=’filter’>
<s>objectclass=*</s>
</defvar>
<defvar name=’attrs’>
<list>
<s>cn</s>
</list>
</defvar>
<defvar name=’scope’>
<i>1</i>
</defvar>
<invoke name=’getADNameList’ class=’es.sun.idm.empresa.LDAPUtils’>
<rule name=’Database Utilities:getHost’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<rule name=’Database Utilities:getUserName’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<rule name=’ Database Utilities:getPassword’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<rule name=’Active Directory Utilities:getDNADGroups’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<ref>filter</ref>
<ref>attrs</ref>
<ref>scope</ref>
</invoke>
</block>
</Rule>
<Rule name=’getDNADGroups’>
<Description>Devuelve el distinguished name para los grupos del AD</Description>
<RuleArgument name=’resourceName’>
<Comments>El nombre del recurso del que devolveremos el DN</Comments>
</RuleArgument>
<concat>
<s>OU=Seguridad, OU=Grupos,</s>
<rule name=’ Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</Rule>
<Rule name=’setGroupsAD’>
<Description>Devolvemos el valor que tiene el atributo groups dentro del recurso AD en funcion de dos atributos</Description>
<RuleArgument name=’atributo1′>
<Comments>La localización del atributo1 para buscar los grupos</Comments>
</RuleArgument>
<RuleArgument name=’atributo2′>
<Comments>El atributo2 para buscar los grupos</Comments>
</RuleArgument>
<RuleArgument name=’resourceName’>
<Comments>El nombre del recurso del que devolveremos el DN</Comments>
</RuleArgument>
<block>
<dolist name=’group’>
<rule name=’Database Utilities:doGetAttributes’>
<argument name=’loc’ value=’$(atributo1)’/>
<argument name=’area’ value=’$(atributo2)’/>
<argument name=’attr’ value=’grupo’/>
<argument name=’tabla’ value=’grupos’/>
</rule>
<concat>
<s>CN=</s>
<ref>group</ref>
<s>,</s>
<s>OU=Seguridad, OU=Grupos,</s>
<rule name=’Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</dolist>
</block>
</Rule>
<Rule name=’getContainerAD’>
<RuleArgument name=’resourceName’/>
<invoke name=’getResourceAttributeFromResource’ class=’com.waveset.ui.FormUtil’>
<rule name=’EndUserRuleLibrary:getCallerSession’/>
<ref>resourceName</ref>
<s>Container</s>
</invoke>
</Rule>
<Rule name=’getSubContainersFromAD’>
<block>
<defvar name=’resourceName’>
<rule name=’Active Directory Utilities:getNameActiveDirectory’/>
</defvar>
<defvar name=’baseDN’>
<rule name=’Active Directory Utilities:getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</defvar>
<defvar name=’filter’>
<s>objectclass=organizationalUnit</s>
</defvar>
<defvar name=’attrs’>
<list>
<s>distinguishedName</s>
</list>
</defvar>
<defvar name=’scope’>
<i>2</i>
</defvar>
<invoke name=’getADNameList’ class=’es.sun.idm.empresa.LDAPUtils’>
<rule name=’Database Utilities:getHost’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<rule name=’Database Utilities:getUserName’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<rule name=’Database Utilities:getPassword’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
<ref>baseDN</ref>
<ref>filter</ref>
<ref>attrs</ref>
<ref>scope</ref>
</invoke>
</block>
</Rule>
<Rule name=’getNameActiveDirectory’>
<Description>Regla que contiene el nombre del recurso ActiveDirectory</Description>
<s>AD</s>
</Rule>
<Rule name=’getOrganizationalUnitAD’>
<Description>Devuelve la unidad organizativa en AD del tipo de usuario pasado como parámetro</Description>
<RuleArgument name=’userType’>
<Comments>Tipo del usuario</Comments>
</RuleArgument>
<block>
<defvar name=’resourceName’>
<rule name=’Active Directory Utilities:getNameActiveDirectory’/>
</defvar>
<switch>
<ref>userType</ref>
<case>
<s>USUARIO</s>
<concat>
<s>OU=Usuarios,</s>
<rule name=’ Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</case>
<case>
<s>TIPOUSER1</s>
<concat>
<s>OU=USUARIO,</s>
<rule name=’Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</case>
<case>
<s>ADMINISTRADOR</s>
<concat>
<s>OU=Administradores,</s>
<rule name=’Active Directory Utilities:getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</case>
<case>
<s>USUARIO</s>
<concat>
<s>OU=Usuarios,OU=Administradores,</s>
<rule name=’Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</case>
</switch>
</block>
</Rule>
<Rule name=’getUpcaseOrganizationalUnit’>
<Description>Devuelve la organizational unit de AD pasada como parametro con los valores de OU en mayusculas</Description>
<RuleArgument name=’orgUnit’/>
<block>
<set name=’Elements’>
<split>
<ref>orgUnit</ref>
<s>,</s>
</split>
</set>
<dolist name=’element’>
<ref>Elements</ref>
<set name=’first’>
<substr>
<ref>element</ref>
<i>0</i>
<indexOf>
<ref>element</ref>
<s>=</s>
</indexOf>
</substr>
</set>
<set name=’second’>
<substr>
<ref>element</ref>
<add>
<indexOf>
<ref>element</ref>
<s>=</s>
</indexOf>
<i>1</i>
</add>
</substr>
</set>
<set name=’upOrgUnit’>
<concat>
<ref>upOrgUnit</ref>
<upcase>
<ref>first</ref>
</upcase>
<s>=</s>
<ref>second</ref>
<s>,</s>
</concat>
</set>
</dolist>
<substr>
<ref>upOrgUnit</ref>
<i>0</i>
<sub>
<length>
<ref>upOrgUnit</ref>
</length>
<i>1</i>
</sub>
</substr>
</block>
</Rule>
<Rule name=’getShortNameGroups’>
<RuleArgument name=’usergroups’/>
<block>
<dolist name=’item’>
<ref>usergroups</ref>
<get>
<split>
<get>
<split>
<ref>item</ref>
<s>,</s>
</split>
<i>0</i>
</get>
<s>=</s>
</split>
<i>1</i>
</get>
</dolist>
</block>
</Rule>
<Rule name=’setLongNameGroups’>
<RuleArgument name=’grupos’/>
<block>
<defvar name=’resultgroups’/>
<set name=’resourceName’>
<rule name=’Active Directory Utilities:getNameActiveDirectory’/>
</set>
<dolist name=’group’>
<ref>grupos</ref>
<append name=’resultgroups’>
<concat>
<s>CN=</s>
<ref>group</ref>
<s>,</s>
<s>OU=Seguridad, OU=Grupos,</s>
<rule name=’ Active Directory Utilities: getContainerAD’>
<argument name=’resourceName’ value=’$(resourceName)’/>
</rule>
</concat>
</append>
</dolist>
<ref>resultgroups</ref>
</block>
</Rule>
</Library>
</Extension>
<MemberObjectGroups>
<ObjectRef type=’ObjectGroup’ id=’#ID#All’ name=’All’/>
</MemberObjectGroups>
</Configuration>
Sin más espero que se entienda.
Un saludo.
Sphere: Related ContentNo related posts.
Related posts brought to you by Yet Another Related Posts Plugin.


Core Networks homepage
Oracle University