summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfangshunjian <[email protected]>2023-06-29 10:00:10 +0800
committerfangshunjian <[email protected]>2023-06-29 10:00:10 +0800
commitca2f8e5f3d7d3a1cb563f89aa7de5eac69d83c95 (patch)
tree25419b65ec455bc3d152eafe635254bb256bfe98
parent0b2c961471085bf0c177246e6cc455eb81908fab (diff)
fix: NEZ-2918 shiro 统一通过单例redisTemplate操作
-rw-r--r--nz-admin/src/main/java/com/nis/common/config/RedisConfig.java5
-rw-r--r--nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java206
-rw-r--r--nz-admin/src/main/java/com/nis/common/interceptor/TokenCheckFilter.java256
-rw-r--r--nz-admin/src/main/java/com/nis/common/thread/RedisCacheSubscribe.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysApiKeyServiceImpl.java8
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysRoleServiceImpl.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysUserServiceImpl.java117
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java76
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisSessionDAO.java305
-rw-r--r--nz-admin/src/main/java/com/nis/modules/sys/shiro/ShiroUtils.java79
-rw-r--r--nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalMonitorHandler.java2
12 files changed, 342 insertions, 718 deletions
diff --git a/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java b/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
index bb8f6ee9..49840bbf 100644
--- a/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
+++ b/nz-admin/src/main/java/com/nis/common/config/RedisConfig.java
@@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessException;
-import org.springframework.data.redis.connection.RedisConfiguration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
@@ -53,9 +52,9 @@ public class RedisConfig {
@Value("${nezha.inited:0}")
private int inited;
// redis sentinel配置项
- @Value("${redis.sentinel.master}")
+ @Value("${redis.sentinel.master:}")
private String sentinelMaster;
- @Value("${redis.sentinel.nodes}")
+ @Value("${redis.sentinel.nodes:}")
private String sentinelNodes;
/**
* redis配置项
diff --git a/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java b/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
index 0853bb5b..9b2927ef 100644
--- a/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
+++ b/nz-admin/src/main/java/com/nis/common/config/ShiroConfig.java
@@ -1,25 +1,25 @@
package com.nis.common.config;
-import Aladdin.HaspStatus;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.nis.common.interceptor.TokenCheckFilter;
-import com.nis.common.utils.*;
-import com.nis.modules.metric.dto.NezhaMetrics;
-import com.nis.modules.sys.dao.SysApiKeyDao;
-import com.nis.modules.sys.dao.SysUserDao;
-import com.nis.modules.sys.entity.SysConfigEntity;
-import com.nis.modules.sys.service.LicenseService;
-import com.nis.modules.sys.service.SysConfigService;
-import com.nis.modules.sys.shiro.*;
-import io.micrometer.core.instrument.MeterRegistry;
+import java.nio.charset.Charset;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.Filter;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.catalina.connector.Connector;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.AccessControlFilter;
+import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.crazycake.shiro.IRedisManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,55 +31,59 @@ import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerF
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
-import javax.servlet.Filter;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.nis.common.interceptor.TokenCheckFilter;
+import com.nis.common.utils.Constant;
+import com.nis.common.utils.R;
+import com.nis.common.utils.RCode;
+import com.nis.common.utils.Tool;
+import com.nis.common.utils.ToolUtil;
+import com.nis.modules.metric.dto.NezhaMetrics;
+import com.nis.modules.sys.dao.SysApiKeyDao;
+import com.nis.modules.sys.dao.SysUserDao;
+import com.nis.modules.sys.entity.SysConfigEntity;
+import com.nis.modules.sys.service.LicenseService;
+import com.nis.modules.sys.service.SysConfigService;
+import com.nis.modules.sys.shiro.MySessionManager;
+import com.nis.modules.sys.shiro.ShiroUtils;
+import com.nis.modules.sys.shiro.UserRealm;
+
+import Aladdin.HaspStatus;
+import cn.hutool.core.util.StrUtil;
+import io.micrometer.core.instrument.MeterRegistry;
/**
* Shiro的配置文件
+ *
*/
@Configuration
@DependsOn(value = { "mybatisPlusConfig", "redisConfig" })
public class ShiroConfig {
- @Value("${compileType:release}")
- private String compileType;
-
- @Value("${vendorCode}")
- private String vendorCode;
-
@Autowired
- private LicenseService licenseService;
+ private RedisTemplate<String,String> redisTemplate;
@Autowired
private SysConfigService sysconfigService;
- @Autowired
- private SysUserDao sysUserDao;
-
- @Autowired
- private SysApiKeyDao sysApiKeyDao;
-
+ @Value("${compileType:release}")
+ private String compileType;
+ @Value("${vendorCode}")
+ private String vendorCode;
@Autowired
private NezhaMetrics nezhaMetrics;
@Autowired
private MeterRegistry meterRegistry;
-
@Autowired
- private RedisTemplate<String, String> redisTemplate;
-
+ private LicenseService licenseService;
@Autowired
- private RedisConnectionFactory redisConnectionFactory;
-
+ private TokenCheckFilter tokenCheckFilter;
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
@@ -88,10 +92,9 @@ public class ShiroConfig {
shiroFilter.setUnauthorizedUrl("/");
Map<String, String> filterMap = new LinkedHashMap<>();
-
-
+
/*
- * 静态资源
+ * 静态资源
*/
filterMap.put("/", "anon");
filterMap.put("/static/**", "anon");
@@ -101,37 +104,35 @@ public class ShiroConfig {
filterMap.put("/**/*.jpg", "anon");
filterMap.put("/**/*.css", "anon");
filterMap.put("/**/*.ico", "anon");
-
+
/*
* 开放权限接口
*/
filterMap.put("/sys/login", "anon"); // 登录接口
filterMap.put("/api/**", "anon"); // 告警消息接收 接口
- filterMap.put("/sys/i18n/lang", "anon"); //国际化文件获取接口
+ filterMap.put("/sys/i18n/lang", "anon"); // 国际化文件获取接口
filterMap.put("/mfa/**", "anon"); // mfa 认证接口
- filterMap.put("/healthy", "anon"); //健康检查接口
- filterMap.put("/buildInfo", "anon"); //编译信息查询接口
- filterMap.put("/terminal.ws", "anon"); //terminal websocket 接口
- filterMap.put("/terminal/monitor.ws", "anon"); //terminal/monitor websocket 接口
+ filterMap.put("/healthy", "anon"); // 健康检查接口
+ filterMap.put("/buildInfo", "anon"); // 编译信息查询接口
+ filterMap.put("/terminal.ws", "anon"); // terminal websocket 接口
+ filterMap.put("/terminal/monitor.ws", "anon"); // terminal/monitor websocket 接口
filterMap.put("/sys/license/**", "anon");// license 相关接口
filterMap.put("/monitor/project/topo/icon/**", "anon"); // topo icon 相关接口
filterMap.put("/setup/**", "anon");// 程序配置 相关接口
- filterMap.put("/sys/appearance","anon"); //系统外观配置查询接口
- filterMap.put("/ctl/**","anon"); //管理员账号密码重置接口
+ filterMap.put("/sys/appearance", "anon"); // 系统外观配置查询接口
+ filterMap.put("/ctl/**", "anon"); // 管理员账号密码重置接口
filterMap.put("/ui/**", "anon"); // UI 接口
filterMap.put("/topology/**", "anon"); // topology 接口
filterMap.put("/file/download/**", "anon"); // 文件下载接口
-
+
/*
* 自定义 过滤器
*/
- filterMap.put("/actuator/prometheus", "metricsFilter"); //prometheus metrics
+ filterMap.put("/actuator/prometheus", "metricsFilter"); // prometheus metrics
filterMap.put("/actuator/**", "anon"); // 诊断接口
filterMap.put("/**", "tokenCheckFilter,licenseFilter");
- Integer loginExpiration = getTimeOutData();
Map<String, Filter> cumstomFilterMap = new LinkedHashMap<String, Filter>();
- TokenCheckFilter tokenCheckFilter = new TokenCheckFilter(redisTemplate, loginExpiration, sysUserDao,sysApiKeyDao);
LicenseShiroFilter licenseShiroFilter = new LicenseShiroFilter();
MetricsShiroFilter metricsShiroFilter = new MetricsShiroFilter();
cumstomFilterMap.put("tokenCheckFilter", tokenCheckFilter);
@@ -139,26 +140,27 @@ public class ShiroConfig {
cumstomFilterMap.put("metricsFilter", metricsShiroFilter);
shiroFilter.setFilters(cumstomFilterMap);
shiroFilter.setFilterChainDefinitionMap(filterMap);
-
+
return shiroFilter;
}
@Component
public class LicenseShiroFilter extends AccessControlFilter {
-
+
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
// debug 模式不校验 license
- if(Tool.StrUtil.equalsIgnoreCase(compileType, "debug")) {
+ if (Tool.StrUtil.equalsIgnoreCase(compileType, "debug")) {
return true;
}
-
+
Integer status = licenseService.verify();
- if( ! Tool.NumberUtil.equals(status, HaspStatus.HASP_STATUS_OK)) {
- HttpServletResponse httpResponse=(HttpServletResponse) response;
+ if (!Tool.NumberUtil.equals(status, HaspStatus.HASP_STATUS_OK)) {
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(HttpStatus.FORBIDDEN.value());
- httpResponse.getWriter().write(Tool.JSONUtil.toJsonStr(R.error(RCode.LICENSE_FILE_INVALID.setParam(status))));
+ httpResponse.getWriter()
+ .write(Tool.JSONUtil.toJsonStr(R.error(RCode.LICENSE_FILE_INVALID.setParam(status))));
return false;
}
return true;
@@ -170,21 +172,21 @@ public class ShiroConfig {
}
}
-
+
public class MetricsShiroFilter extends AccessControlFilter {
- @Override
- protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
- nezhaMetrics.bindTo(meterRegistry);
- return true;
- }
-
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- return false;
- }
+ @Override
+ protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o)
+ throws Exception {
+ nezhaMetrics.bindTo(meterRegistry);
+ return true;
+ }
+
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
+ return false;
+ }
}
-
-
+
@Bean
@ConditionalOnExpression("${nezha.shiroPermisSupport:true}")
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
@@ -213,8 +215,9 @@ public class ShiroConfig {
*
* @return
*/
- public MyRedisManager redisManager() {
- MyRedisManager redisManager = new MyRedisManager(redisConnectionFactory);
+ @Bean
+ public IRedisManager redisManager() {
+ RedisManager redisManager = new RedisManager(redisTemplate);
return redisManager;
}
@@ -242,7 +245,7 @@ public class ShiroConfig {
@Bean
public RedisSessionDAO redisSessionDAO() {
Integer loginExpiration = getTimeOutData();
- MyRedisSessionDAO redisSessionDAO = new MyRedisSessionDAO();
+ RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
redisSessionDAO.setExpire(loginExpiration * 60);
redisSessionDAO.setKeyPrefix(ShiroUtils.REDIS_KEYPREFIX);
@@ -301,4 +304,53 @@ public class ShiroConfig {
}
return loginExpiration;
}
-}
+
+ /**
+ * 自定义 redis manager
+ * @author ThinkPad
+ *
+ */
+ public static class RedisManager implements IRedisManager {
+ private RedisTemplate<String, String> redisTemplate;
+
+ public RedisManager(RedisTemplate<String, String> redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ @Override
+ public byte[] get(byte[] key) {
+ ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
+ String v = opsForValue.get(Tool.StrUtil.str(key, "UTF-8"));
+ return Tool.HexUtil.decodeHex(v);
+ }
+
+ @Override
+ public byte[] set(byte[] key, byte[] value, int expire) {
+ ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
+ opsForValue.set(Tool.StrUtil.str(key, "UTF-8"), Tool.HexUtil.encodeHexStr(value), expire, TimeUnit.SECONDS);
+ return value;
+ }
+
+ @Override
+ public void del(byte[] key) {
+ redisTemplate.delete(Tool.StrUtil.str(key, "UTF-8"));
+ }
+
+ @Override
+ public Long dbSize(byte[] pattern) {
+ return (long)redisTemplate.keys(Tool.StrUtil.str(pattern, "UTF-8")).size();
+ }
+
+ @Override
+ public Set<byte[]> keys(byte[] pattern) {
+ Set<String> set = redisTemplate.keys(Tool.StrUtil.str(pattern, "UTF-8"));
+ if(Tool.CollUtil.isEmpty(set)) {
+ return null;
+ }
+ Set<byte[]> keys = Tool.CollUtil.newHashSet();
+ set.forEach( k -> keys.add(Tool.StrUtil.bytes(k,"UTF-8")));
+ return keys;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/nz-admin/src/main/java/com/nis/common/interceptor/TokenCheckFilter.java b/nz-admin/src/main/java/com/nis/common/interceptor/TokenCheckFilter.java
index fbc35adf..2cd89086 100644
--- a/nz-admin/src/main/java/com/nis/common/interceptor/TokenCheckFilter.java
+++ b/nz-admin/src/main/java/com/nis/common/interceptor/TokenCheckFilter.java
@@ -1,187 +1,127 @@
package com.nis.common.interceptor;
-import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.nis.common.utils.Constant;
-import com.nis.common.utils.DateUtils;
-import com.nis.common.utils.R;
-import com.nis.common.utils.RCode;
-import com.nis.common.utils.SpringContextUtils;
-import com.nis.common.utils.Tool;
-import com.nis.common.utils.ToolUtil;
-import com.nis.modules.sys.dao.SysApiKeyDao;
-import com.nis.modules.sys.dao.SysUserDao;
-import com.nis.modules.sys.entity.SysApiKey;
-import com.nis.modules.sys.entity.SysUserEntity;
-import com.nis.modules.sys.shiro.ShiroUtils;
+import java.util.Date;
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
-import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
-import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
-import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.filter.AccessControlFilter;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
-import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.nis.common.utils.Constant;
+import com.nis.common.utils.R;
+import com.nis.common.utils.RCode;
+import com.nis.common.utils.Tool;
+import com.nis.common.utils.ToolUtil;
+import com.nis.modules.sys.dao.SysApiKeyDao;
+import com.nis.modules.sys.entity.SysApiKey;
+import com.nis.modules.sys.entity.SysUserEntity;
+import com.nis.modules.sys.shiro.ShiroUtils;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+@Component
public class TokenCheckFilter extends AccessControlFilter {
- private Integer loginExpiration;
- private SysUserDao sysUserDao;
- private RedisTemplate<String, String> redisTemplate;
- private SysApiKeyDao sysApiKeyDao;
-
- public TokenCheckFilter(RedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
-
- public TokenCheckFilter(RedisTemplate redisTemplate, Integer loginExpiration) {
- this.redisTemplate = redisTemplate;
- this.loginExpiration = loginExpiration;
- }
-
- public TokenCheckFilter(RedisTemplate redisTemplate, Integer loginExpiration, SysUserDao sysUserDao, SysApiKeyDao sysApiKeyDao) {
- this.redisTemplate = redisTemplate;
- this.loginExpiration = loginExpiration;
- this.sysUserDao = sysUserDao;
- this.sysApiKeyDao = sysApiKeyDao;
- }
-
+ @Autowired
+ private SysApiKeyDao sysApiKeyDao;
-// @Override
-// protected boolean preHandle(ServletRequest req, ServletResponse resp) throws Exception {
-// HttpServletRequest request=(HttpServletRequest) req;
-// HttpServletResponse response=(HttpServletResponse)resp;
-// //跨域请求标志
-// String origin = request.getHeader("Origin");
-// if(StringUtils.isNotBlank(origin)){
-// response.setHeader("Access-Control-Allow-Origin",origin);
-// response.setHeader("Access-Control-Allow-Credentials","true");
-// }
-//
-// return super.preHandle(request, response);
-// }
+ public TokenCheckFilter() {
- @Override
- protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object o) throws Exception {
- HttpServletRequest request = (HttpServletRequest) req;
- HttpServletResponse response = (HttpServletResponse) resp;
- String requestToken = request.getHeader(Constant.AUTH_TOKEN_CODE);
- if (StringUtils.isBlank(requestToken)) {
- requestToken = request.getParameter(Constant.AUTH_TOKEN_CODE);
- }
- if (StringUtils.isBlank(requestToken)) {
- response.getWriter().write(JSON.toJSON(R.error(RCode.SYS_LOGIN_REQUIRED)).toString());
- return false;
- }
-
- Boolean exist = redisTemplate.hasKey(ShiroUtils.REDIS_KEYPREFIX + requestToken);
- if (exist) {
- SysUserEntity userEntity = ShiroUtils.getUserEntity();
- if(Tool.ObjectUtil.isNull(userEntity) ) {
- return false;
- }
- if(ToolUtil.equals(userEntity.getId(), 0L)) {
- // 第三方api key登录
- return true;
- }
- // 重新查询数据库
- SysUserEntity entity = this.sysUserDao.selectById(ShiroUtils.getUserEntity().getId());
- if (entity.getStatus() == 0) {
- response.getWriter().write(JSON.toJSON(R.error(RCode.SYS_LOGIN_LOCK)).toString());
- return false;
- }
- // key 存在 证明验证成功,刷新过期时间
- redisTemplate.expire(requestToken, this.loginExpiration, TimeUnit.MINUTES);
- return true;
- } else {
- Date now = new Date();
- String time = DateUtil.format(now , "yyyy-MM-dd hh:mm:ss");
- // 查询sys_api_key是否有该token记录
- SysApiKey apiKey = sysApiKeyDao.selectOne(new QueryWrapper<SysApiKey>().lambda().eq(SysApiKey::getToken, requestToken)
- .and(wrapper -> wrapper.ge(SysApiKey::getExpireAt,time).or().isNull(SysApiKey::getExpireAt)));
- // 如果有的话则认证通过 同时将该值存放到redis里
- if(ToolUtil.isEmpty(apiKey)) {
- // 如果没有则 返回响应值
- response.getWriter().write(JSON.toJSON(R.error(RCode.SYS_LOGIN_REQUIRED)).toString());
- return false;
- }else {
- RedisConnectionFactory factory = SpringContextUtils.getBean("redisConnectionFactory", RedisConnectionFactory.class);
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
- redisTemplate.setConnectionFactory(factory);
- redisTemplate.afterPropertiesSet();
-
-
- //获取存在缓存中的过期时间
- Date expireAt = apiKey.getExpireAt();
-
- SimpleSession session = new SimpleSession();
- SysUserEntity user = new SysUserEntity();
- user.setApiKeyId(apiKey.getId());
- user.setId(0L);
- user.setName(apiKey.getName());
- SimplePrincipalCollection primaryPrincipal =new SimplePrincipalCollection(user,"");
- session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, primaryPrincipal);
- session.setId(apiKey.getToken());
-
- if(!ToolUtil.isEmpty(expireAt)){
- long seconds = DateUtil.between(now, expireAt, DateUnit.SECOND);
- redisTemplate.opsForValue().set(ShiroUtils.REDIS_KEYPREFIX + requestToken, session,seconds,TimeUnit.SECONDS);
- }else{
- redisTemplate.opsForValue().set(ShiroUtils.REDIS_KEYPREFIX + requestToken, session);
- }
-
- DefaultSubjectContext context =new DefaultSubjectContext();
- context.setSession(session);
- SecurityManager securityManager = SecurityUtils.getSecurityManager();
- Subject subject = securityManager.createSubject(context);
- ThreadContext.bind(subject);
- return true;
- }
- }
- }
+ }
- public Integer getLoginExpiration() {
- return loginExpiration;
+ @Override
+ protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object o) throws Exception {
+ HttpServletRequest request = (HttpServletRequest) req;
+ HttpServletResponse response = (HttpServletResponse) resp;
+ String requestToken = request.getHeader(Constant.AUTH_TOKEN_CODE);
+ if (StringUtils.isBlank(requestToken)) {
+ requestToken = request.getParameter(Constant.AUTH_TOKEN_CODE);
+ }
+ if (StringUtils.isBlank(requestToken)) {
+ response.getWriter().write(JSON.toJSON(R.error(RCode.SYS_LOGIN_REQUIRED)).toString());
+ return false;
+ }
+
+ Session session = ShiroUtils.getSessionById(requestToken);
+ if (Tool.ObjectUtil.isNotNull(session)) {
+ SysUserEntity userEntity = ShiroUtils.getUserEntity();
+ if (Tool.ObjectUtil.isNull(userEntity)) {
+ return false;
+ }
+ return true;
+ } else {
+ boolean login = this.apiKeyLogin(requestToken);
+ if(!login) {
+ response.getWriter().write(JSON.toJSON(R.error(RCode.SYS_LOGIN_REQUIRED)).toString());
+ }
+ return login;
+ }
}
- public void setLoginExpiration(Integer loginExpiration) {
- this.loginExpiration = loginExpiration;
+ /**
+ * 验证 apikey 登录
+ * @param token
+ * @return
+ */
+ private boolean apiKeyLogin(String token) {
+ Date now = new Date();
+ String time = DateUtil.format(now, "yyyy-MM-dd hh:mm:ss");
+ // 查询sys_api_key是否有该token记录
+ SysApiKey apiKey = sysApiKeyDao.selectOne(new QueryWrapper<SysApiKey>().lambda().eq(SysApiKey::getToken, token).and(
+ wrapper -> wrapper.ge(SysApiKey::getExpireAt, time).or().isNull(SysApiKey::getExpireAt)));
+ // 如果有的话则认证通过 同时将该值存放到redis里
+ if (ToolUtil.isEmpty(apiKey)) {
+ // 如果没有则 返回响应值
+ return false;
+ } else {
+ // 获取存在缓存中的过期时间
+ Date expireAt = apiKey.getExpireAt();
+ SimpleSession session = new SimpleSession();
+ SysUserEntity user = new SysUserEntity();
+ user.setApiKeyId(apiKey.getId());
+ user.setId(0L);
+ user.setName(apiKey.getName());
+ SimplePrincipalCollection primaryPrincipal = new SimplePrincipalCollection(user, "");
+ session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, primaryPrincipal);
+ session.setId(apiKey.getToken());
+ // 设置超时时间
+ if (!ToolUtil.isEmpty(expireAt)) {
+ long ms = DateUtil.between(now, expireAt, DateUnit.MS);
+ session.setTimeout(ms);
+ } else {
+ session.setTimeout(Integer.MAX_VALUE);
+ }
+ // 手动保存 session 信息
+ ShiroUtils.updateSession(session);
+ DefaultSubjectContext context = new DefaultSubjectContext();
+ context.setSession(session);
+ SecurityManager securityManager = SecurityUtils.getSecurityManager();
+ Subject subject = securityManager.createSubject(context);
+ ThreadContext.bind(subject);
+ return true;
+ }
+
}
@Override
- protected boolean onAccessDenied(ServletRequest req, ServletResponse resp) throws Exception {
+ protected boolean onAccessDenied(ServletRequest req, ServletResponse resp) throws Exception {
- return false;
- }
+ return false;
+ }
}
diff --git a/nz-admin/src/main/java/com/nis/common/thread/RedisCacheSubscribe.java b/nz-admin/src/main/java/com/nis/common/thread/RedisCacheSubscribe.java
index ec03aa2c..f18ce055 100644
--- a/nz-admin/src/main/java/com/nis/common/thread/RedisCacheSubscribe.java
+++ b/nz-admin/src/main/java/com/nis/common/thread/RedisCacheSubscribe.java
@@ -84,7 +84,7 @@ public class RedisCacheSubscribe implements MessageListener{
TokenCheckFilter filter = (TokenCheckFilter) filters.get("tokenCheckFilter");
// Integer loginExpiration = filter.getLoginExpiration();
// System.out.println(loginExpiration);
- filter.setLoginExpiration(Integer.valueOf(sessionTimeOut));
+// filter.setLoginExpiration(Integer.valueOf(sessionTimeOut));
redisCacheManager.setExpire(Integer.valueOf(sessionTimeOut) * 60);
redisSessionDao.setExpire(Integer.valueOf(sessionTimeOut) * 60);
mySessionManager.setGlobalSessionTimeout(Integer.valueOf(sessionTimeOut) * 60 * 1000);
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysApiKeyServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysApiKeyServiceImpl.java
index 18aac459..4ed2d6c2 100644
--- a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysApiKeyServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysApiKeyServiceImpl.java
@@ -65,9 +65,9 @@ public class SysApiKeyServiceImpl extends ServiceImpl<SysApiKeyDao,SysApiKey> im
List<SysApiKey> sysApiKeys = this.list(new QueryWrapper<SysApiKey>().lambda().in(SysApiKey::getId, Arrays.asList(ids.split(","))));
List<String> tokens = new ArrayList<String>();
for(SysApiKey sysApiKey : sysApiKeys) {
- tokens.add(StrUtil.str(ShiroUtils.REDIS_KEYPREFIX+sysApiKey.getToken()));
+ tokens.add(sysApiKey.getToken());
}
- ShiroUtils.removeRedisCacheByToken(tokens);
+ ShiroUtils.deleteSession(tokens);
this.removeByIds(Arrays.asList(ids.split(",")));
}
@@ -122,8 +122,8 @@ public class SysApiKeyServiceImpl extends ServiceImpl<SysApiKeyDao,SysApiKey> im
.eq(SysApiKey::getCreateBy, ShiroUtils.getUserId().intValue())
);
// 删除 redis 中 api key
- List<String> tokens = sysApiKeys.stream().map(k -> ShiroUtils.REDIS_KEYPREFIX + k.getToken()).collect(Collectors.toList());
- ShiroUtils.removeRedisCacheByToken(tokens);
+ List<String> tokens = sysApiKeys.stream().map(k -> k.getToken()).collect(Collectors.toList());
+ ShiroUtils.deleteSession(tokens);
List<Integer> removeIds = sysApiKeys.stream().map(SysApiKey::getId).collect(Collectors.toList());
this.removeByIds(removeIds);
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysRoleServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysRoleServiceImpl.java
index cc549b4f..a6ce4b59 100644
--- a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysRoleServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysRoleServiceImpl.java
@@ -177,7 +177,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleEntity> i
} finally {
// 删除 关联key
if (CollectionUtils.isNotEmpty(removeKeys)) {
- redisTemplate.delete(removeKeys);
+ ShiroUtils.deleteSession(removeKeys);
}
}
}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysUserServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysUserServiceImpl.java
index 1144f83f..7c4f9f7e 100644
--- a/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysUserServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/sys/service/impl/SysUserServiceImpl.java
@@ -1,8 +1,35 @@
package com.nis.modules.sys.service.impl;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.log.Log;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.support.DefaultSubjectContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -12,7 +39,13 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nis.common.exception.NZException;
import com.nis.common.smartvalidate.ValidateUtils;
-import com.nis.common.utils.*;
+import com.nis.common.utils.CommonUtils;
+import com.nis.common.utils.Constant;
+import com.nis.common.utils.PageUtils;
+import com.nis.common.utils.Query;
+import com.nis.common.utils.RCode;
+import com.nis.common.utils.Tool;
+import com.nis.common.utils.ToolUtil;
import com.nis.modules.alert.dao.AlertRuleDao;
import com.nis.modules.alert.entity.AlertRuleEntity;
import com.nis.modules.alert.service.AlertRuleService;
@@ -27,29 +60,17 @@ import com.nis.modules.sys.entity.SysApiKey;
import com.nis.modules.sys.entity.SysRoleEntity;
import com.nis.modules.sys.entity.SysUserEntity;
import com.nis.modules.sys.entity.SysUserRoleEntity;
-import com.nis.modules.sys.service.*;
+import com.nis.modules.sys.service.SysApiKeyService;
+import com.nis.modules.sys.service.SysConfigService;
+import com.nis.modules.sys.service.SysMenuService;
+import com.nis.modules.sys.service.SysRoleService;
+import com.nis.modules.sys.service.SysUserRoleService;
+import com.nis.modules.sys.service.SysUserService;
import com.nis.modules.sys.shiro.ShiroUtils;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.session.mgt.SimpleSession;
-import org.apache.shiro.subject.SimplePrincipalCollection;
-import org.apache.shiro.subject.support.DefaultSubjectContext;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
-import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import javax.servlet.http.HttpServletRequest;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.log.Log;
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
@@ -116,17 +137,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
}
// 获取缓存中登录的用户
Map<String, SysUserEntity> shiroSessionInfoMap = ShiroUtils.getShiroSessionInfoMap();
- List<SysUserEntity> users = new ArrayList<SysUserEntity>(shiroSessionInfoMap.values());
+ List<Long> loginUserIds = Tool.CollUtil.newArrayList();
+ shiroSessionInfoMap.values().forEach( u -> {
+ loginUserIds.add(u.getId());
+ });
for (SysUserEntity userEntity : userList) {
- for (SysUserEntity user : users) {
- if (user.getId().equals(userEntity.getId())){
- //在线
- userEntity.setOnline(1);
- break;
- }else {
- //离线
- userEntity.setOnline(0);
- }
+ if (loginUserIds.contains(userEntity.getId())){
+ //在线
+ userEntity.setOnline(1);
+ }else {
+ //离线
+ userEntity.setOnline(0);
}
List<SysUserRoleEntity> userRoleEntities = userRoleMap.get(userEntity.getId().intValue());
if (CollectionUtils.isEmpty(userRoleEntities)) {
@@ -290,7 +311,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
} finally {
// 删除 关联key
if (CollectionUtils.isNotEmpty(removeKeys)) {
- redisTemplate.delete(removeKeys);
+ ShiroUtils.deleteSession(removeKeys);
}
}
}
@@ -384,7 +405,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
} finally {
// 删除 关联key
if (CollectionUtils.isNotEmpty(removeKeys)) {
- redisTemplate.delete(removeKeys);
+ ShiroUtils.deleteSession(removeKeys);
}
}
}
@@ -393,24 +414,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
public Map<String, Object> getUserPermissions(HttpServletRequest request) {
String requestToken = request.getHeader(Constant.AUTH_TOKEN_CODE);
requestToken = StringUtils.isEmpty(requestToken) ? request.getParameter(Constant.AUTH_TOKEN_CODE) : requestToken;
- if (StringUtils.isEmpty(requestToken))
+ if (StringUtils.isEmpty(requestToken)) {
throw new NZException(RCode.SYS_TOKEN_ISNULL);
-
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
- redisTemplate.setConnectionFactory(factory);
-
- redisTemplate.afterPropertiesSet();
-
- Boolean exist = redisTemplate.hasKey(ShiroUtils.REDIS_KEYPREFIX + requestToken);
- if (!exist)
+ }
+ Session session = ShiroUtils.getSessionById(requestToken);
+ if(Tool.ObjectUtil.isNull(session)) {
throw new NZException(RCode.SYS_LOGIN_REQUIRED);
-
- ValueOperations ops = redisTemplate.opsForValue();
- Object obj = ops.get(ShiroUtils.REDIS_KEYPREFIX + requestToken);
- SimpleSession session = (SimpleSession) obj;
- SimplePrincipalCollection primaryPrincipal = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
+ }
+ PrincipalCollection primaryPrincipal = (PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
SysUserEntity userEntity = (SysUserEntity) primaryPrincipal.getPrimaryPrincipal();
SysUserEntity user = this.getById(userEntity.getId());
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java b/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java
deleted file mode 100644
index 98271bf5..00000000
--- a/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisManager.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.nis.modules.sys.shiro;
-
-import com.nis.common.utils.Tool;
-import org.apache.shiro.session.Session;
-import org.crazycake.shiro.IRedisManager;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
-import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 自定义 redis manager
- *
- * @author ThinkPad
- */
-public class MyRedisManager implements IRedisManager {
-
- private RedisTemplate<String, Object> redisTemplate;
-
- public MyRedisManager(RedisConnectionFactory factory) {
- redisTemplate = new RedisTemplate<>();
-
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
-
- redisTemplate.setConnectionFactory(factory);
- redisTemplate.afterPropertiesSet();
- }
-
- @Override
- public byte[] get(byte[] key) {
- return null;
- }
-
- @Override
- public byte[] set(byte[] key, byte[] value, int expire) {
- return null;
- }
-
- @Override
- public void del(byte[] key) {
- }
-
- @Override
- public Long dbSize(byte[] pattern) {
- return 16L;
- }
-
- @Override
- public Set<byte[]> keys(byte[] pattern) {
- return Tool.CollUtil.newHashSet();
- }
-
- public Object get(String key) {
- ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();
- return valueOperations.get(key);
- }
-
- public Session set(String key, Session value, int expire) {
- ValueOperations<String, Object> opsForValue = this.redisTemplate.opsForValue();
- opsForValue.set(key, value, expire, TimeUnit.SECONDS);
- return value;
- }
-
- public void del(String key) {
- this.redisTemplate.delete(key);
- }
-
- public Set<String> keys(String pattern) {
- return this.redisTemplate.keys(pattern);
- }
-}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisSessionDAO.java b/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisSessionDAO.java
deleted file mode 100644
index 8fedc6aa..00000000
--- a/nz-admin/src/main/java/com/nis/modules/sys/shiro/MyRedisSessionDAO.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.nis.modules.sys.shiro;
-
-import cn.hutool.log.Log;
-import org.apache.shiro.session.Session;
-import org.apache.shiro.session.UnknownSessionException;
-import org.apache.shiro.session.mgt.eis.SessionDAO;
-import org.crazycake.shiro.IRedisManager;
-import org.crazycake.shiro.RedisSessionDAO;
-import org.crazycake.shiro.common.SessionInMemory;
-import org.springframework.data.redis.serializer.SerializationException;
-
-import java.io.Serializable;
-import java.util.*;
-
-public class MyRedisSessionDAO extends RedisSessionDAO implements SessionDAO {
-
- private static final Log logger = Log.get();
-
- private static final String DEFAULT_SESSION_KEY_PREFIX = "shiro:session:";
- private String keyPrefix = "shiro:session:";
- private static final long DEFAULT_SESSION_IN_MEMORY_TIMEOUT = 1000L;
- private long sessionInMemoryTimeout = 1000L;
- private static final boolean DEFAULT_SESSION_IN_MEMORY_ENABLED = true;
- private boolean sessionInMemoryEnabled = true;
- private static ThreadLocal sessionsInThread = new ThreadLocal();
- private static final int DEFAULT_EXPIRE = -2;
- private static final int NO_EXPIRE = -1;
- private int expire = -2;
- private static final int MILLISECONDS_IN_A_SECOND = 1000;
- private MyRedisManager redisManager;
-
- public MyRedisSessionDAO() {
- }
-
- @Override
- public void update(Session session) throws UnknownSessionException {
- if (this.sessionInMemoryEnabled) {
- this.removeExpiredSessionInMemory();
- }
-
- this.saveSession(session);
- if (this.sessionInMemoryEnabled) {
- this.setSessionToThreadLocal(session.getId(), session);
- }
-
- }
-
- private void saveSession(Session session) throws UnknownSessionException {
- if (session != null && session.getId() != null) {
- String key;
- Session value;
- try {
- key = this.getRedisSessionKey(session.getId());
- value = session;
- } catch (SerializationException var5) {
- logger.error("serialize session error. session id=" + session.getId());
- throw new UnknownSessionException(var5);
- }
-
- if (this.expire == -2) {
- this.redisManager.set(key, value, (int) (session.getTimeout() / 1000L));
- } else {
- if (this.expire != -1 && (long) (this.expire * 1000) < session.getTimeout()) {
- logger.warn("Redis session expire time: " + this.expire * 1000 + " is less than Session timeout: " + session.getTimeout() + " . It may cause some problems.");
- }
-
- this.redisManager.set(key, value, this.expire);
- }
- } else {
- logger.error("session or session id is null");
- throw new UnknownSessionException("session or session id is null");
- }
- }
-
- @Override
- public void delete(Session session) {
- if (this.sessionInMemoryEnabled) {
- this.removeExpiredSessionInMemory();
- }
-
- if (session != null && session.getId() != null) {
- if (this.sessionInMemoryEnabled) {
- this.delSessionFromThreadLocal(session.getId());
- }
-
- try {
- this.redisManager.del(this.getRedisSessionKey(session.getId()));
- } catch (SerializationException var3) {
- logger.error("delete session error. session id=" + session.getId());
- }
-
- } else {
- logger.error("session or session id is null");
- }
- }
-
- @Override
- public Collection<Session> getActiveSessions() {
- if (this.sessionInMemoryEnabled) {
- this.removeExpiredSessionInMemory();
- }
-
- HashSet sessions = new HashSet();
-
- try {
- Set<String> keys = this.redisManager.keys(this.keyPrefix + "*");
- if (keys != null && keys.size() > 0) {
- Iterator<String> var3 = keys.iterator();
- while (var3.hasNext()) {
- String key = var3.next();
- Session s = (Session) this.redisManager.get(key);
- sessions.add(s);
- }
- }
- } catch (SerializationException var6) {
- logger.error("get active sessions error.");
- }
-
- return sessions;
- }
-
- @Override
- protected Serializable doCreate(Session session) {
- if (this.sessionInMemoryEnabled) {
- this.removeExpiredSessionInMemory();
- }
-
- if (session == null) {
- logger.error("session is null");
- throw new UnknownSessionException("session is null");
- } else {
- Serializable sessionId = this.generateSessionId(session);
- this.assignSessionId(session, sessionId);
- this.saveSession(session);
- return sessionId;
- }
- }
-
- @Override
- protected Session doReadSession(Serializable sessionId) {
- if (this.sessionInMemoryEnabled) {
- this.removeExpiredSessionInMemory();
- }
-
- if (sessionId == null) {
- logger.warn("session id is null");
- return null;
- } else {
- Session session;
- if (this.sessionInMemoryEnabled) {
- session = this.getSessionFromThreadLocal(sessionId);
- if (session != null) {
- return session;
- }
- }
-
- session = null;
-
- try {
- String sessionRedisKey = this.getRedisSessionKey(sessionId);
- logger.debug("read session: " + sessionRedisKey + " from Redis");
- session = (Session) this.redisManager.get(sessionRedisKey);
- if (this.sessionInMemoryEnabled) {
- this.setSessionToThreadLocal(sessionId, session);
- }
- } catch (SerializationException var4) {
- logger.error("read session error. sessionId: " + sessionId);
- }
-
- return session;
- }
- }
-
- private void setSessionToThreadLocal(Serializable sessionId, Session session) {
- this.initSessionsInThread();
- Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
- sessionMap.put(sessionId, this.createSessionInMemory(session));
- }
-
- private void delSessionFromThreadLocal(Serializable sessionId) {
- Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
- if (sessionMap != null) {
- sessionMap.remove(sessionId);
- }
- }
-
- private SessionInMemory createSessionInMemory(Session session) {
- SessionInMemory sessionInMemory = new SessionInMemory();
- sessionInMemory.setCreateTime(new Date());
- sessionInMemory.setSession(session);
- return sessionInMemory;
- }
-
- private void initSessionsInThread() {
- Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
- if (sessionMap == null) {
- sessionMap = new HashMap();
- sessionsInThread.set(sessionMap);
- }
-
- }
-
- private void removeExpiredSessionInMemory() {
- Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
- if (sessionMap != null) {
- Iterator it = sessionMap.keySet().iterator();
-
- while (it.hasNext()) {
- Serializable sessionId = (Serializable) it.next();
- SessionInMemory sessionInMemory = (SessionInMemory) sessionMap.get(sessionId);
- if (sessionInMemory == null) {
- it.remove();
- } else {
- long liveTime = this.getSessionInMemoryLiveTime(sessionInMemory);
- if (liveTime > this.sessionInMemoryTimeout) {
- it.remove();
- }
- }
- }
-
- if (sessionMap.size() == 0) {
- sessionsInThread.remove();
- }
-
- }
- }
-
- private Session getSessionFromThreadLocal(Serializable sessionId) {
- if (sessionsInThread.get() == null) {
- return null;
- } else {
- Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
- SessionInMemory sessionInMemory = (SessionInMemory) sessionMap.get(sessionId);
- if (sessionInMemory == null) {
- return null;
- } else {
- logger.debug("read session from memory");
- return sessionInMemory.getSession();
- }
- }
- }
-
- private long getSessionInMemoryLiveTime(SessionInMemory sessionInMemory) {
- Date now = new Date();
- return now.getTime() - sessionInMemory.getCreateTime().getTime();
- }
-
- private String getRedisSessionKey(Serializable sessionId) {
- return this.keyPrefix + sessionId;
- }
-
- @Override
- public IRedisManager getRedisManager() {
- return this.redisManager;
- }
-
- public void setRedisManager(MyRedisManager redisManager) {
- this.redisManager = redisManager;
- }
-
- @Override
- public String getKeyPrefix() {
- return this.keyPrefix;
- }
-
- @Override
- public void setKeyPrefix(String keyPrefix) {
- this.keyPrefix = keyPrefix;
- }
-
-
- @Override
- public long getSessionInMemoryTimeout() {
- return this.sessionInMemoryTimeout;
- }
-
- @Override
- public void setSessionInMemoryTimeout(long sessionInMemoryTimeout) {
- this.sessionInMemoryTimeout = sessionInMemoryTimeout;
- }
-
- @Override
- public int getExpire() {
- return this.expire;
- }
-
- @Override
- public void setExpire(int expire) {
- this.expire = expire;
- }
-
- @Override
- public boolean getSessionInMemoryEnabled() {
- return this.sessionInMemoryEnabled;
- }
-
- @Override
- public void setSessionInMemoryEnabled(boolean sessionInMemoryEnabled) {
- this.sessionInMemoryEnabled = sessionInMemoryEnabled;
- }
-
- public static ThreadLocal getSessionsInThread() {
- return sessionsInThread;
- }
-}
diff --git a/nz-admin/src/main/java/com/nis/modules/sys/shiro/ShiroUtils.java b/nz-admin/src/main/java/com/nis/modules/sys/shiro/ShiroUtils.java
index 40a564a8..1ebb6745 100644
--- a/nz-admin/src/main/java/com/nis/modules/sys/shiro/ShiroUtils.java
+++ b/nz-admin/src/main/java/com/nis/modules/sys/shiro/ShiroUtils.java
@@ -2,6 +2,7 @@ package com.nis.modules.sys.shiro;
import cn.hutool.log.Log;
import com.nis.common.utils.SpringContextUtils;
+import com.nis.common.utils.Tool;
import com.nis.common.utils.ToolUtil;
import com.nis.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils;
@@ -10,9 +11,11 @@ import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SimpleSession;
+import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
+import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@@ -43,7 +46,11 @@ public class ShiroUtils {
}
public static Session getSessionById(String sessionId) {
- return SecurityUtils.getSecurityManager().getSession(new DefaultSessionKey(sessionId));
+ try {
+ return SecurityUtils.getSecurityManager().getSession(new DefaultSessionKey(sessionId));
+ } catch (Exception e) {
+ return null;
+ }
}
public static SysUserEntity getUserEntityBySessionId(String sessionId){
@@ -87,54 +94,50 @@ public class ShiroUtils {
SecurityUtils.getSubject().logout();
}
+
+ public static void updateSession(Session session) {
+ RedisSessionDAO sessionDao = SpringContextUtils.getBean("redisSessionDAO", RedisSessionDAO.class);
+ sessionDao.update(session);
+ }
+
+
+ public static List<SysUserEntity> getActiveUsers() {
+ RedisSessionDAO sessionDao = SpringContextUtils.getBean("redisSessionDAO", RedisSessionDAO.class);
+ Collection<Session> sessions = sessionDao.getActiveSessions();
+ List<SysUserEntity> userList = Tool.CollUtil.newArrayList();
+ for (Session session : sessions) {
+ PrincipalCollection primaryPrincipal = (PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
+ if(ToolUtil.isNotEmpty(primaryPrincipal)) {
+ userList.add((SysUserEntity) primaryPrincipal.getPrimaryPrincipal());
+ }
+ }
+ return userList;
+ }
+
/**
* 从 redis 中获取 token 和 用户信息
*
* @return
*/
public static Map<String, SysUserEntity> getShiroSessionInfoMap() {
- RedisConnectionFactory factory = SpringContextUtils.getBean("redisConnectionFactory", RedisConnectionFactory.class);
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
- redisTemplate.setConnectionFactory(factory);
-
- redisTemplate.afterPropertiesSet();
-
- ValueOperations ops = redisTemplate.opsForValue();
-
- Set keys = redisTemplate.keys(ShiroUtils.REDIS_KEYPREFIX + "*");
- List<String> keyList = new ArrayList<>(keys);
- List<Object> values = ops.multiGet(keyList);
- Map<String, Object> map = new HashMap();
-
- int size = keyList.size();
- for (int i = 0; i < size; i++) {
- map.put(keyList.get(i), values.get(i));
- }
-
- Map<String, SysUserEntity> resultMap = new HashMap(map.size());
- for (Map.Entry<String, Object> entry : map.entrySet()) {
- Object obj = entry.getValue();
- SimpleSession session = (SimpleSession) obj;
- if (ToolUtil.isEmpty(session.getAttributes()))
- continue;
- SimplePrincipalCollection primaryPrincipal = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
+ RedisSessionDAO sessionDao = SpringContextUtils.getBean("redisSessionDAO", RedisSessionDAO.class);
+ Collection<Session> sessions = sessionDao.getActiveSessions();
+ Map<String, SysUserEntity> resultMap = Tool.MapUtil.newHashMap(sessions.size());
+ for (Session session : sessions) {
+ PrincipalCollection primaryPrincipal = (PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if(ToolUtil.isNotEmpty(primaryPrincipal)) {
- resultMap.put(entry.getKey(), (SysUserEntity) primaryPrincipal.getPrimaryPrincipal());
+ resultMap.put(session.getId().toString(), (SysUserEntity) primaryPrincipal.getPrimaryPrincipal());
}
}
return resultMap;
}
- public static void removeRedisCacheByToken(List<String> tokens) {
- RedisConnectionFactory factory = SpringContextUtils.getBean("redisConnectionFactory", RedisConnectionFactory.class);
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
- redisTemplate.setConnectionFactory(factory);
-
- redisTemplate.afterPropertiesSet();
- redisTemplate.delete(tokens);
+ public static void deleteSession(List<String> sessionIds) {
+ RedisSessionDAO sessionDao = SpringContextUtils.getBean("redisSessionDAO", RedisSessionDAO.class);
+ for(String s : sessionIds) {
+ SimpleSession ss = new SimpleSession();
+ ss.setId(s);
+ sessionDao.delete(ss);
+ }
}
}
diff --git a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
index 5d7ca0cb..e3e76730 100644
--- a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
+++ b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
@@ -147,7 +147,7 @@ public class TerminalHandler extends TextWebSocketHandler {
this.initFieldVal(session);
log.info("WebSocket connectioned. after connection established open terminal begin... uuid: {}", uuid);
- SysUserEntity userEntity = Tool.MapUtil.get(ShiroUtils.getShiroSessionInfoMap(), StrUtil.concat(true, ShiroUtils.REDIS_KEYPREFIX, token), SysUserEntity.class);
+ SysUserEntity userEntity = Tool.MapUtil.get(ShiroUtils.getShiroSessionInfoMap(), token, SysUserEntity.class);
if (ObjectUtil.isNull(userEntity)) {
log.warn("open terminal error. system login token exception. uuid: {}, token: {}", uuid, token);
session.sendMessage(new TextMessage("Token error, Please log in to the system first"));
diff --git a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalMonitorHandler.java b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalMonitorHandler.java
index ed6f38b4..3bb191c7 100644
--- a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalMonitorHandler.java
+++ b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalMonitorHandler.java
@@ -29,7 +29,7 @@ public class TerminalMonitorHandler extends TextWebSocketHandler {
String token = (String) attributes.get("terminalToken");
Map<String, SysUserEntity> shiroSessionInfoMap = ShiroUtils.getShiroSessionInfoMap();
- SysUserEntity user = shiroSessionInfoMap.get(Tool.StrUtil.concat(true, ShiroUtils.REDIS_KEYPREFIX, token));
+ SysUserEntity user = shiroSessionInfoMap.get(token);
if (user == null) {
session.sendMessage(new TextMessage("Token error,Please log in to the system first"));
session.close();