如何在不锁定LDAP用户的情况下阻止Spring安全性中的LDAP用户帐户?

时间:2011-05-24 04:51:35

标签: java ldap spring-security

我是Spring Security的新手。在我的应用程序中,身份验证是通过Ldap完成的。在Ldap身份验证之后,我想在登录时处理失败和成功事件。我想跟踪数据库中的登录计数以获取锁定功能。 任何人都知道如何实现这个目标吗?

2 个答案:

答案 0 :(得分:1)

身份验证由LDAP完成,但您希望在登录后锁定ldap用户。

如果你使用spring 2.5,你可以自定义实现InitializingBean并检查principal是否是LDAP用户:

public abstract class EventListener implements InitializingBean {

Log log = LogFactory.getLog(this.getClass());

EventDispatcher eventDispatcher;

// Spring will call this method after auto-
// wiring is complete.
public void afterPropertiesSet() throws Exception {
    // let us register this instance with
    // event dispatcher
    eventDispatcher.registerListener(this);
}

/**
 * Implementation of this method checks whether the given event can be
 * handled in this class. This method will be called by the event
 * dispatcher.
 * 
 * @param event
 *            the event to handle
 * @return true if the implementing subclass can handle the event
 */
public abstract boolean canHandle(Object event);

/**
 * This method is executed by the event dispatcher with the event object.
 * 
 * @param event
 *            the event to handle
 */
public abstract void handle(Object event);

public void setEventDispatcher(EventDispatcher eventDispatcher) {
    this.eventDispatcher = eventDispatcher;
}
}

然后在loginFailureEventListener上实现此自定义句柄(在xml中映射此侦听器)

        public class LoginSuccessEventlistener extends EventListener {  

    @Override  
    public boolean canHandle(Object event) {  
        return event instanceof AuthenticationFailureBadCredentialsEvent;
    }  

    @Override  
    public void handle(Object event) {
AuthenticationFailureBadCredentialsEvent loginFailureEvent = (AuthenticationFailureBadCredentialsEvent) event;
        Object name = loginFailureEvent.getAuthentication().getPrincipal();

        if(principal instanceof org.springframework.security.userdetails.ldap.LdapUserDetailsImpl){
            out.("LDAPUser: " + user.getUsername() + " failed login");
//do you thing here
        }
    }    
}
XML中的

绑定:

<b:bean id="loginFailureEventListener" class="com.foo.bar.support.event.LoginFailureEventListener">
    <b:property name="eventDispatcher" ref="eventDispatcher"/>
</b:bean>

修改 您可以扩展AuthenticationProcessingFilter并覆盖onUnsuccessfulAuthentication方法:

public class CustomAuthenticationProcessingFilter extends AuthenticationProcessingFilter {
    private LoginDao loginDao;

    @Override
    protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException {
        super.onSuccessfulAuthentication(request, response, authResult);    
        request.getSession().setAttribute("wrong", -1); 
    }

    protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        super.onUnsuccessfulAuthentication(request, response, authException);
        String username = (String) authException.getAuthentication().getPrincipal();
        if(username.length() > 0){
            Login login = loginDao.read(username);
            if(login != null){
                request.getSession().setAttribute("wrong", login.getFailedLoginAttempts());
                request.getSession().setAttribute("attempts", Login.MAX_FAILED_LOGIN_ATTEMPTS);
            }else{
                request.getSession().setAttribute("wrong", 100);
            }
        }else{
            request.getSession().setAttribute("wrong", -1);
        }
    }

    public void setLoginDao(LoginDao loginDao) {
        this.loginDao = loginDao;
    }
}

以XML格式分区:

<!-- Custom AuthenticationProcessingFilter with Callbacks -->
<authentication-manager alias="authenticationManagerAlias"/>
<b:bean id="authenticationProcessingFilter" name="authenticationProcessingFilter" class="com.foo.bat.support.event.CustomAuthenticationProcessingFilter"> 
    <b:property name="authenticationManager" ref="authenticationManagerAlias"/>
    <b:property name="authenticationFailureUrl" value="/login.do"/>
    <b:property name="filterProcessesUrl" value="/j_spring_security_check"/>
    <b:property name="defaultTargetUrl" value="/index.html"/>
    <!-- loginDao is a HibernateDao that reads logins an write wrong attempts to DB -->
    <b:property name="loginDao"><b:ref bean="loginDao"/></b:property>
    <custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />          
</b:bean>

现在您可以将此过滤器放在filterChainProxy

在这里寻找灵感 http://www.harinair.com/2010/02/spring-acegi-security-account-lockout/

答案 1 :(得分:1)

什么锁定功能?您是否了解LDAP密码策略扩展,它可以为您管理各种类似的内容?例如几次登录失败后锁定,密码到期/锁定/强制重置,密码质量策略,......