Программная аутентификация пользователя LDAP в AEM

Я установил локальный сервер LDAP. Созданы пользователь и группа. Настроил LDAP в диспетчере конфигурации AEM и синхронизировал пользователей и группы.

Используя ExternalIdentityProvider в качестве справочника службы, я могу получить список пользователей LDAP, т.е. Я могу проверить, присутствует ли пользователь в LDAP или нет.

Но я не могу проверить учетные данные пользователя, используя аутентичный метод вышеупомянутого API.

Мне не хватает каких-либо особенностей конфигурации или я использую неправильный подход?

Обновлено:

Код аутентификации:

@Reference
private ExternalIdentityProviderManager externalIdentityProviderManager;

final String externalId = request.getParameter("externalId");
final String externalPassword = request.getParameter("externalPassword");

final ExternalIdentityProvider idap = externalIdentityProviderManager.getProvider("ldap");
final SimpleCredentials credentials = new SimpleCredentials(externalId, externalPassword.toCharArray());
final ExternalUser externalUser = idap.authenticate(credentials);

Выброшенная ошибка -

javax.security.auth.login.LoginException: Unable to authenticate against LDAP server: INVALID_CREDENTIALS: Bind failed: Attempt to lookup non-existant entry: cn=steve+uid=steve+sn=jobs,dc=example,dc=com

Обновление: конфигурация поставщика удостоверений

# Configuration created by Apache Sling JCR Installer
userPool.maxActive=L"8"
searchTimeout="60s"
host.name="localhost"
customattributes=[""]
adminPool.maxActive=L"8"
group.makeDnPath=B"false"
user.baseDN="ou\=Users,dc\=example,dc\=com"
group.objectclass=["groupOfNames"]
user.objectclass=["person"]
userPool.lookupOnValidate=B"true"
host.noCertCheck=B"false"
user.makeDnPath=B"true"
bind.dn="uid\=admin,ou\=system"
group.baseDN="ou\=Groups,dc\=example,dc\=com"
group.extraFilter=""
user.extraFilter=""
host.port=I"10389"
bind.password="secret"
adminPool.lookupOnValidate=B"true"
useUidForExtId=B"false"
group.nameAttribute="cn"
provider.name="ldap"
host.ssl=B"false"
host.tls=B"false"
user.idAttribute="uid"
group.memberAttribute="member"

Обработчик синхронизации

# Configuration created by Apache Sling JCR Installer
group.pathPrefix=""
user.dynamicMembership=B"false"
group.expirationTime="1d"
user.membershipExpTime="1h"
user.pathPrefix=""
user.propertyMapping=["profile/nt:primaryType\=\"nt:unstructured\"","profile/givenName\=cn","profile/rep:password\=userPassword"]
handler.name="syncHandlerDefault"
enableRFC7613UsercaseMappedProfile=B"false"
user.autoMembership=[""]
user.expirationTime="1h"
group.propertyMapping=[""]
group.autoMembership=[""]
user.disableMissing=B"false"
user.membershipNestingDepth=I"3"

Внешний вход

# Configuration created by Apache Sling JCR Installer
jaas.controlFlag="SUFFICIENT"
jaas.ranking=I"50"
sync.handlerName="syncHandlerDefault"
jaas.realmName=""
idp.name="ldap"

Файл LDIF для пользователей

version: 1

dn: ou=Users,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Users

dn: cn=eden+sn=hazard+uid=eden,ou=Users,dc=example,dc=com
objectClass: uidObject
objectClass: person
objectClass: top
cn: eden
sn: hazard
uid: eden
userPassword: {SSHA}O/t6ZRnWZTLhHla106Hp5nIWy85b0kgwNmeY3w==

dn: cn=rohit+sn=sharma+uid=rohit,ou=Users,dc=example,dc=com
objectClass: uidObject
objectClass: person
objectClass: top
cn: rohit
sn: sharma
uid: rohit
userPassword: {SSHA}9fzIkizxYg3LGG8n0jf/tnpv//qiNlxtS6mnWg==

