我正在使用Spring Security为Web应用程序创建登录页面。用户已在Active Directory中注册。
以下是我正在使用的代码:
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
authenticationManagerBuilder.ldapAuthentication()
.contextSource().url("ldap:MyLdap")
.root("ou=MyOu,dc=MyDC,dc=net")
.port(389)
.managerDn("cn=MyCN,ou=MyOU,ou=MyOU2,dc=MyDC,dc=net").managerPassword("MyPass")
.and()
.userSearchBase("dc=MyDC,dc=net")
.userSearchFilter("(sAMAccountName={0})");
}
用户搜索过滤器设置为sAMAccountName,因为这是我公司的Active Directory中的唯一标识符。
我能够从Active Directory成功检索到正确的用户,但我在NameNotFoundException
类中抛出了LdapTemplate
。该类cas属性IgnoreNameNotFoundException。如果我在调试时将此属性设置为true,则登录正确,否则我会收到错误并且登录失败。
如何从代码中设置此属性?或者我在配置中做错了什么?
编辑:
这是堆栈跟踪:
org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of:
""
]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of:
""
]; remaining name ""
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:183) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:376) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE]
答案 0 :(得分:1)
根据此documentation,ignore-name-not-found
属性具有魔力。如果您可以使用基于XML的配置覆盖它,那应该这样做。我无法为此找到合适的程序覆盖,如果我找到它,我会更新。
另一种方法是创建自己的bean,扩展LDAP Provider,但重写同一属性并注入它。这应该可行,但您需要知道如何使用父类,因为它可能会破坏某些功能。
答案 1 :(得分:0)
我找到了一种使用自定义LdapTemplate的方法,因为我必须定义一个自定义的AuthenticationProvider。
以下是WebSecurityConfigurerAdapter中的代码:
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
LdapAuthenticationProvider ldapProvider=new LdapAuthenticationProvider();
authenticationManagerBuilder.authenticationProvider(ldapProvider);
}
以下是AuthenticationProvider中的代码:
@Component
public class LdapAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
LdapTemplate ldapTemplate=ldapTemplate();
Filter filter = new EqualsFilter("sAMAccountName", name);
boolean authed = ldapTemplate.authenticate("", filter.encode(), password);
//ldapTemplate.getContextSource().getContext(password, name);
if(!authed){
return null;
}
return new UsernamePasswordAuthenticationToken(name,password,new ArrayList<>());
}
@Bean
public LdapTemplate ldapTemplate(){
LdapTemplate ldapTemplate=new LdapTemplate(contextSource());
ldapTemplate.setIgnoreNameNotFoundException(true);
return ldapTemplate;
}
@Bean
LdapContextSource contextSource(){
LdapContextSource contextSource=new LdapContextSource();
contextSource.setUrl("");
//all of the private configurations
contextSource.afterPropertiesSet();
return contextSource;
}