Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
spring安全,如何使用户的所有会话过期_Spring_Spring Security_Weakhashmap - Fatal编程技术网

spring安全,如何使用户的所有会话过期

spring安全,如何使用户的所有会话过期,spring,spring-security,weakhashmap,Spring,Spring Security,Weakhashmap,我必须解决以下场景,在SpringSecurity3.2.5-RELEASE中,使用在wildfly 8.1上运行Java1.7的SpringCore4.1.2-RELEASE应用程序 用户“bob”登录 管理员删除“bob” 如果“bob”注销,他将无法登录。但他目前的治疗仍然很活跃 我想把鲍勃踢出去 //this doesn't work for (final SessionInformation session : sessionRegistry.getAllSessions(use

我必须解决以下场景,在SpringSecurity
3.2.5-RELEASE
中,使用在wildfly 8.1上运行Java1.7的
SpringCore4.1.2-RELEASE
应用程序

  • 用户“bob”登录
  • 管理员删除“bob”
  • 如果“bob”注销,他将无法登录。但他目前的治疗仍然很活跃
  • 我想把鲍勃踢出去

    //this doesn't work
    for (final SessionInformation session :    sessionRegistry.getAllSessions(user, true)) {
             session.expireNow();
    }
    
  • 添加应用程序事件侦听器以跟踪
    HttpSessionCreatedEvent
    HttpSessionDestroyedEvent
    ,并将其注册为
    ApplicationListener
    ,并将SessionId缓存到HttoSession
  • (可选)添加您自己的ApplicationEvent类
    AskToExpireSessionEvent
    -
  • 在用户管理服务中,向
    SessionRegistry
    ApplicationEventPublisher
    添加依赖项,以便您可以列出当前活动的用户会话,并找到您正在查找的用户的活动会话(因为可能有很多),即“bob”
  • 删除用户时,为其每个会话分派一个
    AskToExpireSessionEvent
  • 使用弱引用HashMap跟踪会话
  • 用户服务:

         @Service
         public class UserServiceImpl implements UserService {
    
          /** {@link SessionRegistry} does not exists in unit tests */
          @Autowired(required = false)
          private Set<SessionRegistry> sessionRegistries;
    
    
          @Autowired
          private ApplicationEventPublisher publisher;
    
    
         /**
          * destroys all active sessions.
          * @return <code>true</code> if any session was invalidated^
          * @throws IllegalArgumentException
          */
          @Override
          public boolean invalidateUserByUserName(final String userName) {
                  if(null == StringUtils.trimToNull(userName)) {
                          throw new IllegalArgumentException("userName must not be null or empty");
                  }
                  boolean expieredAtLeastOneSession = false;
                  for (final SessionRegistry sessionRegistry : safe(sessionRegistries)) {
                          findPrincipal: for (final Object principal : sessionRegistry.getAllPrincipals()) {
                                  if(principal instanceof IAuthenticatedUser) {
                                          final IAuthenticatedUser user = (IAuthenticatedUser) principal;
                                          if(userName.equals(user.getUsername())) {
                                                  for (final SessionInformation session : sessionRegistry.getAllSessions(user, true)) {
                                                          session.expireNow();
                                                          sessionRegistry.removeSessionInformation(session.getSessionId());
                                                          publisher.publishEvent(AskToExpireSessionEvent.of(session.getSessionId()));
                                                          expieredAtLeastOneSession = true;
                                                  }
                                                  break findPrincipal;
                                          }
                                  } else {
                                          logger.warn("encountered a session for a none user object {} while invalidating '{}' " , principal, userName);
                                  }
                          }
                  }
                  return expieredAtLeastOneSession;
          }
    
         }
    
         import org.springframework.context.ApplicationEvent;
    
         public class AskToExpireSessionEvent extends ApplicationEvent {
    
                 private static final long serialVersionUID = -1915691753338712193L;
    
                 public AskToExpireSessionEvent(final Object source) {
                         super(source);
                 }
    
                 @Override
                 public String getSource() {
                         return (String)super.getSource();
                 }
    
    
                 public static AskToExpireSessionEvent of(final String sessionId) {
                         return new AskToExpireSessionEvent(sessionId);
                 }
         }
    
    应用程序事件:

         @Service
         public class UserServiceImpl implements UserService {
    
          /** {@link SessionRegistry} does not exists in unit tests */
          @Autowired(required = false)
          private Set<SessionRegistry> sessionRegistries;
    
    
          @Autowired
          private ApplicationEventPublisher publisher;
    
    
         /**
          * destroys all active sessions.
          * @return <code>true</code> if any session was invalidated^
          * @throws IllegalArgumentException
          */
          @Override
          public boolean invalidateUserByUserName(final String userName) {
                  if(null == StringUtils.trimToNull(userName)) {
                          throw new IllegalArgumentException("userName must not be null or empty");
                  }
                  boolean expieredAtLeastOneSession = false;
                  for (final SessionRegistry sessionRegistry : safe(sessionRegistries)) {
                          findPrincipal: for (final Object principal : sessionRegistry.getAllPrincipals()) {
                                  if(principal instanceof IAuthenticatedUser) {
                                          final IAuthenticatedUser user = (IAuthenticatedUser) principal;
                                          if(userName.equals(user.getUsername())) {
                                                  for (final SessionInformation session : sessionRegistry.getAllSessions(user, true)) {
                                                          session.expireNow();
                                                          sessionRegistry.removeSessionInformation(session.getSessionId());
                                                          publisher.publishEvent(AskToExpireSessionEvent.of(session.getSessionId()));
                                                          expieredAtLeastOneSession = true;
                                                  }
                                                  break findPrincipal;
                                          }
                                  } else {
                                          logger.warn("encountered a session for a none user object {} while invalidating '{}' " , principal, userName);
                                  }
                          }
                  }
                  return expieredAtLeastOneSession;
          }
    
         }
    
         import org.springframework.context.ApplicationEvent;
    
         public class AskToExpireSessionEvent extends ApplicationEvent {
    
                 private static final long serialVersionUID = -1915691753338712193L;
    
                 public AskToExpireSessionEvent(final Object source) {
                         super(source);
                 }
    
                 @Override
                 public String getSource() {
                         return (String)super.getSource();
                 }
    
    
                 public static AskToExpireSessionEvent of(final String sessionId) {
                         return new AskToExpireSessionEvent(sessionId);
                 }
         }
    
    http会话缓存侦听器:

         import java.util.Map;
         import java.util.WeakHashMap;
    
         import javax.servlet.http.HttpSession;
    
         import org.slf4j.Logger;
         import org.slf4j.LoggerFactory;
         import org.springframework.beans.factory.annotation.Autowired;
         import org.springframework.context.ApplicationListener;
         import org.springframework.security.web.session.HttpSessionCreatedEvent;
         import org.springframework.security.web.session.HttpSessionDestroyedEvent;
         import org.springframework.stereotype.Component;
    
         import com.cb4.base.service.event.AskToExpireSessionEvent;
    
    
         @Component
         public class HttpSessionCachingListener {
    
                 private static final Logger logger = LoggerFactory.getLogger(HttpSessionCachingListener.class);
    
                 private final Map<String, HttpSession> sessionCache = new WeakHashMap<>();
    
                 void onHttpSessionCreatedEvent(final HttpSessionCreatedEvent event){
                         if (event != null && event.getSession() != null && event.getSession().getId() != null) {
                                 sessionCache.put(event.getSession().getId(), event.getSession());
                         }
                 }
    
                 void onHttpSessionDestroyedEvent(final HttpSessionDestroyedEvent event){
                         if (event != null && event.getSession() != null && event.getSession().getId() != null){
                                 sessionCache.remove(event.getSession().getId());
                         }
                 }
    
                 public void timeOutSession(final String sessionId){
                         if(sessionId != null){
                                 final HttpSession httpSession = sessionCache.get(sessionId);
                                 if(null != httpSession){
                                         logger.debug("invalidating session {} in 1 second", sessionId);
                                         httpSession.setMaxInactiveInterval(1);
                                 }
                         }
                 }
    
                 @Component
                 static class HttpSessionCreatedLisener implements ApplicationListener<HttpSessionCreatedEvent> {
    
                         @Autowired
                         HttpSessionCachingListener parent;
    
                         @Override
                         public void onApplicationEvent(final HttpSessionCreatedEvent event) {
                                 parent.onHttpSessionCreatedEvent(event);
                         }
                 }
    
                 @Component
                 static class HttpSessionDestroyedLisener implements ApplicationListener<HttpSessionDestroyedEvent> {
    
                         @Autowired
                         HttpSessionCachingListener parent;
    
                         @Override
                         public void onApplicationEvent(final HttpSessionDestroyedEvent event) {
                                 parent.onHttpSessionDestroyedEvent(event);
                         }
                 }
    
                 @Component
                 static class AskToTimeOutSessionLisener implements ApplicationListener<AskToExpireSessionEvent> {
    
                         @Autowired
                         HttpSessionCachingListener parent;
    
                         @Override
                         public void onApplicationEvent(final AskToExpireSessionEvent event) {
                                 if(event != null){
                                         parent.timeOutSession(event.getSource());
                                 }
                         }
                 }
    
         }
    
    import java.util.Map;
    导入java.util.WeakHashMap;
    导入javax.servlet.http.HttpSession;
    导入org.slf4j.Logger;
    导入org.slf4j.LoggerFactory;
    导入org.springframework.beans.factory.annotation.Autowired;
    导入org.springframework.context.ApplicationListener;
    导入org.springframework.security.web.session.httpsessioncreatevent;
    导入org.springframework.security.web.session.HttpSessionDestroyedEvent;
    导入org.springframework.stereotype.Component;
    导入com.cb4.base.service.event.AskToExpireSessionEvent;
    @组成部分
    公共类HttpSessionAchingListener{
    私有静态最终记录器Logger=LoggerFactory.getLogger(HttpSessionCachingListener.class);
    private final Map sessionCache=new WeakHashMap();
    void onHttpSessionCreatedEvent(最终HttpSessionCreatedEvent事件){
    if(event!=null&&event.getSession()!=null&&event.getSession().getId()!=null){
    sessionCache.put(event.getSession().getId(),event.getSession());
    }
    }
    HttpSessionDestroyedEvent无效(最终HttpSessionDestroyedEvent事件){
    if(event!=null&&event.getSession()!=null&&event.getSession().getId()!=null){
    remove(event.getSession().getId());
    }
    }
    public void timeOutSession(最终字符串sessionId){
    if(sessionId!=null){
    final-HttpSession-HttpSession=sessionCache.get(sessionId);
    if(null!=httpSession){
    debug(“在1秒内使会话{}无效”,sessionId);
    httpSession.setMaxInactiveInterval(1);
    }
    }
    }
    @组成部分
    静态类HttpSessionCreatedLisener实现ApplicationListener{
    @自动连线
    HttpSessionCacheGlistener父级;
    @凌驾
    ApplicationEvent上的公共无效(最终HttpSessionCreateEvent事件){
    父.onHttpSessionCreateEvent(事件);
    }
    }
    @组成部分
    静态类HttpSessionDestroyedLisener实现ApplicationListener{
    @自动连线
    HttpSessionCacheGlistener父级;
    @凌驾
    ApplicationEvent上的公共无效(最终HttpSessionDestroyeEvent事件){
    父.onHttpSessionDestroyedEvent(事件);
    }
    }
    @组成部分
    静态类AskToTimeOutSessionLisener实现ApplicationListener{
    @自动连线
    HttpSessionCacheGlistener父级;
    @凌驾
    ApplicationEvent上的公共无效(最终AskToExpireSessionEvent事件){
    如果(事件!=null){
    timeOutSession(event.getSource());
    }
    }
    }
    }
    
    使用java配置在扩展WebSecurity配置适配器的类中添加以下代码:

    并在配置(HttpSecurity http)方法中添加以下内容:

    另外,在自定义身份验证bean中设置registerSessionAuthenticationStratergy,如下所示:

        usernamePasswordAuthenticationFilter
                .setSessionAuthenticationStrategy( registerSessionAuthStr( ) );
    

    注意:在自定义身份验证bean中设置registerSessionAuthenticationStratergy会导致prinicpal列表被填充,因此当您尝试从sessionRegistry(sessionRegistry.getAllPrinicpals())获取所有prinicpal的列表时,该列表不是空的。

    请共享IAAuthenticationedUser,请问什么是IAAuthenticatedUser?