dn: cn=harry+uid=harry+sn=kane,ou=Users,dc=example,dc=com
objectClass: uidObject
objectClass: person
objectClass: top
cn: harry
sn: kane
uid: harry
userPassword: {SSHA}WjNxB0ZDsmKfpjN0zwgsvDtZ4c/lHrIZXb7T2g==

dn: cn=cristiano+uid=cristiano+sn=ronaldo,ou=Users,dc=example,dc=com
objectClass: uidObject
objectClass: person
objectClass: top
cn: cristiano
sn: ronaldo
uid: cristiano
userPassword: {SSHA}ykzpMLVAbK99hfbCwwGgmgcDVzDV/Kfl0TlA8Q==

person Abhishek Sinha    schedule 26.06.2019    source источник


Ответы (1)


Для входа в LDAP вам потребуется 3 конфигурации OSGi. Самый сложный, который у вас уже есть.

  • Модуль внешнего входа (со ссылкой на следующие два)
  • Поставщик удостоверений LDAP (как получить доступ к LDAP)
  • Обработчик синхронизации (сопоставление данных LDAP с данными пользователя AEM)

Вот пример:

org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory-emea

"jcr:primaryType": "sling:OsgiConfig",
"jaas.ranking": "50",
"jaas.controlFlag": "SUFFICIENT",
"jaas.realmName": "",
"idp.name": "ldap-emea",
"sync.handlerName": "sync-emea"

org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentityProvider-emea

"jcr:primaryType": "sling:OsgiConfig",
"provider.name": "ldap-emea",
"host.name": "ldap-emea.emea.mycompany.internal",
"host.port": "3269",
"host.ssl": true,
"host.tls": true,
"host.noCertCheck": false,
"bind.dn": "CN=xxxx,OU=xxxx,OU=xxxx,OU=xxxx,DC=emea,DC=dir",
"bind.password": "very secret",
"searchTimeout": "60s",
"adminPool.maxActive": "8",
"adminPool.lookupOnValidate": true,
"userPool.maxActive": "8",
"userPool.lookupOnValidate": true,
"user.baseDN": "DC=emea,DC=dir",
"user.objectclass": "user",
"user.idAttribute": "sAMAccountName",
"user.extraFilter": "xxx very specific LDAP query xxxxx",
"user.makeDnPath": false,
"group.baseDN": "OU=Groups,OU=Common,DC=emea,DC=dir",
"group.objectclass": "group",
"group.nameAttribute": "cn",
"group.extraFilter": "xxx very specific LDAP query xxxxx",
"group.makeDnPath": false,
"group.memberAttribute": "member",
"customattributes": []

org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler-emea

"jcr:primaryType": "sling:OsgiConfig",
"handler.name": "sync-emea",
"user.expirationTime": "1h",
"user.autoMembership": [],
"user.propertyMapping": [
   "rep:fullname=cn",
   "profile/email=mail",
   "profile/familyName=sn",
   "profile/givenName=givenName",
   "profile/aboutMe=description",
   "profile/country=co",
   "profile/jobTitle=department",
   "profile/phoneNumber=telephoneNumber",
   "profile/mobile=mobile",
   "profile/postalCode=postalCode",
   "profile/street=streetAddress",
   "preferences/language=\"en\""
],
"user.pathPrefix": "my-company/emea",
"user.membershipExpTime": "1h",
"user.membershipNestingDepth": "3",
"group.expirationTime": "1d",
"group.autoMembership": [],
"group.propertyMapping": [
   "profile/givenName=name",
   "profile/aboutMe=description"
],
"group.pathPrefix": "my-company/nested/emea",
"user.dynamicMembership": false,
"user.disableMissing": false,
"enableRFC7613UsercaseMappedProfile": false

С уважением, Алекс


Я дополнительно установил сервер каталогов Apache и заполнил его образцами данных («Моряки семи морей») http://directory.apache.org/apacheds/basic-ug/1.5-sample-configuration.html

У меня сработала следующая конфигурация (синхронизация пользователей и групп через JMX, успешный вход пользователя, включая автосинхронизацию):

