Как я могу ограничить попытки входа в систему Spring Безопасность?

Существует ли какая-либо конфигурация или доступный модуль в Spring Security для ограничения попыток входа (в идеале, я хотел бы увеличить время ожидания между последующими неудачными попытками)? Если нет, какую часть API следует использовать для этого?

Ответы

Ответ 1

Внедрить AuthenticationFailureHandler, который обновляет счет/время в БД. Я бы не стал рассчитывать на использование сеанса, потому что злоумышленник все равно не будет отправлять файлы cookie.

Ответ 3

Как предложил Роб Винч в http://forum.springsource.org/showthread.php?108640-Login-attempts-Spring-security, я просто подклассифицировал DaoAuthenticationProvider (который также мог быть выполнен с использованием аспекта как Ritesh предлагает) ограничить количество неудачных логинов, но вы также можете утверждать и предварительные условия:

public class LimitingDaoAuthenticationProvider extends DaoAuthenticationProvider {
  @Autowired
  private UserService userService;
    @Override
    public Authentication authenticate(Authentication authentication)
        throws AuthenticationException {
      // Could assert pre-conditions here, e.g. rate-limiting
      // and throw a custom AuthenticationException if necessary

      try {
        return super.authenticate(authentication);
      } catch (BadCredentialsException e) {
        // Will throw a custom exception if too many failed logins have occurred
        userService.recordLoginFailure(authentication);
        throw e;
      }
   }
}

В Spring config XML просто укажите этот bean:

<beans id="authenticationProvider"   
    class="mypackage.LimitingDaoAuthenticationProvider"
    p:userDetailsService-ref="userDetailsService"
    p:passwordEncoder-ref="passwordEncoder"/>

<security:authentication-manager>
    <security:authentication-provider ref="authenticationProvider"/>
</security:authentication-manager>

Обратите внимание, что я думаю, что решения, которые полагаются на доступ к свойствам AuthenticationException authentication или extraInformation (например, реализация AuthenticationFailureHandler), вероятно, не будут использоваться, поскольку эти свойства теперь устарели (в Spring Безопасность 3.1, по крайней мере).

Ответ 4

Недавно я реализовал аналогичную функцию для мониторинга сбоев входа в систему с использованием JMX. Пожалуйста, см. Код в ответе на вопрос Опубликовать уведомления JMX при использовании Spring без NotificationPublisherAware. Аспект метода аутентификации поставщика проверки подлинности обновляет MBean и работает с прослушивателем уведомлений (код, который не показан в этом вопросе) для блокировки пользователя и IP-адреса, отправки предупреждающих сообщений и даже приостановки регистрации, если ошибки превышают пороговое значение.

Edit
Как и мой ответ на вопрос Spring безопасность 3: сохраните информацию об аутентификации в базе данных, я думаю, что захват события сбоя аутентификации (в отличие от настройки обработчика) и сохранение информации в базе данных также будет работать, и он также сохранит код.

Ответ 5

Вы также можете использовать службу, которая реализует ApplicationListener <AuthenticationFailureBadCredentialsEvent> для обновления записи в БД.

Смотрите события приложения spring.

Ответ 6

Вот моя реализация, надеюсь, помощь.

  • Создайте таблицу для хранения любых недопустимых попыток входа в систему.
  • Если недопустимые попытки > max разрешены, установите для параметра UserDetail.accountNonLocked значение false
  • Spring Безопасность будет обрабатывать процесс блокировки. (см. AbstractUserDetailsAuthenticationProvider)

Last, расширяет DaoAuthenticationProvider и интегрирует логику внутри.

@Component("authenticationProvider")
public class YourAuthenticationProvider extends DaoAuthenticationProvider {

@Autowired
UserAttemptsDao userAttemptsDao;

@Override
public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {

  try {

    Authentication auth = super.authenticate(authentication);

    //if corrent password, reset the user_attempts
    userAttemptsDao.resetFailAttempts(authentication.getName());

    return auth;

  } catch (BadCredentialsException e) { 

    //invalid login, update user_attempts, set attempts+1 
    userAttemptsDao.updateFailAttempts(authentication.getName());

    throw e;

  } 

}


}

Для полного исходного кода и реализации см. это Spring Пример попыток входа в лимит безопасности,

Ответ 7

  • создать таблицу для хранения значений неудачных попыток ex: user_attempts
  • Запись пользовательского прослушивателя событий

     @Component("authenticationEventListner")
     public class AuthenticationEventListener
     implements AuthenticationEventPublisher
     {
     @Autowired
     UserAttemptsServices userAttemptsService;
    
     @Autowired
     UserService userService;
    
     private static final int MAX_ATTEMPTS = 3;
     static final Logger logger = LoggerFactory.getLogger(AuthenticationEventListener.class);   
    
     @Override
     public void publishAuthenticationSuccess(Authentication authentication) {          
     logger.info("User has been logged in Successfully :" +authentication.getName());       
     userAttemptsService.resetFailAttempts(authentication.getName());       
     }
    
    
     @Override
     public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {               
     logger.info("User Login failed :" +authentication.getName());      
     String username = authentication.getName().toString();
     UserAttempts userAttempt =  userAttemptsService.getUserAttempts(username);
     User userExists = userService.findBySSO(username);
    
     int attempts = 0;
     String error = "";
     String lastAttempted = "";             
     if (userAttempt == null) {     
    
        if(userExists !=null ){                     
        userAttemptsService.insertFailAttempts(username);   }       
      } else {                
          attempts = userAttempt.getAttempts();
          lastAttempted = userAttempt.getLastModified();
        userAttemptsService.updateFailAttempts(username, attempts);         
        if (attempts + 1 >= MAX_ATTEMPTS) {                 
            error = "User account is locked! <br>Username : "
                           + username+ "<br>Last Attempted on : " + lastAttempted;          
        throw new LockedException(error);           
        }                                   
      }
    throw new BadCredentialsException("Invalid User Name and Password");
    
    
    
     }
      }
    

Конфигурация 3.Security

         1) @Autowired
         @Qualifier("authenticationEventListner")
         AuthenticationEventListener authenticationEventListner;

      2) @Bean
         public AuthenticationEventPublisher authenticationListener() {
         return new AuthenticationEventListener();
         }
      3) @Autowired
         public void 
         configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
         //configuring custom user details service
         auth.authenticationProvider(authenticationProvider);
         // configuring login success and failure event listener
         auth.authenticationEventPublisher(authenticationEventListner);
         }