All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.hdis.framework.security.session.imp.RedisSessionServiceImpl Maven / Gradle / Ivy

There is a newer version: 1.3
Show newest version
package tech.hdis.framework.security.session.imp;

import com.google.gson.Gson;
import tech.hdis.framework.security.properties.SecuritySessionProperties;
import tech.hdis.framework.security.session.entity.Session;
import tech.hdis.framework.security.session.interfaces.SessionService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 基于redis实现的session管理
 *
 * @author 黄志文
 */
@Component
public class RedisSessionServiceImpl implements SessionService {

    private Gson gson = new Gson();

    private ThreadLocal sessionThreadLocal = new ThreadLocal<>();

    private Integer refreshStepSize = 60;

    @Resource
    protected SecuritySessionProperties securitySessionProperties;
    @Resource
    protected RedisSessionClient redisSessionClient;

    /**
     * 新增或修改session;
     */
    @Override
    public void saveOrUpdateSession(Session session) {
        if (StringUtils.isBlank(session.getSessionId())) {
            this.saveSession(session);
        } else {
            this.updateSession(session);
        }
    }

    /**
     * 新增session
     */
    private void saveSession(Session session) {
        session.setSessionId(UUID.randomUUID().toString().replaceAll("-", ""));
        session.setLastAccessedTime(new Date());
        redisSessionClient.set(session.getSessionId(), gson.toJson(session), securitySessionProperties.timeout);
        sessionThreadLocal.set(session);
    }

    /**
     * 修改session
     */
    private void updateSession(Session session) {
        Session oldSession = getSession();
        if (session == null || oldSession == null || !session.getSessionId().equals(oldSession.getSessionId())) {
            return;
        }
        BeanUtils.copyProperties(session, oldSession);
        oldSession.setLastAccessedTime(new Date());
        redisSessionClient.set(oldSession.getSessionId(), gson.toJson(oldSession), securitySessionProperties.timeout);
        sessionThreadLocal.set(oldSession);
    }

    /**
     * 绑定当前线程session
     *
     * @param sessionId
     */
    @Override
    public void bindingSession(String sessionId) {
        String sessionJsonString = redisSessionClient.get(sessionId);
        if (StringUtils.isNotBlank(sessionJsonString)) {
            Session session = gson.fromJson(sessionJsonString, Session.class);
            sessionThreadLocal.set(session);
        } else {
            sessionThreadLocal.remove();
        }
    }

    /**
     * 刷新session,将最后访问时间与当前时间同步;
     */
    @Override
    public void refresh() {
        Session session = getSession();
        if (session == null) {
            return;
        }
        //避免高并发量,1分钟执行一次redis写入
        Calendar refreshStep = Calendar.getInstance();
        refreshStep.setTime(session.getLastAccessedTime());
        refreshStep.add(Calendar.SECOND, refreshStepSize);
        if (new Date().after(refreshStep.getTime())) {
            //执行写入
            redisSessionClient.del(session.getSessionId());
            session.setLastAccessedTime(new Date());
            redisSessionClient.set(session.getSessionId(), gson.toJson(session), securitySessionProperties.timeout);
            sessionThreadLocal.set(session);
        }
    }

    /**
     * 刷新session
     * 1:判断当前session是否失效
     * 2:处理单端单用户登录(一个‘用户账号’的‘手机端’只能有一个在线)
     *
     * @return 是否登录成功
     */
    @Override
    public Boolean flush() {
        return true;
        /*
        Session session = getSession();
        if (session == null) {
            return false;
        }
        //获得此username所有的session(username格式“mobile:username”)
        Object sobj = this.sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, (String) session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME));
        //强制类型转化,普通转化无效
        Map sMap = (Map) sobj;
        //删除当前账户的所有session,只保留当前session,达到单端单用户登录
        for (String key : sMap.keySet()) {
            if (!tokenThreadLocal.get().equals(key)) {
                this.sessionRepository.delete(key);
            }
        }
        return true;
        */
    }

    /**
     * 登出,需要已登录状态
     */
    @Override
    public void logout() {
        Session session = getSession();
        if (session == null) {
            return;
        }
        redisSessionClient.del(session.getSessionId());
    }

    /**
     * 获取当前Session
     */
    @Override
    public Session getSession() {
        return sessionThreadLocal.get();
    }

    /**
     * session是否失效
     */
    @Override
    public boolean isExpired() {
        return getSession() == null;
    }

    /**
     * 是否具有角色
     *
     * @param roles 角色字符串
     * @return 是否具有角色
     */
    @Override
    public Boolean hasRoles(String[] roles) {
        Session session = getSession();
        if (session == null) {
            return false;
        }
        Set sessionRoles = session.getRoles();
        if (sessionRoles != null && roles != null) {
            if (roles.length != 0 && "".equals(roles[0])) {
                return true;
            } else {
                return sessionRoles.containsAll(Arrays.asList(roles));
            }
        }
        return true;
    }

    /**
     * 是否具有权限
     *
     * @param permissions 权限字符串
     * @return 是否具有权限
     */
    @Override
    public Boolean hasPermissions(String[] permissions) {
        Session session = getSession();
        if (session == null) {
            return false;
        }
        Set sessionPermissions = session.getPermissions();
        if (sessionPermissions != null && permissions != null) {
            if (permissions.length != 0 && "".equals(permissions[0])) {
                return true;
            } else {
                return sessionPermissions.containsAll(Arrays.asList(permissions));
            }
        }
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy