現在、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)" であることを確認できます。
コードをデバッグできる最後のポイントは次のとおりです (org.springframework.ldap.core.LdapTemplate の 229 行目から)。
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 は、フィルター「(sAMAccountName=boi*)」を含む searchRequest を含む LDAP パケットが送信されたことを通知します (* はエスケープされなくなりました)。
同様のエンコーディングを使用し、LdapTemplate のさまざまなメソッドを使用して、期待していた結果を得ました (エンコードされたフィルターが WireShark で送信されているのを見ました) が、公開したばかりの場合、値が送信される前にデコードされる理由を説明できません.
状況を理解するのを手伝ってください。残念ながら、私はここで LDAP プロトコルを正しく理解していません。
ありがとう。
免責事項:同じ質問を Spring LDAP フォーラムに投稿しました。
TL/DR: LDAP サーバーに送信する前に、com.sun.jndi.ldap.LdapCtx が LDAP エンコード フィルタ (\2a から * など) をデコードするのはなぜですか?
更新: IBM の J9 JDK7 で同じ動作を試してみました。