http://localhost:4502/apps/ldap-test.9.json

  {
  "jcr:primaryType": "nt:folder",
  "config": {
    "jcr:primaryType": "sling:Folder",
    "org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentityProvider-test": {
      "jcr:primaryType": "sling:OsgiConfig",
      "provider.name": "ldap-test-alex",
      "host.name": "localhost",
      "host.port": "10389",
      "host.ssl": false,
      "host.tls": false,
      "bind.dn": "uid=admin,ou=system",
      "bind.password": "secret",
      "user.objectclass": "person",
      "user.baseDN": "ou=people,o=sevenSeas",
      "user.idAttribute": "uid",
      "group.objectclass": "groupOfUniqueNames",
      "group.baseDN": "ou=groups,o=sevenSeas",
      "group.nameAttribute": "cn",
      "group.memberAttribute": "uniquemember",
    },
    "org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler-test": {
      "jcr:primaryType": "sling:OsgiConfig",
      "handler.name": "ldap-sync-test-alex",
      "user.pathPrefix": "ldap-test",
      "group.pathPrefix": "ldap-test",
      "user.membershipNestingDepth": 1,
      "user.autoMembership": [
        "contributor"
      ],
      "user.propertyMapping": [
        "profile/email=mail",
        "profile/familyName=sn",
        "profile/givenName=givenName",
        "profile/aboutMe=description"
      ]
    },
    "org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory-test": {
      "jcr:primaryType": "sling:OsgiConfig",
      "idp.name": "ldap-test-alex",
      "sync.handlerName": "ldap-sync-test-alex",
      "jaas.controlFlag": "SUFFICIENT",
      "jaas.ranking": "50"
    }
  }
}

Проверьте, чтобы были следующие

  • знать или установить пароль для тестового пользователя
  • установите user.autoMembership для участника (чтобы видеть больше, чем белый экран после успешного входа в систему)
  • проверьте конфигурацию OSGi в консоли Felix, возможно, вы пропустили тип или неверно указали параметр конфигурации
  • Проверьте лог-файл на наличие подсказок

Алекс

