如何正确使用配置器类实现 Spring Security Ldap 身份验证?
Posted
技术标签:
【中文标题】如何正确使用配置器类实现 Spring Security Ldap 身份验证?【英文标题】:How to implement Spring Security Ldap authentication using the configurer class correctly? 【发布时间】:2015-08-12 11:28:23 【问题描述】:您好,我正在尝试使用 WebSecurityConfigurerAdapter 类实现 Spring 的 ldap 身份验证。
到目前为止,我可以通过 in memory 方法甚至我公司的 ldap 服务器进行身份验证,但是后一种方法我只能在我创建新上下文时传递硬编码的 userDN 和密码时才能进行身份验证,如果我不这样做' t 创建一个新的上下文或者我没有输入 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: '/'
我的问题是,如何从登录表单中获取用户密码和 userDN,以便将其放入上下文中?如果这不可能,我怎样才能获得密码和 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();
谢谢。
【问题讨论】:
使用LDAP认证有两种模式。首先,您知道如何根据用户名构建用户的 DN(它甚至可以是 DN 本身)。其次,您需要执行 LDAP 搜索来查找用户的 DN。对于后者,您需要进行技术登录,以便 LDAP 身份验证组件可以找到用户条目。这就是你应该用来判断你的例子。您应该要求您的 LDAP 管理员为您的应用程序创建技术帐户并在您的LdapContextSource
中使用它。
我知道 userDN 将永远是用户在用户名框中输入的内容 + @pop.corp.local。我首先认为 auth 知道上下文并在其中包含用户名,但这似乎不是真的,因此我必须创建一个新的上下文。我只是不知道如何从那里获取凭据。
那不是DN,是域登录名。但也许您可以使用它登录到 Active Directory。我不确定。
有两个字段,DN和userDN。 DN 是“DC=pop,DC=corp,DC=local”。
不。 DN 是由RFC 4514 定义的特定事物。基础 DN 是上下文基础 DN,即 LDAP 树的基础(即您的树开始的位置)。您所指的 userDN 也应该是 DN。您没有提供 DN,而是提供用户的 principal name。
【参考方案1】:
我终于从this 帖子中弄明白了。我仍然不知道如何设置组过滤器,但至少现在我可以绑定到服务器了。
@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 类 v3.2.6 中添加了一个 setSearchFilter() 方法。因为我使用的是旧版本,所以我从来不知道这一点。所以我用该方法制作了一个类的副本,并创建了一个 buildFilter 方法来创建传递给 setSearchFilter 的过滤器字符串。
【讨论】:
以上是关于如何正确使用配置器类实现 Spring Security Ldap 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确实现使用 Spring MVC\Boot 返回图像列表的 REST 服务?
Spring 应用程序在 8 小时后失去与 MySql 的连接。如何正确配置?