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

问题描述

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

解决方法

验证由LDAP完成,但是您要在ldap用户登录后锁定它。 如果您使用spring 2.5,则可以对InitializingBean进行自定义实现,并检查主体是否为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,AuthenticationException authException) throws IOException {
        super.onUnsuccessfulAuthentication(request,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/     ,有什么锁定功能?您是否知道LDAP密码策略扩展,它可以为您管理所有此类内容?例如多次失败登录后锁定,密码到期/锁定/强制重置,密码质量策略,...