security - 记录登录时间和 session 持续时间 - Java - Spring Security

标签 security spring login usage-statistics

我正在开发一个使用 Spring Security 作为安全层的 webapp。

我们的一项重要功能是了解哪个用户正在访问该应用程序,以及他们在该应用程序上花费了多少时间。

我不知道如何处理它。是否有其他框架可以处理这种使用统计数据?

有什么办法可以使用Spring Security本身来处理吗?

//我正在阅读有关 Spring Security 的更多信息,似乎它的过滤器可以帮助我。任何进展都会在这里分享。

最佳答案

我认为我能想到的解决方案之一是使用 HttpSessionListener,如果您实现 Session 监听器,您可以捕获创建和销毁新用户 session 时的时间,您可以利用您的 spring 安全上下文持有者来获取登录用户的唯一名称/用户 ID

我在想这样的事情

 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 session 永远不会失效,那么您最终会得到一些没有结束时间的 session 。
  • 如果你可以温和地刺激你的用户群一直注销作为一个好习惯(虽然不是一个实用的解决方案)
  • 您可以在加载时执行正文并检查用户是否离开您的域或使用窗口关闭按钮关闭窗口并触发 session 无效以捕获结束时间

  • 更新

    您说得对,我认为您可以使用 spring 应用程序事件机制,将其添加到您的 web.xml,此监听器发布 HTTP session 事件,否则即使您实现 ApplicationListener,您也将无法访问 session 事件
        <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 使您可以访问注销事件。

    关于security - 记录登录时间和 session 持续时间 - Java - Spring Security,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8554346/

    相关文章:

    python - Python:在网站上登录

    security - 防止民意调查泛滥

    security - CWE vs CVE 在使用方面

    database - 查询 Postgresql 管理员权限

    ios - 隐藏 UITextField 密码

    java - MapStruct 根据目标类型映射正确的对象实例

    spring - 如何使用 Spring Security 登录页面传递附加参数

    spring - 在同一事务中保存后更新期间不会调用 @PreUpdate

    login - Google 全局登录如何运作?

    email - Web应用程序中 token 认证的最佳做法?