Skip to content

EqualsFilter does not support binary strings #634

Open
@goto1134

Description

@goto1134

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,

  1. provide a way to pass a value to the query builder without the encoding
  2. provide a way to pass binary values to the query builder
  3. fix the log at LdapTemplate.java[find]:1843 to show the propper encoded finalFilter

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")
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions