How to block LDAP user account in spring security without locking the LDAP user?
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, ...
精彩评论