更新
看起来https://jira.spring.io/browse/SEC-2897会解决问题。我使用3.2.6并更改了提供程序以添加
provider.setSearchFilter("(sAMAccountName={0})");
它开始工作了。我还是不知道为什么它提到了DaoAuthenticationProvider。这种变化也不会这样做。
END UPDATE
我有一个Spring Boot应用程序,其网页受到针对Active Directory验证的登录保护。一切正常,直到我升级到Spring Boot 1.2.2.RELEASE,它引入了Spring Security 3.2.6。
登录到Active Directory时,升级失败。如果我将spring-security-ldap切换到3.2.5,一切都会恢复正常工作。
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
使用那个JAR的3.2.5.RELEASE
DEBUG 18702 --- [tp1586246816-18] ctiveDirectoryLdapAuthenticationProvider : Processing authentication request for user: myuser
DEBUG 18702 --- [tp1586246816-18] o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under DN '', base = 'dc=mycompany,dc=com', filter = '(&(objectClass=user)(userPrincipalName={0}))'
DEBUG 18702 --- [tp1586246816-18] o.s.s.ldap.SpringSecurityLdapTemplate : Found DN: cn=My User,ou=Users,dc=mycompany,dc=com
INFO 18702 --- [tp1586246816-18] o.s.s.ldap.SpringSecurityLdapTemplate : Ignoring PartialResultException
DEBUG 18702 --- [tp1586246816-18] ctiveDirectoryLdapAuthenticationProvider : 'memberOf' attribute values: [CN=Content Admin,DC=mycompany,DC=com, ... and more]
DEBUG 18702 --- [tp1586246816-18] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@1a256d80
DEBUG 18702 --- [tp1586246816-18] w.a.UsernamePasswordAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@8ba0727d: Principal: org.springframework.security.core.userdetails.User@30421acf: Username: myuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: 1kgfzfy7haxcu1skjarcd03sg6; Granted Authorities: ROLE_USER
一切正常。
切换到该JAR的3.2.6.RELEASE并获取
DEBUG 19234 --- [tp1586246816-18] ctiveDirectoryLdapAuthenticationProvider : Processing authentication request for user: myuser
DEBUG 19234 --- [tp1586246816-18] o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under DN '', base = 'dc=mycompany,dc=com', filter = '(&(objectClass=user)(userPrincipalName={0}))'
INFO 19234 --- [tp1586246816-18] o.s.s.ldap.SpringSecurityLdapTemplate : Ignoring PartialResultException
DEBUG 19234 --- [tp1586246816-18] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG 19234 --- [tp1586246816-18] o.s.s.a.dao.DaoAuthenticationProvider : User 'myuser' not found
看起来它发现AD中的用户很好,然后由于某种原因尝试使用DaoAuthenticationProvider。我没有DaoAuthenticationProvider,因为安全性只是基于用户在活动目录中并经过验证。
我查看了从3.2.5到3.2.6的变化,但没有任何东西跳出来,可能导致失败。
我现在需要考虑的两个版本的spring-security-ldap之间有什么变化吗?
这是我的@Configuration
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.hasAuthority("ROLE_USER")
.and()
.authenticationProvider(activeDirectoryLdapAuthenticationProvider())
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
// @formatter:on
}
@Bean
public UserDetailsContextMapperImpl nyUserDetailsContextMapper() {
return new UserDetailsContextMapperImpl();
}
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("mycompany.com", "ldap://10.0.0.131:389");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUserDetailsContextMapper(myUserDetailsContextMapper());
return provider;
}
}
和映射器
public class UserDetailsContextMapperImpl implements UserDetailsContextMapper, Serializable {
public static final String DATA_SERVICES_ADMIN_AUTHORITY = "Data Services Admin";
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
List<GrantedAuthority> mappedAuthorities = Lists.newArrayList();
mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username, "", true, true, true, true, mappedAuthorities);
}
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
}
}
更新
看起来https://jira.spring.io/browse/SEC-2897会解决问题。我使用3.2.6并更改了提供程序以添加
provider.setSearchFilter("(sAMAccountName={0})");
它开始工作了。我还是不知道为什么它提到了DaoAuthenticationProvider。这种变化也不会这样做。
END UPDATE