Programmatically Authenticate LDAP user in AEM

Viewed 1145

I've set up local LDAP server Created user and group. Configured LDAP in AEM config manager and synchronized the users and group.

Using, ExternalIdentityProvider as a service reference, I'm able to get list of LDAP users I.e. I am able to validate if the user is present in LDAP or not.

But, I'm not able to validate user credentials using authentic method of the above mentioned API.

Am I missing any configuration specifics or the approach that I'm using is wrong ?

Updated:

Authentication code:

@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);

Error thrown -

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

Update: Identity provider config

# 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"

Sync Handler

# 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"

External login

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

LDIF file for users

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==
1 Answers

For LDAP Login you need 3 OSGi configs. The most difficult one, you already have.

  • External Login Module (containing a reference to the next two)
  • LDAP Identity Provider (how to access the LDAP)
  • Sync Handler (mapping the LDAP data to AEM user data)

Here an example:

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

kind regards, Alex


I additionally setup an Apache Directory Server and filled it with the sample data (Sailors of the seven seas) http://directory.apache.org/apacheds/basic-ug/1.5-sample-configuration.html

The following configuration worked for me (synced users and groups via JMX, successful login of a user, including auto sync):

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

Check, to have the following

  • know or set the password for the test user
  • set user.autoMembership to contributor (to see more than a white screen after a successful login)
  • check the OSGi config in the Felix console, maybe you missed the type or mispelled a config option
  • Check the log-file for hints

Alex

Related