在 AEM 中以编程方式验证 LDAP 用户

Programmatically Authenticate LDAP user in AEM

我已经设置了本地 LDAP 服务器 创建的用户和组。 在 AEM 配置管理器中配置 LDAP 并同步用户和组。

使用 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==

对于 LDAP 登录,您需要 3 个 OSGi 配置。最难的,你已经有了。

  • 外部登录模块(包含对下两个的引用)
  • LDAP Identity Provider(如何访问 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 Directory Server 并在其中填充了示例数据(七海水手)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为contributor(登录成功后看到的不仅仅是白屏)
  • 检查 Felix 控制台中的 OSGi 配置,也许您错过了类型或拼错了配置选项
  • 检查 log-file 以获得提示

亚历克斯