From ba946b54f7ded054c54965b25d2f5ce370293893 Mon Sep 17 00:00:00 2001 From: bohmber Date: Tue, 10 Aug 2021 14:20:14 +0200 Subject: [PATCH] KEYCLOAK-19021 LDAPOperationManager.getFilterById is causing additional call to AD --- .../idm/store/ldap/LDAPOperationManager.java | 27 +--------- .../storage/ldap/idm/store/ldap/LDAPUtil.java | 51 +++++++++++++++++++ .../ldap/idm/store/ldap/LDAPUtilTest.java | 33 ++++++++++++ 3 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtilTest.java diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java index ef4015f08b..3a240b6f89 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java @@ -373,33 +373,10 @@ public class LDAPOperationManager { String filter = null; if (this.config.isObjectGUID()) { - final String strObjectGUID = ""; + byte[] objectGUID = LDAPUtil.encodeObjectGUID(id); - try { - Attributes attributes = execute(new LdapOperation() { + filter = "(&(objectClass=*)(" + getUuidAttributeName() + LDAPConstants.EQUAL + LDAPUtil.convertObjectGUIDToByteString(objectGUID) + "))"; - @Override - public Attributes execute(LdapContext context) throws NamingException { - return context.getAttributes(strObjectGUID); - } - - - @Override - public String toString() { - return new StringBuilder("LdapOperation: GUIDResolve\n") - .append(" strObjectGUID: ").append(strObjectGUID) - .toString(); - } - - - }); - - byte[] objectGUID = (byte[]) attributes.get(LDAPConstants.OBJECT_GUID).get(); - - filter = "(&(objectClass=*)(" + getUuidAttributeName() + LDAPConstants.EQUAL + LDAPUtil.convertObjectGUIDToByteString(objectGUID) + "))"; - } catch (NamingException ne) { - filter = null; - } } else if (this.config.isEdirectoryGUID()) { filter = "(&(objectClass=*)(" + getUuidAttributeName().toUpperCase() + LDAPConstants.EQUAL + LDAPUtil.convertGUIDToEdirectoryHexString(id) + "))"; } diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtil.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtil.java index f417d23a14..22e3ed5a56 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtil.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtil.java @@ -129,6 +129,57 @@ public class LDAPUtil { return result.toString().toUpperCase(); } + /** + *

Encode a string representing the display value of the objectGUID attribute retrieved from Active + * Directory.

+ * + * @param displayString A string representing the decoded value in the form of [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]. + * + * @return A raw byte array representing the value of the objectGUID attribute retrieved from + * Active Directory. + */ + public static byte[] encodeObjectGUID(String displayString) { + byte [] objectGUID = new byte[16]; + // [3][2][1][0] + objectGUID[0] = (byte) ((Character.digit(displayString.charAt(6), 16) << 4) + + Character.digit(displayString.charAt(7), 16)); + objectGUID[1] = (byte) ((Character.digit(displayString.charAt(4), 16) << 4) + + Character.digit(displayString.charAt(5), 16)); + objectGUID[2] = (byte) ((Character.digit(displayString.charAt(2), 16) << 4) + + Character.digit(displayString.charAt(3), 16)); + objectGUID[3] = (byte) ((Character.digit(displayString.charAt(0), 16) << 4) + + Character.digit(displayString.charAt(1), 16)); + // [5][4] + objectGUID[4] = (byte) ((Character.digit(displayString.charAt(11), 16) << 4) + + Character.digit(displayString.charAt(12), 16)); + objectGUID[5] = (byte) ((Character.digit(displayString.charAt(9), 16) << 4) + + Character.digit(displayString.charAt(10), 16)); + // [7][6] + objectGUID[6] = (byte) ((Character.digit(displayString.charAt(16), 16) << 4) + + Character.digit(displayString.charAt(17), 16)); + objectGUID[7] = (byte) ((Character.digit(displayString.charAt(14), 16) << 4) + + Character.digit(displayString.charAt(15), 16)); + // [8][9] + objectGUID[8] = (byte) ((Character.digit(displayString.charAt(19), 16) << 4) + + Character.digit(displayString.charAt(20), 16)); + objectGUID[9] = (byte) ((Character.digit(displayString.charAt(21), 16) << 4) + + Character.digit(displayString.charAt(22), 16)); + // [10][11][12][13][14][15] + objectGUID[10] = (byte) ((Character.digit(displayString.charAt(24), 16) << 4) + + Character.digit(displayString.charAt(25), 16)); + objectGUID[11] = (byte) ((Character.digit(displayString.charAt(26), 16) << 4) + + Character.digit(displayString.charAt(27), 16)); + objectGUID[12] = (byte) ((Character.digit(displayString.charAt(28), 16) << 4) + + Character.digit(displayString.charAt(29), 16)); + objectGUID[13] = (byte) ((Character.digit(displayString.charAt(30), 16) << 4) + + Character.digit(displayString.charAt(31), 16)); + objectGUID[14] = (byte) ((Character.digit(displayString.charAt(32), 16) << 4) + + Character.digit(displayString.charAt(33), 16)); + objectGUID[15] = (byte) ((Character.digit(displayString.charAt(34), 16) << 4) + + Character.digit(displayString.charAt(35), 16)); + return objectGUID; + } + /** *

Decode a raw byte array representing the value of the objectGUID attribute retrieved from Active * Directory.

diff --git a/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtilTest.java b/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtilTest.java new file mode 100644 index 0000000000..f79d598c7a --- /dev/null +++ b/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPUtilTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.keycloak.storage.ldap.idm.store.ldap; + +import org.junit.Assert; +import org.junit.Test; + +public class LDAPUtilTest { + + @Test + public void testEncodeDecodeGUID() { + String displayGUID = "2f419d1c-6495-479f-b340-9cb419eb9ae7"; + byte[] bytes = LDAPUtil.encodeObjectGUID(displayGUID); + String decodeObjectGUID = LDAPUtil.decodeObjectGUID(bytes); + Assert.assertEquals(displayGUID, decodeObjectGUID); + } +}