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

–>

技术交流群:365814763

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

shiro工作图:

介绍:

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;
}

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

本文来源 互联网收集,文章内容系作者个人观点,不代表 本站 对观点赞同或支持。如需转载,请注明文章来源,如您发现有涉嫌抄袭侵权的内容,请联系本站核实处理。

© 版权声明

相关文章