В настоящее время я правильно избегаю своих фильтров, либо используя классы Spring LDAP Filter, либо используя LdapEncoder.filterEncode().
В то же время я использую WireShark для захвата пакетов, которыми обмениваются моя локальная машина и сервер LDAP.
А у меня похоже проблема. Даже если я правильно экранирую значения (что я подтвердил при отладке), они выходят через сеть без экранирования. Я также подтвердил (путем отладки), что значение остается закодированным до тех пор, пока оно не войдет в javax.naming.InitialContext.
Вот пример (обратите внимание, что я использую Spring LDAP 1.3.0, и это происходит как в Oracle JDK 6u45, так и в Oracle JDK 7u45).
В моем собственном коде на сервисном уровне выполняется следующий вызов:
String lMailAddress = (String) ldapTemplate.searchForObject("", new EqualsFilter(ldapUserSearchFilterAttribute, principal).encode(), new ContextMapper() {
@Override
public Object mapFromContext(Object ctx) {
DirContextAdapter lContext = (DirContextAdapter) ctx;
return lContext.getStringAttribute("mail");
}});
На данный момент я могу подтвердить, что строка, возвращаемая методом encode() в фильтре, имеет вид "(sAMAccountName=boi\2a)"
Последнее, что я могу отладить, это следующий код (начинается со строки 229 org.springframework.ldap.core.LdapTemplate):
SearchExecutor se = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException {
return ctx.search(base, filter, controls);
}
};
Когда позже вызывается executeSearch(), я также могу убедиться, что строка фильтра содержит "(sAMAccountName=boi\2a)".
Я не могу продолжать отладку, так как у меня нет исходного кода для javax,naming.* или com.sun.jndi.ldap.* (поскольку вызывается com.sun.jndi.ldap.LdapCtx).
Однако, как только вызов возвращается из executeSearch(), WireShark сообщает мне, что пакет LDAP, содержащий searchRequest с фильтром "(sAMAccountName=boi*)" был передан (* больше не экранируется).
Я использовал аналогичную кодировку и использовал разные методы LdapTemplate, которые дали ожидаемый результат (я видел, как закодированный фильтр передается в WireShark), но я не могу объяснить, почему в случае, который я только что показал, значение декодируется перед передачей .
Помогите, пожалуйста, разобраться в ситуации. К счастью, я тот, кто неправильно понимает протокол LDAP.
Спасибо.
Отказ от ответственности: я разместил тот же вопрос на форумах Spring LDAP.
TL/DR: Почему com.sun.jndi.ldap.LdapCtx декодирует закодированные фильтры LDAP (например, от \2a до *) перед их передачей на сервер LDAP?
Обновление: Пробовал и наблюдал такое же поведение с IBM J9 JDK7.