spring-security - example - spring security ldap java config
Spring LDAP-enlace para una conexión exitosa (3)
Parece que su LDAP está configurado para no permitir una búsqueda sin vincularse (sin enlace anónimo). También ha implementado PasswordComparisonAuthenticator
y no BindAuthenticator
para autenticarse en LDAP.
Puede intentar modificar su método queryEmployeesByName()
para enlazar y luego buscar, mirando algunos ejemplos en el documento .
Estoy intentando autenticar y luego consultar nuestro LDAP corporativo utilizando Spring LDAP y Spring security. Logré hacer que la autenticación funcionara, pero cuando intento ejecutar la búsqueda siempre obtengo la siguiente excepción
Para realizar esta operación, se debe completar un enlace exitoso en la conexión
Después de mucha investigación, tengo la teoría de que después de autenticar y antes de poder realizar una consulta, debo vincularme a la conexión. Simplemente no sé qué y cómo?
Solo por mencionar que puedo navegar y buscar con éxito nuestro LDAP usando JXplorer, así que mis parámetros son correctos.
Aquí hay una sección de mi securityContext.xml
<security:http auto-config=''true''>
<security:intercept-url pattern="/reports/goodbye.html"
access="ROLE_LOGOUT" />
<security:intercept-url pattern="/reports/**" access="ROLE_USER" />
<security:http-basic />
<security:logout logout-url="/reports/logout"
logout-success-url="/reports/goodbye.html" />
</security:http>
<security:ldap-server url="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" />
<security:authentication-manager>
<security:authentication-provider ref="ldapAuthProvider">
</security:authentication-provider>
</security:authentication-manager>
<!-- Security beans -->
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" />
</bean>
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="foo.bar.reporting.server.security.ldap.LdapAuthenticatorImpl">
<property name="contextFactory" ref="contextSource" />
<property name="principalPrefix" value="TD/" />
<property name="employee" ref="employee"></property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="foo.bar.reporting.server.security.ldap.LdapAuthoritiesPopulator" />
</constructor-arg>
</bean>
<!-- DAOs -->
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
Aquí hay un fragmento de código de LdapAuthenticatorImpl
que realiza la autenticación. No hay problema aquí:
@Override
public DirContextOperations authenticate(final Authentication authentication) {
// Grab the username and password out of the authentication object.
final String name = authentication.getName();
final String principal = this.principalPrefix + name;
String password = "";
if (authentication.getCredentials() != null) {
password = authentication.getCredentials().toString();
}
if (!("".equals(principal.trim())) && !("".equals(password.trim()))) {
final InitialLdapContext ldapContext = (InitialLdapContext)
this.contextFactory.getContext(principal, password);
// We need to pass the context back out, so that the auth provider
// can add it to the Authentication object.
final DirContextOperations authAdapter = new DirContextAdapter();
authAdapter.addAttributeValue("ldapContext", ldapContext);
this.employee.setqId(name);
return authAdapter;
} else {
throw new BadCredentialsException("Blank username and/or password!");
}
}
Y aquí hay otro fragmento de código de EmployeeDao
con mi inútil intento de consulta:
public List<Employee> queryEmployeesByName(String query)
throws BARServerException {
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
filter.and(new WhitespaceWildcardsFilter("cn", query));
try {
// the following line throws bind exception
List result = ldapTemplate.search(BASE, filter.encode(),
new AttributesMapper() {
@Override
public Employee mapFromAttributes(Attributes attrs)
throws NamingException {
Employee emp = new Employee((String) attrs.get("cn").get(),
(String) attrs.get("cn").get(),
(String) attrs.get("cn").get());
return emp;
}
});
return result;
} catch (Exception e) {
throw new BarServerException("Failed to query LDAP", e);
}
}
Y, por último, la excepción que recibo
org.springframework.ldap.UncategorizedLdapException:
Uncategorized exception occured during LDAP processing; nested exception is
javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr:
DSID-0C090627, comment: In order to perform this operation a successful bind
must be completed on the connection., data 0, vece]; remaining name
''DC=TD,DC=FOO,DC=COM''
Voy a aceptar la respuesta de @Raghuram principalmente porque me hizo pensar en la dirección correcta.
¿Por qué mi código estaba fallando? Resultó - la forma en que lo conecté, estaba tratando de realizar una búsqueda anónima que está prohibida por el sistema - de ahí el error.
Cómo volver a conectar el ejemplo anterior para trabajar? Lo primero (y feo) es que debe proporcionar el nombre de usuario y la contraseña del usuario que se utilizará para acceder al sistema. Muy contrario a la intuición, incluso cuando inicia sesión y se autentica, incluso si está utilizando el sistema BindAuthenticator
, no intentará reutilizar sus credenciales. Gorrón. Entonces, debe pegar 2 parámetros en la definición de contextSource
manera:
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://foo.com:389/dc=td,dc=foo,dc=com" />
<!-- TODO - need to hide this or encrypt a password -->
<property name="userDn" value="CN=admin,OU=Application,DC=TD,DC=FOO,DC=COM" />
<property name="password" value="blah" />
</bean>
Hacer eso me permitió reemplazar la implementación personalizada de autenticador con BindAuthenticator
genérico y luego mi búsqueda de Java comenzó a funcionar
Obtuve el mismo error, no pude encontrar una solución. Finalmente cambié la identidad del grupo de aplicaciones al servicio de red y todo funcionó como un amuleto. (Tengo autenticación de Windows y anónimo habilitado en mi sitio)