如何在 Spring Boot 中为 Spring LDAP 身份验证设置覆盖 BindAuthenticator handleBindException
Posted
技术标签:
【中文标题】如何在 Spring Boot 中为 Spring LDAP 身份验证设置覆盖 BindAuthenticator handleBindException【英文标题】:How to Over ride BindAuthenticator handleBindException for Spring LDAP Authentication setup in Spring Boot 【发布时间】:2017-07-06 23:57:53 【问题描述】:用于 Spring Boot 中的 Spring 安全设置。 LDAP 身份验证提供程序默认配置为使用 BindAuthenticator 类。
这个类包含方法
/**
* Allows subclasses to inspect the exception thrown by an attempt to bind with a
* particular DN. The default implementation just reports the failure to the debug
* logger.
*/
protected void handleBindException(String userDn, String username, Throwable cause)
if (logger.isDebugEnabled())
logger.debug("Failed to bind as " + userDn + ": " + cause);
此方法用于处理身份验证相关的异常,例如无效凭据。
我想覆盖此方法,以便我可以处理此问题并根据 LDAP 返回的错误代码返回正确的错误消息。如密码无效或帐户被锁定。
当前的 LDAP 实现总是返回“错误的凭据”,它不能正确说明我的凭据为何无效。我想报道这些案例
-
帐户被锁定的位置
密码已过期,所以我可以重定向以更改密码
帐户因密码重试次数无效而被锁定
请帮忙
【问题讨论】:
应该...你真的想把它还给你的最终用户吗?从安全角度来看,您不想公开该信息。如果一个帐户被锁定,黑客现在知道它有一个有效的用户名。同样是你告诉他密码错误或者用户名不存在。 @Denium 我正在为内部应用程序构建此应用程序,只有员工可以访问 Intranet。所以这是我的产品负责人的期望:) 从安全的角度来看,这并不重要。谁说所有用户都愿意,那么心怀不满的员工呢。我可以想象您可能希望在日志中包含这些信息,但您希望对外界尽可能通用 是的。但由于许多原因,要么记录或提高对我公司内部用户的可见性。应该有一种方法来扩展它。目前在安全模式的 Spring Boot 配置中,这似乎是不可能的。 还有其他可能的用例,例如过期密码。凭证有效的地方。并且帐户已锁定,凭据再次有效。我无法捕捉这些案例。 【参考方案1】:我通过定义 LDAP 上下文而不是使用 Spring Boot LDAPAuthenticationProviderConfigurer 解决了这个问题。
然后创建 FilterBasedLdapUserSearch 并用我的 ConnectBindAuthenticator 覆盖 BindAuthentication。
我为 Spring Boot 配置创建了一个单独的 LDAPConfiguration 类,并将所有这些自定义对象注册为 Bean。
从上面的对象中,我通过将自定义对象传递给构造函数来创建 LDAPAuthenticationProvider
配置如下
@Bean
public DefaultSpringSecurityContextSource contextSource()
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(env.getProperty("ldap.url"));
contextSource.setBase(env.getProperty("ldap.base"));
contextSource.setUserDn(env.getProperty("ldap.managerDn"));
contextSource.setPassword(env.getProperty("ldap.managerPassword"));
return contextSource;
@Bean
public ConnectBindAuthenticator bindAuthenticator()
ConnectBindAuthenticator connectBindAuthenticator = new ConnectBindAuthenticator(contextSource());
connectBindAuthenticator.setUserSearch(ldapUserSearch());
connectBindAuthenticator.setUserDnPatterns(new String[]env.getProperty("ldap.managerDn"));
return connectBindAuthenticator;
@Bean
public LdapUserSearch ldapUserSearch()
return new FilterBasedLdapUserSearch("", env.getProperty("ldap.userSearchFilter"), contextSource());
【讨论】:
嗨。你能解释一下你班上的 env 是什么吗?【参考方案2】:您必须更改您的 spring 安全配置以添加您的 BindAuthenticator 扩展:
CustomBindAuthenticator.java
public class CustomBindAuthenticator extends BindAuthenticator
public CustomBindAuthenticator(BaseLdapPathContextSource contextSource)
super(contextSource);
@Override
protected void handleBindException(String userDn, String username, Throwable cause)
// TODO: Include here the logic of your custom BindAuthenticator
if (somethingHappens())
throw new MyCustomException("Custom error message");
super.handleBindException(userDn, username, cause);
spring-security.xml
<beans:bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg value="LDAP_URL" />
<beans:property name="userDn" value="USER_DN" />
<beans:property name="password" value="PASSWORD" />
</beans:bean>
<beans:bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="USER_SEARCH_BASE" />
<beans:constructor-arg index="1" value="USER_SEARCH_FILTER" />
<beans:constructor-arg index="2" ref="contextSource" />
</beans:bean>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean class="com.your.project.CustomBindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userSearch" ref="userSearch" />
</beans:bean>
</beans:constructor-arg>
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
希望对你有帮助。
【讨论】:
以上是关于如何在 Spring Boot 中为 Spring LDAP 身份验证设置覆盖 BindAuthenticator handleBindException的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot / Spring Data 中为 Amazon RDS Mysql 启用 SSL?
如何在 Spring-Boot 项目中为电话号码身份验证创建 REST API?
如何在 Spring Boot 中为 prometheus 制作自己的指标