在 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 以获得提示
亚历克斯
我已经设置了本地 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 以获得提示
亚历克斯