Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Security 记录登录时间和会话持续时间-Java-Spring安全性_Security_Spring_Login_Usage Statistics - Fatal编程技术网

Security 记录登录时间和会话持续时间-Java-Spring安全性

Security 记录登录时间和会话持续时间-Java-Spring安全性,security,spring,login,usage-statistics,Security,Spring,Login,Usage Statistics,我正在开发一个webapp,它使用Spring安全性作为安全层 对我们来说,一个重要的特性是知道哪个用户正在访问应用程序,以及他们在应用程序上花费了多少时间 我不知道该怎么处理。是否有其他框架处理此类使用统计数据 有没有办法使用SpringSecurity本身来处理它 //我正在阅读更多关于SpringSecurity的文章,它的过滤器似乎可以帮助我。任何进展都将在此处共享。也许您正在寻找类似以下内容: 实用工具,用于跟踪站点上的当前用户以及他们的详细位置。这允许您跟踪整个站点的“点击流”或“流

我正在开发一个webapp,它使用Spring安全性作为安全层

对我们来说,一个重要的特性是知道哪个用户正在访问应用程序,以及他们在应用程序上花费了多少时间

我不知道该怎么处理。是否有其他框架处理此类使用统计数据

有没有办法使用SpringSecurity本身来处理它


//我正在阅读更多关于SpringSecurity的文章,它的过滤器似乎可以帮助我。任何进展都将在此处共享。

也许您正在寻找类似以下内容:

实用工具,用于跟踪站点上的当前用户以及他们的详细位置。这允许您跟踪整个站点的“点击流”或“流量路径”


我认为我能想到的解决方案之一是使用HttpSessionListener,如果您实现了一个会话侦听器,您可以捕获创建和销毁新用户会话的时间,您可以利用spring安全上下文持有者来获取登录用户的uniquename/userid

我在想这样的事情

 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会话从未失效,那么您将得到一些没有结束时间的会话

  • 如果你能温和地促使你的用户群一直注销,这是一个很好的做法(尽管不是一个实用的解决方案)
  • 您可以在加载时检查用户是否正在离开您的域,或者使用windows关闭按钮关闭窗口并触发会话失效以捕获结束时间
更新

您是对的,我认为您可以使用spring应用程序事件机制,将其添加到您的web.xml中,此侦听器发布HTTP会话事件,否则即使您实现ApplicationListener,您也无法访问会话事件

    <listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
  </listener>
  @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 () );
    }


}

}

org.springframework.security.web.session.HttpSessionEventPublisher
现在添加一个实现ApplicationListener的新类

    <listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
  </listener>
  @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 () );
    }


}

}
@服务
公共类ApplicationSecurityListener实现ApplicationListener
{
@凌驾
ApplicationEvent上的公共无效(ApplicationEvent事件)
{
if(授权失败事件的事件实例)
{
AuthorizationFailureEvent AuthorizationFailureEvent=(AuthorizationFailureEvent)事件;
System.out.println(“未授权:+授权失败事件”);
}
else if(AuthenticationFailureBadCredentialsEvent的事件实例)
{
AuthenticationFailureBadCredentialsEvent badCredentialsEvent=(AuthenticationFailureBadCredentialsEvent)事件;
System.out.println(“badCredentials:+badCredentialsEvent”);
}
//登录成功事件
else if(AuthenticationSuccessEvent的事件实例)
{
AuthenticationSuccessEvent AuthenticationSuccessEvent=(AuthenticationSuccessEvent)事件;
//这将提供用户id和密码,但没有会话,get source在安全上下文中拥有所有用户信息
System.out.println(“AuthenticationSuccessEvent:+AuthenticationSuccessEvent.getSource());
}
//如果将HttpSessionEventPublisher添加到web.xml,将发布此事件
else if(SessionDestroyedEvent的事件实例)
{
SessionDestroyedEvent SessionEvent=(SessionDestroyedEvent)事件;
System.out.println(“SessionDestroyedEvent:+sessionvent.getId());
//如果会话不为空,则加载该会话
if(sessionvent.getSecurityContext()!=null)
{
System.out.println(“SessionDestroyedEvent:+SessionEvent.getSecurityContext().getAuthentication().getName());
//使用endTime更新会话
}
}
其他的
{
//System.out.println(“未定义:+event.getClass().getName());
}
}
}

还有另一个事件,如果您想自己捕获注销,您可以实现LogoutHandler,它允许您访问logut事件。

Hm,不确定这是否是一个好的选择。似乎OpenSymphony已经关门了,这个项目已经停止了。似乎Spring安全过滤器允许我在用户登录和注销时注册。解决方案是使用安全过滤器将用户ID、登录时间和注销时间持久化到数据库(如您所说)!