Grails OpenLDAP 登录失败:抱歉,我们无法找到具有该用户名和密码的用户
Posted
技术标签:
【中文标题】Grails OpenLDAP 登录失败:抱歉,我们无法找到具有该用户名和密码的用户【英文标题】:Grails OpenLDAP login failed: Sorry, we were not able to find a user with that username and password 【发布时间】:2018-09-11 10:12:51 【问题描述】:我正在尝试将 Ldap 登录添加到我的 grails 应用程序。添加 spring-secutiry-core 和 spring-security-ldap (2.0.1) 插件后,我在 config.groovy 中添加了配置:
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider','anonymousAuthenticationProvider','rememberMeAuthenticationProvider']
grails.plugin.springsecurity.ldap.context.managerDn = 'uid=admin,dc=sw01,dc=com'
grails.plugin.springsecurity.ldap.context.managerPassword = 'Admin123'
grails.plugin.springsecurity.ldap.context.server = 'ldap://localhost:389'
grails.plugin.springsecurity.ldap.context.anonymousReadOnly = true
grails.plugin.springsecurity.ldap.authorities.groupSearchBase = 'ou=Groups,dc=sw01,dc=com'
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = false
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = false
grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = 'member=0'
grails.plugin.springsecurity.ldap.useRememberMe = false
grails.plugin.springsecurity.ldap.search.base = 'dc=sw01,dc=com'
grails.plugin.springsecurity.ldap.search.attributesToReturn = ['uid', 'mail', 'cn', 'sn', 'givenName', 'jpegPhoto' , 'telephoneNumber']
grails.plugin.springsecurity.ldap.search.filter = '(uid=0)'
grails.plugin.springsecurity.ldap.authenticator.attributesToReturn = ['uid', 'mail', 'cn', 'sn', 'givenName', 'jpegPhoto' , 'telephoneNumber']
grails.plugin.springsecurity.userLookup.usernamePropertyName = 'uid'
我按照官方指南添加了我的 userDetails 类,详细 contextMapper 类。
加载 Grails 应用程序并尝试登录时,会显示标题中的错误消息。
在查看后台 slapd 日志时,我非常确定(虽然不熟悉 slapd 日志格式)用户的 DN 搜索已经成功...:
5ac1d79a => send_search_entry: conn 1017 dn="uid=sito,ou=Users,dc=sw01,dc=com"
ber_flush2: 3768 bytes to sd 15
ldap_write: want=3768, written=3768
0000: 30 82 0e b4 02 01 01 64 82 0e ad 04 20 75 69 64 0......d.... uid
0010: 3d 73 69 74 6f 2c 6f 75 3d 55 73 65 72 73 2c 64 =sito,ou=Users,d
0020: 63 3d 73 77 30 31 2c 64 63 3d 63 6f 6d 30 82 0e c=sw01,dc=com0..
0030: 87 30 5e 04 0b 6f 62 6a 65 63 74 43 6c 61 73 73 .0^..objectClass
0040: 31 4f 04 10 65 78 74 65 6e 73 69 62 6c 65 4f 62 1O..extensibleOb
0050: 6a 65 63 74 04 09 75 69 64 4f 62 6a 65 63 74 04 ject..uidObject.
0060: 06 70 65 72 73 6f 6e 04 14 6f 72 67 61 6e 69 7a .person..organiz
0070: 61 74 69 6f 6e 61 6c 50 65 72 73 6f 6e 04 0d 69 ationalPerson..i
0080: 6e 65 74 4f 72 67 50 65 72 73 6f 6e 04 03 74 6f netOrgPerson..to
0090: 70 30 16 04 02 63 6e 31 10 04 0e 41 6c 66 6f 6e p0...cn1...Alfon
00a0: 73 6f 20 52 69 76 65 72 6f 30 16 04 09 67 69 76 so Rivero0...giv
...
ber_get_next
ldap_read: want=8 error=Resource temporarily unavailable
5ac1d79a conn=1018 op=0 do_bind
ber_scanf fmt (imt) ber:
ber_scanf fmt (m) ber:
5ac1d79a >>> dnPrettyNormal: <uid=sito,ou=Users,dc=sw01,dc=com>
5ac1d79a <<< dnPrettyNormal: <uid=sito,ou=Users,dc=sw01,dc=com>, <uid=sito,ou=users,dc=sw01,dc=com>
5ac1d79a do_bind: version=3 dn="uid=sito,ou=Users,dc=sw01,dc=com" method=128
5ac1d79a mdb_dn2entry("uid=sito,ou=users,dc=sw01,dc=com")
5ac1d79a => mdb_dn2id("uid=sito,ou=users,dc=sw01,dc=com")
5ac1d79a <= mdb_dn2id: got id=0xd
5ac1d79a => mdb_entry_decode:
5ac1d79a <= mdb_entry_decode
5ac1d79a send_ldap_result: conn=1018 op=0 p=3
5ac1d79a send_ldap_response: msgid=1 tag=97 err=49
ber_flush2: 14 bytes to sd 16
ldap_write: want=14, written=14
0000: 30 0c 02 01 01 61 07 0a 01 31 04 00 04 00 0....a...1....
5ac1d79a connection_get(16): got connid=1018
5ac1d79a connection_read(16): checking for input on id=1018
ber_get_next
ldap_read: want=8, got=0
5ac1d79a ber_get_next on fd 16 failed errno=0 (Undefined error: 0)
5ac1d79a connection_close: conn=1018 sd=16
但是页面仍然没有显示匹配的用户名和密码。 我尝试了使用和不使用以下配置行,同样的错误:
grails.plugin.springsecurity.password.algorithm = 'SHA-256'
我是否有一些配置错误,或者在实施过程中遗漏了什么?请帮助,非常感谢任何信息!
[更新 20180403]
所以我做了更多的挖掘工作。我修改了自动生成的 LoginController.groovy authfail() 动作并打印出异常堆栈跟踪:
| Error org.springframework.security.authentication.BadCredentialsException: Bad credentials
| Error at org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:95)
| Error at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:178)
| Error at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:80)
| Error at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
| Error at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:92)
| Error at grails.plugin.springsecurity.web.authentication.GrailsUsernamePasswordAuthenticationFilter.attemptAuthentication(GrailsUsernamePasswordAuthenticationFilter.java:59)
| Error at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
| Error at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
它发生在 org.springframework.security.ldap.authentication.BindAuthenticator 并带有 BadCredentialsException 异常...
但我确实有从示例 ldif 导入的用户(也使用 JXplorer 浏览器验证):
dn: uid=mcurie,ou=Users,dc=sw01,dc=com
objectClass: uidObject
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
cn: Marie Curie
facsimileTelephoneNumber: +1 904 982 6883
givenName: Marie
mail: mcurie@example.com
ou: Users
roomNumber: 667
sn: Curie
telephoneNumber: +1 904 982 6882
uid: mcurie
userPassword:: c2VjcmV0
唯一的问题是,我没有用户的“用户名”字段,所以我使用“uid”登录,也在 config.groovy 中指定:
grails.plugin.springsecurity.userLookup.usernamePropertyName = 'uid'
以上是正确的,还是我还缺少其他东西?
非常感谢任何信息/帮助!
[更新 20180406]
所以我回到最基本的,只是从ldap命令搜索和绑定一个用户测试出来:
$ ldapsearch -D 'cn=admin,dc=sw01,dc=com' -W -x -b 'uid=wpauli,ou=Users,dc=sw01,dc=com'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <uid=wpauli,ou=Users,dc=sw01,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# wpauli, Users, sw01.com
dn: uid=wpauli,ou=Users,dc=sw01,dc=com
objectClass: uidObject
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
cn: Wolfgang Pauli
facsimileTelephoneNumber: +1 904 982 6883
givenName: Wolfgang
mail: wpauli@example.com
ou: Users
roomNumber: 667
sn: Pauli
telephoneNumber: +1 904 982 6882
uid: wpauli
userPassword:: c2VjcmV0
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
然后(不确定我需要在 DN 周围加上单引号,所以我都尝试了,都失败了):
$ ldapwhoami -vvv -h localhost -p 389 -D 'uid=wpauli,ou=Users,dc=sw01,dc=com' -x -w c2VjcmV0
ldap_initialize( ldap://localhost:389 )
ldap_bind: Invalid credentials (49)
$ ldapwhoami -vvv -h localhost -p 389 -D uid=wpauli,ou=Users,dc=sw01,dc=com -x -w c2VjcmV0
ldap_initialize( ldap://localhost:389 )
ldap_bind: Invalid credentials (49)
为什么绑定失败?使用的密码与上面的 Ldapsearch 结果返回的密码匹配吗?
帮助任何人?
【问题讨论】:
【参考方案1】:啊,我把它整理好了。仔细查看我使用的示例 LDIF 文件,填充 userPassword 的行有双冒号'::',这意味着密码是 base64 编码的......
telephoneNumber: +1 904 982 6882
uid: sito
userPassword:: c2VjcmV0
我通过 base64 解码器运行了值“c2VjcmV0”,它是“secret”。呃……
所以现在用正确的密码更改 ldapwhoami 测试
发件人:
$ ldapwhoami -vvv -h localhost -p 389 -D uid=wpauli,ou=Users,dc=sw01,dc=com -x -w c2VjcmV0
收件人:
$ ldapwhoami -vvv -h localhost -p 389 -D uid=wpauli,ou=Users,dc=sw01,dc=com -x -w secret
已成功验证。
回到我的示例 Grails App 登录,使用正确的密码现在也可以毫无问题地登录。
【讨论】:
以上是关于Grails OpenLDAP 登录失败:抱歉,我们无法找到具有该用户名和密码的用户的主要内容,如果未能解决你的问题,请参考以下文章
Grails Spring Security登录失败未重定向到登录视图
在 docker 容器中运行可运行 jar 时,Grails Spring Security Active Directory 登录失败