Security 记录登录时间和会话持续时间-Java-Spring安全性
我正在开发一个webapp,它使用Spring安全性作为安全层 对我们来说,一个重要的特性是知道哪个用户正在访问应用程序,以及他们在应用程序上花费了多少时间 我不知道该怎么处理。是否有其他框架处理此类使用统计数据 有没有办法使用SpringSecurity本身来处理它Security 记录登录时间和会话持续时间-Java-Spring安全性,security,spring,login,usage-statistics,Security,Spring,Login,Usage Statistics,我正在开发一个webapp,它使用Spring安全性作为安全层 对我们来说,一个重要的特性是知道哪个用户正在访问应用程序,以及他们在应用程序上花费了多少时间 我不知道该怎么处理。是否有其他框架处理此类使用统计数据 有没有办法使用SpringSecurity本身来处理它 //我正在阅读更多关于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关闭按钮关闭窗口并触发会话失效以捕获结束时间
<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、登录时间和注销时间持久化到数据库(如您所说)!