tech.hdis.framework.security.session.imp.RedisSessionServiceImpl Maven / Gradle / Ivy
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;
}
}