person Alexander Berndt    schedule 26.06.2019
comment
Привет, Алекс. Я настроил 3 конфигурации osgi, и теперь я могу получать и отображать всех пользователей LDAP. Но я не могу аутентифицировать идентификатор пользователя / пароль для создания модуля входа в систему. - person Abhishek Sinha; 01.07.2019
comment
Я проверю это сегодня вечером и протестирую с помощью Apache Directory Studio. Но самая сложная часть - это соединение с LDAP. Получение пользователей уже отлично. - person Alexander Berndt; 02.07.2019
comment
Вы адаптировали имена? Они своего рода id, чтобы все связать. В моем примере ldap-emea и sync-emea. - person Alexander Berndt; 02.07.2019
comment
Может быть, вы разместите свою конфигурацию и сообщите нам, какой сервер LDAP вы используете? - person Alexander Berndt; 03.07.2019
comment
Кстати. ваш образец кода отлично подходит для меня, поэтому я могу пройти аутентификацию: за исключением того, что я назвал поставщика по-другому externalIdentityProviderManager.getProvider("ldap-test-alex"); - person Alexander Berndt; 03.07.2019
comment
Использовали ли вы какой-либо метод шифрования / хеширования перед передачей в качестве учетных данных? Если нет, то какой экземпляр сервера LDAP вы используете? Поскольку служба каталогов Apache по умолчанию хранит все пароли как хешированные значения SSHA. Боюсь, что это тоже может быть причиной. Просто нужно подтвердить другое мнение. - person Abhishek Sinha; 03.07.2019
comment
Нет, я просто использовал его как есть. И я использовал ваш пример кода как есть. Раньше я использовал его как минимум для трех разных LDAP-серверов. Но поскольку вы можете синхронизировать пользователей через JMX (как я понял), вход через Bind-DN ​​работает. Так что это не пароль. Я бы сказал, что это имя пользователя, которое указано в user.idAttribute. Это отличается для каждого LDAP. Или вам нужен префикс (например, emea / myuser), что часто бывает в крупных компаниях (если идентификаторы пользователей не уникальны для всех регионов или объединенных компаний). Какой сервер LDAP вы используете? Какая у вас конфигурация OSGi? - person Alexander Berndt; 03.07.2019
comment
Обновился конфигами. Также я имел в виду хеширование userPassword, а не bind.password. Я использую Apache Directory Studio для локальной настройки и создания пользователей вручную - person Abhishek Sinha; 03.07.2019
comment
Я просто могу дико догадываться. 1-й) Вы пытались установить пароль для своего тестового пользователя вручную? Возможно, импорт не удался. 2-й) Вы пробовали это с другим клиентом LDAP? 3-й) Измените bind-dn на одного из ваших пользователей и попробуйте подключиться. Если это работает, значит, по крайней мере, ваш пароль установлен правильно. - person Alexander Berndt; 03.07.2019
comment
Можете ли вы добавить следующего пользователя в свой ldap? Меня устраивает. Я могу войти в AEM и пройти аутентификацию с помощью вашего кода. # userpassword is pass # version: 1 dn: cn = Alexander Berndt, ou = Users, dc = example, dc = com objectclass: person objectclass: organizationPerson objectclass: inetOrgPerson objectclass: top cn: Alexander Berndt description: Это тестовое имя: Александр sn: Берндт uid: aberndt mail: [email protected] пароль пользователя: {SHA} nU4eI71bcnBGqeO0t9tXvY1u5oQ = - person Alexander Berndt; 03.07.2019
comment
Вышеупомянутый должен быть файлом ldif, но комментарии разрушают форматирование. Я думаю, ты поймешь. - person Alexander Berndt; 03.07.2019
comment
Кстати. Я импортировал вам файл LDIF, и я тоже не могу аутентифицировать этих пользователей. Так что ошибка странного пользователя. Если я создам его вручную, он работает. - person Alexander Berndt; 03.07.2019
comment
Этот работает (снова переформатируйте файл в ldif, пароль = pass) - person Alexander Berndt; 03.07.2019
comment
версия: 1 dn: cn = Ronaldo2, ou = Users, dc = example, dc = com objectClass: uidObject objectClass: person objectClass: top cn: Ronaldo2 sn: Ronaldo uid: christiano2 userPassword: {SHA256} 10 / w7o2juYBrGMh326 / KbveteUL знак равно - person Alexander Berndt; 03.07.2019
comment
РАЗРЕШЕНО !! Проблема заключалась в методе создания пользователей в студии каталогов Apache. Если мы создадим пользователя и предоставим какой-либо атрибут в дополнение к 'cn', dn будет создан как - dn: cn = eden + sn = haz + uid = eden, ou = Users, dc = example, dc = com ie '+' разделенные атрибуты, но если мы создадим пользователя только с помощью cn и добавим другие атрибуты позже, это сработает. Вот почему вы смогли аутентифицировать своих пользователей, а мои пользователи не прошли аутентификацию. helpx.adobe.com/experience-manager/ using / - документация AEM, которую я использовал, НЕ помогает - person Abhishek Sinha; 03.07.2019
comment
ВАЖНО для будущих ссылок - Другой пример пользователя: - dn: cn = cristian, ou = Users, dc = example, dc = com objectClass: uidObject objectClass: person objectClass: top cn: cristian sn: bale uid: cristian userPassword: {SSHA} QSOFZWViatL5u5gT8vFCw1zIrWkRHJgrZ8BiEw == Спасибо, Алекс за вашу помощь. - person Abhishek Sinha; 03.07.2019
comment
На самом деле я неправильно прочитал ваш вопрос вначале. Если вы хотите аутентифицироваться только программно, вам не нужны ExternalLoginModuleFactory и DefaultSyncHandler. Это необходимо только в том случае, если пользователи должны быть импортированы как пользователи AEM (например, для закрытых групп пользователей или созданного пользователем контента) или для входа в AEM (например, как авторы контента). Чистая аутентификация работает без нее, и это проблема безопасности, если она вам не нужна. - person Alexander Berndt; 03.07.2019
comment
Я сослался на [helpx.adobe.com/experience-manager/ используя / oak-login.html]. Пожалуйста, проверьте строку метода 'login ()' 198 'externalUser = idp.authenticate (credentials); ' - person Abhishek Sinha; 03.07.2019