spring boot shiro 获取在线用户和踢出用户!

shiro工作图:

springboot在线打开excel并在线编辑 springboot在线用户_ci

介绍:

subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。

securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。它包含下面的认证器和授权器。

authenticator:认证器,主体进行认证最终通过authenticator进行的。 

authorizer:授权器,主体进行授权最终通过authorizer进行的。

sessionManager:web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。可以实现单点登录。

SessionDao:  通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。

cache Manager:缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。

realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。(它的主要目的是与数据库打交道,查询数据库中的认证的信息(比如用户名和密码),查询授权的信息(比如权限的code等,所以这里可以理解为调用数据库查询一系列的信息,一般情况下在项目中采用自定义的realm,因为不同的业务需求不一样))

注意:在realm中存储授权和认证的逻辑。

写在前面,使用spring boot apache shiro获取在线用户和对在线用户进行管理,主要是通过EnterpriseCacheSessionDAO
的CRUD,知道了shrio操作用户的类就可以继承它,使用自己的CRUD操作用户了。

思路:
1、使用自己的类继承shiro默认的CRUD类EnterpriseCacheSessionDAO
2、设置bean sessionDAO
3、设置bean SessionManager 将sessionDAO配置到sessionManage
4、设置bean securityManager 将sessionManger配置到securityManager

/**
  * <pre>
  *  主要定义了在缓存中保存session,更新,删除,读取,获取所有的集合等操作。
  * </pre>
  * <small> 2018/12/24 | eriz</small>
  */
 public class RedisSessionDAO extends EnterpriseCacheSessionDAO {    /**
      * session 名称
      */
     private String activeSessionsCacheName;    public RedisSessionDAO(String activeSessionsCacheName) {
         this.activeSessionsCacheName = activeSessionsCacheName;
     }    @Override
     public String getActiveSessionsCacheName() {
         return this.activeSessionsCacheName;
     }
 } /**
  * <pre>
  *
  * </pre>
  * <small> 2018/12/24 | eriz</small>
  */
 @Component
 @ConfigurationProperties(prefix = "eriz.shiro")
 public class ShiroProperties {
     //自定义session名称,避免与tomcat或者其他session默认的名称重名
     private String sessionKeyPrefix = "eriz:session";
     private String jsessionidKey = "SESSION";    public String getSessionKeyPrefix() {
         return sessionKeyPrefix;
     }    public void setSessionKeyPrefix(String sessionKeyPrefix) {
         this.sessionKeyPrefix = sessionKeyPrefix;
     }    public String getJsessionidKey() {
         return jsessionidKey;
     }    public void setJsessionidKey(String jsessionidKey) {
         this.jsessionidKey = jsessionidKey;
     }
 }接下来是在shiroConfig类中配置sessionDAO与sessionManager、securityManager
 /**
      * 设置sessionDAO
      * @param config
      * @return
      */
     @Bean
     SessionDAO sessionDAO(ShiroProperties config){
         RedisSessionDAO sessionDAO = new RedisSessionDAO(config.getSessionKeyPrefix());
         return sessionDAO;
     } /**
      * 设置sessionManager
      * @param sessionDAO
      * @return
      */
     @Bean
     public SessionManager sessionManager(SessionDAO sessionDAO) {
         DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();        Collection<SessionListener> sessionListeners = new ArrayList<SessionListener>();
         sessionListeners.add(new BDSessionListener());//这里的BDsessionListener实现了SessionListener接口,主要用于监听session的开始、停止与过期时间
         sessionManager.setSessionListeners(sessionListeners);
         sessionManager.setSessionDAO(sessionDAO);
         return sessionManager;
     } /**
      * 配置securityManager
      * @param sessionManager
      * @param authenticator
      * @param authorizer
      * @return
      */
     @Bean("securityManager")
     public DefaultWebSecurityManager getManager(SessionManager sessionManager,Authenticator authenticator,Authorizer authorizer) {
         DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
         // 使用自己的realm
         manager.setAuthenticator(authenticator);
         manager.setAuthorizer(authorizer);
 //        manager.setCacheManager();
         manager.setSessionManager(sessionManager);
         return manager;
     }

配置sessionDAO已经完成了,接下来测试获取数据
获取在线用户主要是Collection<Session> sessions = sessionDAO.getActiveSessions();
session中包含了id、host、lastAccesTime、startTimestamp、timeout等数据

@Autowired
     private SessionDAO sessionDAO;    //获取在线用户信息
     @Override
     public List<OnlineDo> list() {
         //数据量大时通过 page分页
         Collection<Session> sessions = sessionDAO.getActiveSessions();
         List<OnlineDo> list = new ArrayList<>();
         for (Session session : sessions) {
             if (session == null) continue;
             OnlineDo onlineDo = new OnlineDo();
             UserDo userDo = new UserDo();
             //principalCollection 身份
             SimplePrincipalCollection principalCollection = new SimplePrincipalCollection();
             if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) {
                 continue;
             } else {
                 principalCollection = (SimplePrincipalCollection) session
                         .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                 userDo = (UserDo) principalCollection.getPrimaryPrincipal();
                 onlineDo.setUsername(userDo.getUsername());
             }
             onlineDo.setId(session.getId().toString());
             onlineDo.setHost(session.getHost());
             onlineDo.setLastAccessTime(session.getLastAccessTime());
             onlineDo.setStartTimestamp(session.getStartTimestamp());
             onlineDo.setTimeout(session.getTimeout());
             list.add(onlineDo);
         }
         return list;
     }//踢出用户
@Override
public boolean removeSession(String ids) {
    //read session by id
    Session session = sessionDAO.readSession(ids);//通过readSession读取session,然后调用delete删除
    sessionDAO.delete(session);
    return true;
}
@Override
public boolean removeSession(String ids) {
    //read session by id
    Session session = sessionDAO.readSession(ids);//通过readSession读取session,然后调用delete删除
    sessionDAO.delete(session);
    return true;
}

整个获取在线用户和踢出用户已完成