Вести учет времени входа и продолжительности сеанса - Java - Spring Security - PullRequest
6 голосов
/ 18 декабря 2011

Я разрабатываю веб-приложение, которое использует Spring Security в качестве слоя безопасности.

Одна важная функция для нас - это знать, какой пользователь обращается к приложению и сколько времени он на него тратит.

Я не уверен, как с этим бороться.Есть ли какая-то другая структура, которая имеет дело с такого рода статистикой использования?

Есть ли какой-то способ использовать саму Spring Security для решения этой проблемы?

// Я читаю больше о Spring Securityи кажется, что его фильтры могут помочь мне.Любой прогресс будет сообщаться здесь.

Ответы [ 2 ]

6 голосов
/ 19 декабря 2011

Я думаю, что одним из решений, которое я могу придумать, является использование HttpSessionListener. Если вы реализуете слушатель Session, вы можете фиксировать время, когда и когда создается и уничтожается новый пользовательский сеанс, вы можете использовать свой весенний держатель контекста безопасности, чтобы захватить уникальное имя / ИД пользователя вошедшего в систему пользователя

Я думаю, что-то вроде этого

 public class SesssionListenerImpl implements HttpSessionListener 
 {
  @Override
  public void sessionCreated(HttpSessionEvent httpSessionEvent) 
  {
      String uniqueName =     SecurityContextHolder.getContext().getAuthentication().getName();
     String sessionId = httpSessionEvent.getSession().getId();
     long beginTimeInSeconds = System.currentTimeMillis()/1000;
//create a record and persist to data base with sessionId, uniquename, sessionBeginTime

}

@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) 
{

    SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    httpSessionEvent.getSession().getId();
    long endTime = System.currentTimeMillis()/1000;
    //load the record based on sessionId
    //update the record with sessionEndTime
}
}

При этом есть несколько недостатков в этом подходе. Если сеанс HTTP никогда не будет признан недействительным, вы получите несколько сеансов без времени окончания.

  • Если бы вы могли аккуратно подтолкнуть свою пользовательскую базу, чтобы все время выходить из системы, как хорошая практика (хотя это и не практическое решение)
  • Вы можете сделать это при загрузке тела и проверить, покидает ли пользователь ваш домен или использует кнопку закрытия окна, чтобы закрыть окно и запустить недействительный сеанс для захвата времени окончания

UPDATE

Вы правы, я думаю, что вы могли бы использовать механизм событий приложений Spring, чтобы сделать это, добавив это в ваш web.xml. Этот слушатель публикует события сеанса HTTP, иначе вы не сможете получить доступ к событиям сеанса, даже если вы реализуете ApplicationListener.

    <listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
  </listener>

Теперь добавьте новый класс, который реализует ApplicationListener

  @Service
 public class ApplicationSecurityListener implements ApplicationListener<ApplicationEvent>
 {
  @Override
  public void onApplicationEvent(ApplicationEvent event)
  {

    if ( event instanceof AuthorizationFailureEvent )
    {
        AuthorizationFailureEvent authorizationFailureEvent = ( AuthorizationFailureEvent ) event;
        System.out.println ( "not authorized:" + authorizationFailureEvent );
    }
    else if ( event instanceof AuthenticationFailureBadCredentialsEvent )
    {
        AuthenticationFailureBadCredentialsEvent badCredentialsEvent = ( AuthenticationFailureBadCredentialsEvent ) event;
        System.out.println ( "badCredentials:" + badCredentialsEvent );
    }
            //login success event
    else if ( event instanceof AuthenticationSuccessEvent )
    {
        AuthenticationSuccessEvent authenticationSuccessEvent = ( AuthenticationSuccessEvent ) event;
        //this will provide user id and password but no session, get source has all the user information in security context
        System.out.println ( "AuthenticationSuccessEvent:" + authenticationSuccessEvent.getSource() );
    }
    //this event will published if you add the HttpSessionEventPublisher to web.xml
    else if ( event instanceof SessionDestroyedEvent )
    {
        SessionDestroyedEvent sessinEvent = ( SessionDestroyedEvent ) event;
        System.out.println ( "SessionDestroyedEvent:" + sessinEvent.getId() );
        //load session if it is not empty
        if(sessinEvent.getSecurityContext() != null)
        {
            System.out.println ( "SessionDestroyedEvent:" + sessinEvent.getSecurityContext().getAuthentication().getName() );
            //update the session with endTime
        }
    }
    else
    {
        //System.out.println ( "undefined: " + event.getClass ().getName () );
    }


}

}

Существует другое событие, если вы хотите захватить выход из системы самостоятельно. Вы можете реализовать LogoutHandler, который дает вам доступ к событию выхода из системы.

0 голосов
/ 19 декабря 2011

Может быть, вы ищете что-то вроде этого:

Утилита для отслеживания текущих пользователей на вашем сайте, и где они были в деталях. Это позволяет вам отслеживать «потоки кликов» или «пути трафика» на вашем сайте.

http://www.quartzscheduler.org/clickstream/

...