如何使用配置器 class 正确实施 Spring 安全 Ldap 身份验证?
How to implement Spring Security Ldap authentication using the configurer class correctly?
您好,我正在尝试使用 WebSecurityConfigurerAdapter class 实施 spring 的 ldap 身份验证。
到目前为止,我可以通过内存方法甚至我公司的 ldap 服务器进行身份验证,但是后一种方法只有在我创建新上下文时传递硬编码的 userDN 和密码时才能进行身份验证,如果我不要创建新的上下文或者我没有输入 userDN 和密码,jvm 会抛出我:
Caused by: javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1\u0000]; Remaining name: '/'
我的问题是,如何从登录表单中获取用户密码和用户 DN,以便将其放入上下文中?如果那不可能,我怎样才能获得密码和 userDn 的上下文?
这是我的代码:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication().userSearchFilter("(&(objectClass=user)(sAMAccountName={0}))")
.groupSearchFilter("(&(memberOf:1.2.840.113556.1.4.1941:=CN=DL - DC859 - MIDDLEWARE,OU=Dyn,OU=Dist,OU=Security Groups,OU=POP,DC=pop,DC=corp,DC=local))")
.contextSource(getLdapContextSource());
}
private LdapContextSource getLdapContextSource() throws Exception {
LdapContextSource cs = new LdapContextSource();
cs.setUrl("ldap://tcp-prd.pop.corp.local:389");
cs.setBase("DC=pop,DC=corp,DC=local");
cs.setUserDn("t8951435@pop.corp.local");
cs.setPassword("mypassword");
cs.afterPropertiesSet();
return cs;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
}
谢谢。
我终于从thispost弄明白了。我仍然不知道如何设置组过滤器,但至少现在我可以绑定到服务器了。
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("pop.corp.local",
"ldap://tcp-prd.pop.corp.local:389");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
@Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
编辑:我终于找到了如何按组过滤。事实证明,他们在 ActiveDirectoryLdapAuthenticationProvider class v3.2.6 中添加了一个 setSearchFilter() 方法。因为我使用的是旧版本,所以我从来不知道这一点。所以我用该方法复制了 class 并创建了一个 buildFilter 方法来创建传递给 setSearchFilter 的过滤器字符串。
您好,我正在尝试使用 WebSecurityConfigurerAdapter class 实施 spring 的 ldap 身份验证。
到目前为止,我可以通过内存方法甚至我公司的 ldap 服务器进行身份验证,但是后一种方法只有在我创建新上下文时传递硬编码的 userDN 和密码时才能进行身份验证,如果我不要创建新的上下文或者我没有输入 userDN 和密码,jvm 会抛出我:
Caused by: javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1\u0000]; Remaining name: '/'
我的问题是,如何从登录表单中获取用户密码和用户 DN,以便将其放入上下文中?如果那不可能,我怎样才能获得密码和 userDn 的上下文?
这是我的代码:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication().userSearchFilter("(&(objectClass=user)(sAMAccountName={0}))")
.groupSearchFilter("(&(memberOf:1.2.840.113556.1.4.1941:=CN=DL - DC859 - MIDDLEWARE,OU=Dyn,OU=Dist,OU=Security Groups,OU=POP,DC=pop,DC=corp,DC=local))")
.contextSource(getLdapContextSource());
}
private LdapContextSource getLdapContextSource() throws Exception {
LdapContextSource cs = new LdapContextSource();
cs.setUrl("ldap://tcp-prd.pop.corp.local:389");
cs.setBase("DC=pop,DC=corp,DC=local");
cs.setUserDn("t8951435@pop.corp.local");
cs.setPassword("mypassword");
cs.afterPropertiesSet();
return cs;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
}
谢谢。
我终于从thispost弄明白了。我仍然不知道如何设置组过滤器,但至少现在我可以绑定到服务器了。
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("pop.corp.local",
"ldap://tcp-prd.pop.corp.local:389");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
@Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
编辑:我终于找到了如何按组过滤。事实证明,他们在 ActiveDirectoryLdapAuthenticationProvider class v3.2.6 中添加了一个 setSearchFilter() 方法。因为我使用的是旧版本,所以我从来不知道这一点。所以我用该方法复制了 class 并创建了一个 buildFilter 方法来创建传递给 setSearchFilter 的过滤器字符串。