我正在尝试使用Spring Boot 2.1.9.RELEASE针对Microsoft AD验证用户身份。我可以从AD中找到用户dn,但它不能对用户进行身份验证并获得空指针异常。
我的WebSecurityConfig代码
with
a as (select ... from ...),
b as (select ... from ...),
f as (select ... from ...),
...
select a.col1, b.col2, f.col3
from a join b on a.id = b.id
left join f on f.id = b.id
where ...
错误日志
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
// auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
auth.ldapAuthentication().userDnPatterns("CN={0},OU=Users")
.groupSearchBase("ou=groups")
.userSearchFilter("(sAMAccountName={0})").contextSource()
.url(AD_URL)
.managerDn(AD_USERNAME).managerPassword(AD_PASSWORD).and()
.passwordCompare()
.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
在进一步调查错误日志时,我发现以下代码试图从用户对象获取编码的密码,但是我的passwordAttributeName“ userPassword”在用户对象中不存在
org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator.isPasswordAttrCompare(PasswordComparisonAuthenticator.java:121)
w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
o.s.s.l.a.LdapAuthenticationProvider : Processing authentication request for user: <username>
o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://<companyname>.com:389/dc=<companyname>,dc=com'
o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user '<username>', with user search [ searchFilter: '(sAMAccountName={0})', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://<companyname>.com:389/dc=<companyname>,dc=com'
o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under DN 'dc=<companyname>,dc=com', base = '', filter = '(sAMAccountName={0})'
o.s.s.ldap.SpringSecurityLdapTemplate : Found DN: CN=<User Full Name>,OU=Users,OU=HM Bangalore,OU=Office Locations
o.s.s.ldap.SpringSecurityLdapTemplate : Ignoring PartialResultException
.s.s.l.a.PasswordComparisonAuthenticator : Performing LDAP compare of password attribute 'userPassword' for user 'CN=<User Full Name>,OU=Users,OU=HM Bangalore,OU=Office Locations'
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@456cde20
w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception
java.lang.NullPointerException: null
at org.springframework.security.crypto.password.LdapShaPasswordEncoder.extractPrefix(LdapShaPasswordEncoder.java:193) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.crypto.password.LdapShaPasswordEncoder.matches(LdapShaPasswordEncoder.java:162) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.crypto.password.LdapShaPasswordEncoder.matches(LdapShaPasswordEncoder.java:158) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator.isPasswordAttrCompare(PasswordComparisonAuthenticator.java:121) ~[spring-security-ldap-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator.authenticate(PasswordComparisonAuthenticator.java:109) ~[spring-security-ldap-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:187) ~[spring-security-ldap-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:85) ~[spring-security-ldap-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) ~[spring-security-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
.
.
.
不确定为什么我无法从AD获取编码的密码。 任何帮助将不胜感激。
答案 0 :(得分:1)
Microsoft Active Directory不使用普通的“ userPassword”密码,而是使用“ unicodePwd”。
此外,与许多LDAP服务器实现一样,Microsoft Active Directory 不会返回密码属性的值。
最后,对密码执行LDAP比较是一种不好的做法,并且不应,因为对密码执行“比较请求”时可能会绕过某些内置功能,例如密码过期和入侵者检测userPassword属性。 您应该始终对LDAP执行绑定操作。