Spring LDAP 验证有问题
Trouble with Spring LDAP Auth
所以这是我第一次与 Spring 合作,请多多包涵!
我很确定问题出在我对 DnPatterns 和组搜索库的设置不正确。
我正在尝试连接一个外部广告。使用广告浏览器我找到了一个条目,下面是用户的 dn,然后是他们通常用来登录的登录 ID
在 AD Explorer 视图中的用户配置文件中收听
DN -> CN=LastName\, FirstName, OU=Users,OU=Calgary,DC=CORP,DC=DEPARTMENT,DC=com
用户名和密码用户将在登录时提供:
UserName -> LastFirst5
Password -> Password
在目录资源管理器中获取用户信息的路径如图所示
DC=CORP,DC=DEPARTMENT,DC=com -> OU=Calgary -> OU=Users -> CN=LastName,FirstName
这是我的配置设置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("DC=corp,DC=department,DC=com")
.groupSearchBase("OU=Users,OU=Calgary,DC=CORP,DC=Department,DC=com")
.contextSource()
.url("ldap://corp.Ad.com/")
.and()
.passwordCompare()
.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
首先,上下文源 url 应包括用于搜索 and/or 身份验证用户的基本 DN。
.contextSource()
.url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
userDnPatterns()
用于匹配出现在用户条目的 RDN 中的用户登录名 - 如果出现 ! - 服务器然后用用户输入的登录名替换 {0} 占位符,并通过附加来自 LDAP url 的基本 dn 重新创建用户 dn。问题是在您的目录中,用户 dn 不是 是根据其用户名构建的,而是根据其不同的 cn
属性构建的,因此您无法匹配(LastName, FirstName ≠ LastFirst5
),因此您无法使用此方法对用户进行身份验证(但如果用户名和 cn 相同,则正确的模式应类似于 cn={0},ou=Users
)。
另一方面,userSearchFilter()
可用于匹配用户使用常规搜索过滤器提供的登录名。可选地 userSearchBase()
可以与它一起设置一个可选的分支 rdn,用户条目所在的位置以及从中执行搜索,如果未指定,则搜索包括从 LDAP [=55 的基本 dn 开始的整个目录=].
.and()
.userSearchBase('ou=Users,ou=Calgary')
.userSearchFilter('(sAMAccountName={0})')
请注意,如果您在 OU=Users,OU=OtherCity,DC=...
等其他城市有用户,您将需要另一个配置来验证他们的身份,而无需知道从哪个城市开始搜索。在这种情况下,您将重置搜索基础以匹配基础 dn 下的所有条目,并且由于您只希望用户能够登录,因此您可以优化过滤器
因此:
.and()
.userSearchBase('')
.userSearchFilter('(&(sAMAccountName={0})(objectClass=user)')
没有 groupSearchFilter()
就不需要 groupSearchBase()
,这 2 个仅在授权时需要(验证用户具有给定角色 <=> 是成员给定的组)。
为了能够搜索和匹配用户条目,身份验证请求本身需要连接并绑定到 LDAP 服务器,大多数服务器不接受匿名绑定,因此您可能需要设置 managerDn () 和 managerPassword() :
.contextSource()
.url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
.managerDn('admin')
.managerPassword('password')
所以这是我第一次与 Spring 合作,请多多包涵!
我很确定问题出在我对 DnPatterns 和组搜索库的设置不正确。
我正在尝试连接一个外部广告。使用广告浏览器我找到了一个条目,下面是用户的 dn,然后是他们通常用来登录的登录 ID
在 AD Explorer 视图中的用户配置文件中收听
DN -> CN=LastName\, FirstName, OU=Users,OU=Calgary,DC=CORP,DC=DEPARTMENT,DC=com
用户名和密码用户将在登录时提供:
UserName -> LastFirst5
Password -> Password
在目录资源管理器中获取用户信息的路径如图所示
DC=CORP,DC=DEPARTMENT,DC=com -> OU=Calgary -> OU=Users -> CN=LastName,FirstName
这是我的配置设置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("DC=corp,DC=department,DC=com")
.groupSearchBase("OU=Users,OU=Calgary,DC=CORP,DC=Department,DC=com")
.contextSource()
.url("ldap://corp.Ad.com/")
.and()
.passwordCompare()
.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
首先,上下文源 url 应包括用于搜索 and/or 身份验证用户的基本 DN。
.contextSource() .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
userDnPatterns()
用于匹配出现在用户条目的 RDN 中的用户登录名 - 如果出现 ! - 服务器然后用用户输入的登录名替换 {0} 占位符,并通过附加来自 LDAP url 的基本 dn 重新创建用户 dn。问题是在您的目录中,用户 dn 不是 是根据其用户名构建的,而是根据其不同的cn
属性构建的,因此您无法匹配(LastName, FirstName ≠ LastFirst5
),因此您无法使用此方法对用户进行身份验证(但如果用户名和 cn 相同,则正确的模式应类似于cn={0},ou=Users
)。
另一方面,userSearchFilter()
可用于匹配用户使用常规搜索过滤器提供的登录名。可选地userSearchBase()
可以与它一起设置一个可选的分支 rdn,用户条目所在的位置以及从中执行搜索,如果未指定,则搜索包括从 LDAP [=55 的基本 dn 开始的整个目录=]..and() .userSearchBase('ou=Users,ou=Calgary') .userSearchFilter('(sAMAccountName={0})')
请注意,如果您在
OU=Users,OU=OtherCity,DC=...
等其他城市有用户,您将需要另一个配置来验证他们的身份,而无需知道从哪个城市开始搜索。在这种情况下,您将重置搜索基础以匹配基础 dn 下的所有条目,并且由于您只希望用户能够登录,因此您可以优化过滤器 因此:.and() .userSearchBase('') .userSearchFilter('(&(sAMAccountName={0})(objectClass=user)')
没有
groupSearchFilter()
就不需要groupSearchBase()
,这 2 个仅在授权时需要(验证用户具有给定角色 <=> 是成员给定的组)。为了能够搜索和匹配用户条目,身份验证请求本身需要连接并绑定到 LDAP 服务器,大多数服务器不接受匿名绑定,因此您可能需要设置 managerDn () 和 managerPassword() :
.contextSource() .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com') .managerDn('admin') .managerPassword('password')