Как заблокировать учетную запись пользователя LDAP в spring Security без блокировки пользователя LDAP?

#java #ldap #spring-security

#java #ldap #spring-безопасность

Вопрос:

Я новичок в Spring Security. В моем приложении аутентификация выполняется через Ldap .После аутентификации Ldap я хочу обрабатывать события сбоя и успеха при входе в систему. Я хочу отслеживать количество входов в базу данных для функциональности блокировки. кто-нибудь знает, как этого добиться?

Ответ №1:

Аутентификация выполняется 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, 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. @Michel: Спасибо за предложение. Я хочу отслеживать попытки входа в систему с использованием loginCounter в базе данных. Увеличение счетчика при попытке пользователя пройти аутентификацию. Сбросьте счетчик на 0 после успешной аутентификации пользователя. итак, после AuthenticationFailureBadCredentials события, как я могу перенаправить страницу на страницу входа с сообщением о заблокированной учетной записи?

2. @amit31 Я думаю, вам нужно обратиться к пользовательской AuthenticationProcessingFilter функции и переопределить ее onUnsuccessfulAuthentication здесь у вас есть request объект, в который вы можете поместить некоторые атрибуты (request.getSession().setAttribute("locked",true) . В простом JSP вы можете прочитать эти атрибуты и отобразить некоторые сообщения. Пожалуйста, дайте мне знать, если вам нужен пример…

3. @Michel: извините за поздний ответ. Я новичок во всех этих вещах. не могли бы вы, пожалуйста, привести пример, чтобы я мог лучше это понять.

4. @amit31 Добавьте пример к моему ответу

5. @Michel: Я не хочу блокировать пользователя ldap. я хочу заблокировать пользователя с помощью базы данных. В нашем приложении аутентификация выполняется через ldap. После ldap он повторно запрашивает данные userdetails из таблицы. итак, после сбоя аутентификации ldap я проверяю lockingcounter в базе данных. если logincounter> 5, то я хочу отобразить сообщение как заблокированную учетную запись пользователя на странице входа. итак, где я должен добавить ‘AuthenticationProcessingFilter’ в свой код?

Ответ №2:

Какие функции блокировки? Известно ли вам о расширении политики паролей LDAP, которое управляет всеми видами подобных вещей для вас? например, блокировка после нескольких неудачных входов в систему, истечение срока действия пароля / блокировка / обязательный сброс, политика качества пароля, …

Комментарии:

1. @EJP, спасибо за предложение, в принципе, я хочу заблокировать учетную запись с помощью базы данных. я не хочу блокировать учетную запись через ldap. Мой подход заключается в том, что попытки входа в систему можно отслеживать с помощью счетчика в базе данных. Увеличьте счетчик, как только пользователь попытается пройти аутентификацию. Сбросьте счетчик на 0 после успешной аутентификации пользователя. итак, сначала проверьте пользователя и пароль с помощью ldap. после аутентификации (сбой или успех) выполняется через ldap, я хочу установить счетчик в базе данных и после пяти сбоев заблокировать учетную запись пользователя. итак, после завершения аутентификации ldap, как я могу обработать функцию блокировки?

2. @amit31 зачем делать все это самому? LDAP сделает в точности все это, без необходимости писать строку кода.

3. @EJP Я думаю, что он не хочет блокировать всего пользователя LDAP, а только для своего приложения. возможно ли это с помощью LDAP (путем блокирования определенных запросов?) или это делается с блокировкой определенных ролей (групп) для пользователя LDAP?

4. @michel нет никаких доказательств этой гипотезы, и это было бы плохой практикой обеспечения безопасности.

5. @michel: @ EJB: Возможно ли добавить какой-либо фильтр перед аутентификацией ldap?. итак, изначально он переходит к filter и проверяет, больше ли loginitems 5 или нет. если количество элементов входа больше 5, то аутентификация ldap не выполняется, а если количество элементов входа меньше 5, то выполняется аутентификация Ldap.