spring-projects / spring-projects/spring-ldap
EqualsFilter does not support binary strings
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 375
- Forks
- 501
- Avg merge
- 6h 4m
- Merged PRs (30d)
- 63
Description
Suppose the following classes:
@Entry(objectClasses = ["top", "person", "user"], base = "ou=users")
class LdapUser {
@Id
lateinit var id: Name
@Attribute(name = "objectGUID", type = Attribute.Type.BINARY, readonly = true)
lateinit var guid: UUID
}
@Repository
class LdapUserRepository(
private val ldapTemplate: LdapTemplate,
) {
fun findById(guid: UUID): LdapUser {
val byteBuffer = ByteBuffer.wrap(ByteArray(16))
byteBuffer.putLong(guid.mostSignificantBits)
byteBuffer.putLong(guid.leastSignificantBits)
val bytes = byteBuffer.array()
val guidByteString = bytes.joinToString("\\", "\\") { "%02x".format(it) }
val guidFilter = HardcodedFilter("(objectGUID=$guidByteString)")
return ldapTemplate.find(
query().where("objectGUID").`is`(guidByteString),
LdapUser::class.java
).firstOrNull() ?: error("Could not find user")
}
When you search the user with guid 90d1c68e-01be-4485-aafd-b3ffb9ddb026. The following log will be generated but nothing would be found:
DEBUG LdapTemplate.java[find]:1843 - Searching - base=ou=users, finalFilter=(&(&(objectclass=top)(objectclass=person)(objectclass=user))(objectGUID=\90\d1\c6\8e\01\be\44\85\aa\fd\b3\ff\b9\dd\b0\26)), scope=javax.naming.directory.SearchControls@54e07139
The query is correct, but it will not be executed. The following query will be executed instead:
base=ou=users, finalFilter=(&(&(objectclass=top)(objectclass=person)(objectclass=user))(objectGUID=\5c90\5cd1\5cc6\5c8e\5c01\5cbe\5c44\5c85\5caa\5cfd\5cb3\5cff\5cb9\5cdd\5cb0\5c26))
This happens because org.springframework.ldap.filter.EqualsFilter will be encoded and the backslashes will be escaped. This encoding is incorrect for the binary strings.
Please,
- provide a way to pass a value to the query builder without the encoding
- provide a way to pass binary values to the query builder
- fix the log at
LdapTemplate.java[find]:1843to show the propper encodedfinalFilter
P.S. There is a workaround to fix the encoding issue but it finalizes the query builder
@Repository
class LdapUserRepository(
private val ldapTemplate: LdapTemplate,
) {
fun findById(guid: UUID): LdapUser {
val byteBuffer = ByteBuffer.wrap(ByteArray(16))
byteBuffer.putLong(guid.mostSignificantBits)
byteBuffer.putLong(guid.leastSignificantBits)
val bytes = byteBuffer.array()
val guidByteString = bytes.joinToString("\\", "\\") { "%02x".format(it) }
val guidFilter = HardcodedFilter("(objectGUID=$guidByteString)")
return ldapTemplate.find(
query().filter(guidFilter),
LdapUser::class.java
).firstOrNull() ?: error("Could not find user")
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with org.springframework.ldap.filter.EqualsFilter and the query builder behavior described in the issue, then inspect LdapTemplate.java at the find log location. Reproduce the binary objectGUID filter behavior and determine how raw or binary values should be represented; done means the filter is executed without incorrect backslash escaping and the finalFilter log shows the actual encoded filter.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, kotlin
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100