开发者

How to block LDAP user account in spring security without locking the LDAP user?

开发者 https://www.devze.com 2023-03-08 09:03 出处:网络
I\'m new to Spring Security. In my application authentication is done through Ldap.After Ldap authentication I want to handle failure and success events on login. I want to track login count in databa

I'm new to Spring Security. In my application authentication is done through Ldap.After Ldap authentication I want to handle failure and success events on login. I want to track login count in database for locking functionality. any body kn开发者_运维百科ows how to achieve this?


Authentication is done by LDAP but you want to lock the ldap user after he logged in.

If you use spring 2.5 you can make your custom implementation of a InitializingBean and check if principal is a LDAP user:

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;
}
}

And next implement this custom handle on your loginFailureEventListener (map this listener in your 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
        }
    }    
}

binding in XML:

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

EDIT: You can extend AuthenticationProcessingFilter and override the onUnsuccessfulAuthentication method:

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;
    }
}

Binning in 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>

Now you can put this filter in your filterChainProxy

Look here for inspiration http://www.harinair.com/2010/02/spring-acegi-security-account-lockout/


What locking functionality? Are you aware of the LDAP Password Policy extension, that manages all kinds of stuff like this for you? e.g. lockout after several unsuccessful logins, password expiry/lock/mandatory reset, password quality polices, ...

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号