Commit 330253f7 authored by nie'hong's avatar nie'hong

增加微信小程序授权登录,集成shiro

parent e4a08e6e
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
<module>wisenergy-model</module> <module>wisenergy-model</module>
<module>wisenergy-mapper</module> <module>wisenergy-mapper</module>
<module>wisenergy-service</module> <module>wisenergy-service</module>
<module>wisenergy-shiro</module>
<module>wisenergy-web-admin</module> <module>wisenergy-web-admin</module>
</modules> </modules>
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
<moduleVersion.wisenergy-model>1.0.0-${projectDevMode}</moduleVersion.wisenergy-model> <moduleVersion.wisenergy-model>1.0.0-${projectDevMode}</moduleVersion.wisenergy-model>
<moduleVersion.wisenergy-mapper>1.0.0-${projectDevMode}</moduleVersion.wisenergy-mapper> <moduleVersion.wisenergy-mapper>1.0.0-${projectDevMode}</moduleVersion.wisenergy-mapper>
<moduleVersion.wisenergy-service>1.0.0-${projectDevMode}</moduleVersion.wisenergy-service> <moduleVersion.wisenergy-service>1.0.0-${projectDevMode}</moduleVersion.wisenergy-service>
<moduleVersion.wisenergy-shiro>1.0.0-${projectDevMode}</moduleVersion.wisenergy-shiro>
<moduleVersion.wisenergy-web-admin>2.0.0-${projectDevMode}</moduleVersion.wisenergy-web-admin> <moduleVersion.wisenergy-web-admin>2.0.0-${projectDevMode}</moduleVersion.wisenergy-web-admin>
</properties> </properties>
......
...@@ -123,16 +123,16 @@ ...@@ -123,16 +123,16 @@
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
</dependency> </dependency>
<!-- shiro --> <!-- shiro -->
<dependency> <!--<dependency>-->
<groupId>org.apache.shiro</groupId> <!--<groupId>org.apache.shiro</groupId>-->
<artifactId>shiro-core</artifactId> <!--<artifactId>shiro-core</artifactId>-->
<version>1.4.0</version> <!--<version>1.4.0</version>-->
</dependency> <!--</dependency>-->
<dependency> <!--<dependency>-->
<groupId>org.apache.shiro</groupId> <!--<groupId>org.apache.shiro</groupId>-->
<artifactId>shiro-spring</artifactId> <!--<artifactId>shiro-spring</artifactId>-->
<version>1.4.0</version> <!--<version>1.4.0</version>-->
</dependency> <!--</dependency>-->
<!-- POI --> <!-- POI -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
......
package cn.wisenergy.common.config; package cn.wisenergy.common.config.redis;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -13,16 +13,17 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; ...@@ -13,16 +13,17 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
*/ */
@Configuration @Configuration
public class RedisConfig { public class RedisConfig {
@Autowired @Autowired
private RedisConnectionFactory factory; private RedisConnectionFactory factory;
@Bean @Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate() { public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new SerializeUtils());
redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new SerializeUtils());
redisTemplate.setConnectionFactory(factory); redisTemplate.setConnectionFactory(factory);
return redisTemplate; return redisTemplate;
} }
......
package cn.wisenergy.common.config.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.io.*;
/**
* @author: nh
* @date: 2021/04/08
* @description: redis的value序列化工具
*/
public class SerializeUtils implements RedisSerializer {
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
public static boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
/**
* 序列化
*
* @param object
* @return
* @throws SerializationException
*/
@Override
public byte[] serialize(Object object) throws SerializationException {
byte[] result = null;
if (object == null) {
return new byte[0];
}
try (
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream)
) {
if (!(object instanceof Serializable)) {
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
"but received an object of type [" + object.getClass().getName() + "]");
}
objectOutputStream.writeObject(object);
objectOutputStream.flush();
result = byteStream.toByteArray();
} catch (Exception ex) {
logger.error("Failed to serialize", ex);
}
return result;
}
/**
* 反序列化
*
* @param bytes
* @return
* @throws SerializationException
*/
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
Object result = null;
if (isEmpty(bytes)) {
return null;
}
try (
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream)
) {
result = objectInputStream.readObject();
} catch (Exception e) {
logger.error("Failed to deserialize", e);
}
return result;
}
}
\ No newline at end of file
...@@ -2,7 +2,6 @@ package cn.wisenergy.common.expection; ...@@ -2,7 +2,6 @@ package cn.wisenergy.common.expection;
import cn.wisenergy.common.utils.R; import cn.wisenergy.common.utils.R;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
...@@ -37,10 +36,10 @@ public class BaseExceptionHandler { ...@@ -37,10 +36,10 @@ public class BaseExceptionHandler {
return R.error("数据库中已存在该记录"); return R.error("数据库中已存在该记录");
} }
@ExceptionHandler(AuthorizationException.class) // @ExceptionHandler(AuthorizationException.class)
public R<?> handleAuthorizationException(AuthorizationException e){ // public R<?> handleAuthorizationException(AuthorizationException e){
log.error(e.getMessage(), e); // log.error(e.getMessage(), e);
return R.error("没有权限,请联系管理员授权"); // return R.error("没有权限,请联系管理员授权");
} // }
} }
...@@ -29,7 +29,7 @@ public class RedisUtil { ...@@ -29,7 +29,7 @@ public class RedisUtil {
public final static long NOT_EXPIRE = -1; public final static long NOT_EXPIRE = -1;
public void set(String key, Object value){ public void set(String key, Object value){
set(key, value); valueOperations.set(key, toJson(value));
} }
public void set(String key, Object value, long expire){ public void set(String key, Object value, long expire){
...@@ -68,6 +68,7 @@ public class RedisUtil { ...@@ -68,6 +68,7 @@ public class RedisUtil {
return redisTemplate.delete(key); return redisTemplate.delete(key);
} }
/** /**
* Object转成JSON数据 * Object转成JSON数据
*/ */
......
package cn.wisenergy.common.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
public class WeChatUtil {
public static JSONObject getSessionKeyOrOpenId(String code) {
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
HashMap<String, Object> requestUrlParam = new HashMap<>();
//小程序appId
requestUrlParam.put("appid", "wx245543a790527cc6");
//小程序secret
requestUrlParam.put("secret", "915b44d0631f7a24c7057ee657ca8a1e");
//小程序端返回的code
requestUrlParam.put("js_code", code);
//默认参数
requestUrlParam.put("grant_type", "authorization_code");
//发送post请求读取调用微信接口获取openid用户唯一标识
String result = HttpUtil.get(requestUrl, requestUrlParam);
JSONObject jsonObject = JSONUtil.parseObj(result);
return jsonObject;
}
public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {
// 被加密的数据
byte[] dataByte = Base64.decode(encryptedData);
// 加密秘钥
byte[] keyByte = Base64.decode(sessionKey);
// 偏移量
byte[] ivByte = Base64.decode(iv);
try {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
if (keyByte.length % base != 0) {
int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
keyByte = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
// 初始化
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, "UTF-8");
return JSONUtil.parseObj(result);
}
} catch (Exception e) {
}
return null;
}
}
\ No newline at end of file
...@@ -87,7 +87,8 @@ public enum BASE_RESP_CODE_ENUM { ...@@ -87,7 +87,8 @@ public enum BASE_RESP_CODE_ENUM {
PLEASE_CANCELTHE_MANAGEMENTROLE("669", "注销账号,请取消管理角色"), PLEASE_CANCELTHE_MANAGEMENTROLE("669", "注销账号,请取消管理角色"),
ATLEASTONEADMINISTRATORISREQUIRED("670", "至少需要一个系统管理员!"), ATLEASTONEADMINISTRATORISREQUIRED("670", "至少需要一个系统管理员!"),
PLEASESELECTANITEM("671", "请选择一个项目"), PLEASESELECTANITEM("671", "请选择一个项目"),
PLEASESELECTADEPARTMENT("672","请选择一个部门") PLEASESELECTADEPARTMENT("672","请选择一个部门"),
WECHAT_NOT_BIND("673","微信未绑定")
; ;
......
...@@ -32,7 +32,7 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> { ...@@ -32,7 +32,7 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> {
*/ */
WorkUser getUserById(Integer userId); WorkUser getUserById(Integer userId);
Integer updateUserInfo(WorkUser user); int updateUserInfo(WorkUser user);
/** /**
* 获取用户主键、姓名、部门名称 * 获取用户主键、姓名、部门名称
...@@ -46,7 +46,16 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> { ...@@ -46,7 +46,16 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> {
List<WorkRole> getUserRole(Integer id); List<WorkRole> getUserRole(Integer id);
int updateStatusAndSubmitOrderById(@Param("userId") Integer userId,@Param("status") Integer status,@Param("submitOrder")Integer submitOrder); int updateStatusAndSubmitOrderById(@Param("userId") Integer userId,@Param("status") Integer status,@Param("submitOrder")Integer submitOrder);
WorkUser getUserByLoginName(String loginName);
/**
* 根据openid查询用户
* @param openid
* @return
*/
WorkUser getUserByOpenId(String openid);
int clearOpenidByUserId(Integer userId);
} }
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
</sql> </sql>
<sql id="cols_exclude_id"> <sql id="cols_exclude_id">
name, oa_user_id, login_name, phone, dept_id, email, role ,type,status,wx_id,submit_order,create_time,modify_time name, oa_user_id, login_name, phone, password, dept_id, email, role ,type,status,wx_id,submit_order,create_time,modify_time
</sql> </sql>
<sql id="values"> <sql id="values">
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
from <include refid="table"/> from <include refid="table"/>
where id = #{userId} where id = #{userId}
</select> </select>
<select id="getStatisticsTableDtos" resultType="cn.wisenergy.model.dto.StatisticsTableDto"> <select id="getStatisticsTableDtos" resultType="cn.wisenergy.model.dto.StatisticsTableDto">
select u.id AS user_id, u.name AS user_name, d.dept_name select u.id AS user_id, u.name AS user_name, d.dept_name
from work_user u join work_dept d on u.dept_id=d.id from work_user u join work_dept d on u.dept_id=d.id
...@@ -102,6 +103,7 @@ ...@@ -102,6 +103,7 @@
set <include refid="updateCondition"/> set <include refid="updateCondition"/>
where id = #{id} where id = #{id}
</update> </update>
<update id="updateStatusAndSubmitOrderById"> <update id="updateStatusAndSubmitOrderById">
update <include refid="table"/> update <include refid="table"/>
<set> <set>
...@@ -115,6 +117,12 @@ ...@@ -115,6 +117,12 @@
where id = #{userId} where id = #{userId}
</update> </update>
<update id="clearOpenidByUserId">
update <include refid="table"/>
set wx_id = null
where id = #{userId}
</update>
<resultMap id="UserRoleMap" type="cn.wisenergy.model.dto.UserRoleDto"> <resultMap id="UserRoleMap" type="cn.wisenergy.model.dto.UserRoleDto">
<id column="id" property="id"/> <id column="id" property="id"/>
...@@ -171,4 +179,20 @@ LEFT JOIN work_role r on ur.role_id = r.id ...@@ -171,4 +179,20 @@ LEFT JOIN work_role r on ur.role_id = r.id
ORDER BY CONVERT( `name` USING gbk ) ORDER BY CONVERT( `name` USING gbk )
</select> </select>
<select id="getUserByLoginName" resultType="cn.wisenergy.model.app.WorkUser">
select <include refid="cols_all"/>
from <include refid="table"/>
<where>
login_name = #{loginName}
</where>
</select>
<select id="getUserByOpenId" resultType="cn.wisenergy.model.app.WorkUser">
select <include refid="cols_all"/>
from <include refid="table"/>
<where>
wx_id = #{openid}
</where>
</select>
</mapper> </mapper>
package cn.wisenergy.model.dto;
import lombok.Data;
@Data
public class WeChatUserInfo {
/**
* 微信返回的code
*/
private String code;
// private String
/**
* 非敏感的用户信息
*/
// private String rawData;
/**
* 签名信息
*/
// private String signature;
/**
* 加密的数据
*/
// private String encrypteData;
/**
* 加密密钥
*/
// private String iv;
}
\ No newline at end of file
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
<artifactId>wisenergy-mapper</artifactId> <artifactId>wisenergy-mapper</artifactId>
<version>${moduleVersion.wisenergy-mapper}</version> <version>${moduleVersion.wisenergy-mapper}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.wisenergy</groupId>
<artifactId>wisenergy-shiro</artifactId>
<version>${moduleVersion.wisenergy-shiro}</version>
</dependency>
<!--综合安防管理平台提供了OpenAPI安全认证库(Java、C++)快速实现接口调用。--> <!--综合安防管理平台提供了OpenAPI安全认证库(Java、C++)快速实现接口调用。-->
<dependency> <dependency>
<groupId>com.hikvision.ga</groupId> <groupId>com.hikvision.ga</groupId>
......
package cn.wisenergy.service; package cn.wisenergy.service;
import cn.wisenergy.model.app.WorkUser; import cn.wisenergy.model.app.WorkUser;
import cn.wisenergy.model.dto.AllRoleAndUserRoleDto; import cn.wisenergy.model.dto.*;
import cn.wisenergy.model.dto.OrganizationDto;
import cn.wisenergy.model.dto.OrganizationStructureDto;
import cn.wisenergy.model.dto.ResultUser;
import cn.wisenergy.model.vo.GetUserListVo; import cn.wisenergy.model.vo.GetUserListVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -27,10 +23,9 @@ public interface WorkUserService { ...@@ -27,10 +23,9 @@ public interface WorkUserService {
* @param loginName 登录名 * @param loginName 登录名
* @param password 密码 * @param password 密码
* @param source 登录来源 * @param source 登录来源
* @param request
* @return * @return
*/ */
ResultUser login(String loginName, String password, String source, HttpServletRequest request); ResultUser login(String loginName, String password, String source);
/** /**
* 获取用户基础信息 * 获取用户基础信息
...@@ -69,4 +64,25 @@ public interface WorkUserService { ...@@ -69,4 +64,25 @@ public interface WorkUserService {
Boolean reSetPassword(Integer userId); Boolean reSetPassword(Integer userId);
List<WorkUser> getByMap(Map<String, Object> map); List<WorkUser> getByMap(Map<String, Object> map);
/**
* 微信登录
* @param code
* @return
*/
ResultUser weChatLogin( String code);
/**
* 绑定用户和微信登录
* @param userId
* @param code
* @return
*/
boolean bindWeChat(Integer userId, String code);
/**
* 微信登录处理,将数据库中的wx_id中存储的openid置为null
* @param userId
*/
void wxLogout(Integer userId);
} }
...@@ -605,6 +605,7 @@ public class WorkProjectServiceImpl implements WorkProjectService { ...@@ -605,6 +605,7 @@ public class WorkProjectServiceImpl implements WorkProjectService {
return insert1 > 0; return insert1 > 0;
} }
private OrderChangeDto getProjevtAndTypeOfDept(Integer userId, Boolean isFillIn, Boolean addProjectOfDept) { private OrderChangeDto getProjevtAndTypeOfDept(Integer userId, Boolean isFillIn, Boolean addProjectOfDept) {
if (null == userId) { if (null == userId) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL); throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
......
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<artifactId>wisenergy-parent</artifactId> <artifactId>wisenergy-parent</artifactId>
<groupId>org.yun</groupId> <groupId>cn.wisenergy</groupId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<artifactId>wisenergy-shiro</artifactId> <artifactId>wisenergy-shiro</artifactId>
<version>${moduleVersion.wisenergy-shiro}</version> <version>${moduleVersion.wisenergy-shiro}</version>
<packaging>jar</packaging> <packaging>jar</packaging>
...@@ -17,19 +20,22 @@ ...@@ -17,19 +20,22 @@
<dependencies> <dependencies>
<!-- 模块依赖 --> <!-- 模块依赖 -->
<dependency> <dependency>
<groupId>org.yun</groupId> <groupId>cn.wisenergy</groupId>
<artifactId>wisenergy-service</artifactId> <artifactId>wisenergy-mapper</artifactId>
<version>${moduleVersion.wisenergy-service}</version> <version>${moduleVersion.wisenergy-mapper}</version>
</dependency> </dependency>
<!-- Shiro --> <!-- Shiro -->
<dependency> <dependency>
<groupId>org.apache.shiro</groupId> <groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId> <artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
<!-- MAVEN构建 --> <!-- MAVEN构建 -->
<build> <build>
<finalName>${project.artifactId}-${moduleVersion.project-shiro}</finalName> <finalName>${project.artifactId}-${moduleVersion.wisenergy-shiro}</finalName>
</build> </build>
</project> </project>
\ No newline at end of file
//package cn.wisenergy.shiro.config;
//
//import com.alibaba.fastjson.JSONObject;
//import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
//import org.springframework.http.HttpStatus;
//
//import javax.servlet.ServletRequest;
//import javax.servlet.ServletResponse;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.util.HashMap;
//import java.util.Map;
//
//public class AuthenticationFilter extends FormAuthenticationFilter {
// @Override
// protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
// // 错误异常提示
// HttpServletResponse httpResponse = (HttpServletResponse) response;
// HttpServletRequest httpRequest = (HttpServletRequest) request;
// String sessionId = ((HttpServletRequest) request).getHeader("sessionId");
// if (sessionId == null) {
// setHeader(httpRequest, httpResponse);
// httpResponse.setCharacterEncoding("UTF-8");
// httpResponse.setContentType("application/json");
// Map<String, Object> map = new HashMap<>();
// map.put("status", "1003");
// map.put("message", "请先登录!");
// httpResponse.getWriter().write(JSONObject.toJSONString(map));
// return false;
// } else {
// return true;
// }
//
// }
//
// /**
// * 为response设置header,实现跨域
// */
// private void setHeader(HttpServletRequest request, HttpServletResponse response) {
// //跨域的header设置
// response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
// response.setHeader("Access-Control-Allow-Methods", request.getMethod());
// response.setHeader("Access-Control-Allow-Credentials", "true");
// response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
// //防止乱码,适用于传输JSON数据
// //Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild
// response.setHeader("Content-Type", "application/json;charset=UTF-8");
// response.setStatus(HttpStatus.OK.value());
// }
//
// @Override
// protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
// if (request instanceof HttpServletRequest) {
// if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
// return true;
// }
// }
// //小程序放行
// if(isFilter((HttpServletRequest) request)){
// return true;
// }
//
// return super.isAccessAllowed(request, response, mappedValue);
// }
// //判断请求头中是否带有identity(标识是小程序)
// public boolean isFilter(HttpServletRequest request) {
// return null != request.getHeader("identity") && request.getHeader("identity").equals("miniprogram");
// }
//}
package cn.wisenergy.shiro.filter;
import cn.wisenergy.mapper.WorkUserMapper;
import cn.wisenergy.model.app.WorkUser;
import cn.wisenergy.shiro.util.CustomerRealm;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* @description: 自定义退出
* @author: nh
* @create: 2021-04-10 16:31
**/
public class CustomerLogoutFilter extends LogoutFilter {
@Autowired
private WorkUserMapper workUserMapper;
@Autowired
private CustomerRealm realm;
public CustomerLogoutFilter() {
}
// 删除存入redis中的认证信息,小程序请求不带session,用shiro的subject.logout()方法不能够删除redis中的认证信息
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 请求的路径
String requestURI = httpServletRequest.getRequestURI();
// 不为微信登出则进行下一过滤器
if (!requestURI.equals("/wxLogout")) {
return true;
}
// shiro主体
Subject subject = getSubject(request, response);
// 获取请求的参数:userId
String userIdString = httpServletRequest.getParameter("userId");
Integer userId = Integer.valueOf(userIdString);
// 获取用户信息
WorkUser user = workUserMapper.getUserById(userId);
//
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection(user,realm.getName());
// 删除主体认证信息
realm.clearCachedAuthenticationInfo(simplePrincipalCollection);
try {
subject.logout();
} catch (SessionException ise) {
ise.printStackTrace();
}
// 重定向到指定地址
// String redirectUrl = getRedirectUrl(request, response, subject);
// issueRedirect(request, response, redirectUrl);
// 为true,进入微信退出接口
return true;
}
}
package cn.wisenergy.shiro.filter;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.Result;
import cn.wisenergy.model.app.WorkUser;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
/**
* @description:
* @author: nh
* @create: 2021-04-06 17:41
**/
public class KickoutSessionControlFilter extends AccessControlFilter {
protected Logger log = LoggerFactory.getLogger(this.getClass());
private SessionManager sessionManager;
// false为提出之前登录的用户
private boolean kickoutAfter = false;
// 用一个账号最大的会话数量
private int maxSession = 1;
private static final String DEFAULT_KICKOUT_CACHE_KEY_PREFIX = "shiro:cache:kickout:";
private String keyprefix = DEFAULT_KICKOUT_CACHE_KEY_PREFIX;
private static final long EXPIRE_TIME = 30 * 60;
@Autowired
private RedisTemplate redisTemplate;
String getRedisKickoutKey(Integer userId) {
return keyprefix + userId;
}
public void setSessionManager(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//如果是小程序请求或请求登录接口,就放行
return isMiniProgram((HttpServletRequest) request);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
HttpServletResponse httpServletResponse = null;
// 没有登陆或没有设置“记住我”
if (!subject.isAuthenticated() && !subject.isRemembered()) {
// 没有登陆,抛出异常
httpServletResponse = (HttpServletResponse) response;
thrLogoutException(httpServletResponse, Result.RESULT_FLG.FAIL,BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
return false;
}
// 获取当前用户请求所携带的session
Session session = subject.getSession();
// 当前用户
WorkUser user = (WorkUser) subject.getPrincipal();
Integer userId = user.getId();
// 获取用户登录账户的session队列,并将超过规定人数的用户进项标记
this.getSessionQue(session, userId);
// 如果当前用户被标记,则将用户登出
if (session.getAttribute("kickout") != null) {
try {
subject.logout();
// 当前拦截器为唯一拦截器,抛出未登录异常,结束本次请求
httpServletResponse = (HttpServletResponse) response;
thrLogoutException(httpServletResponse, Result.RESULT_FLG.FAIL,BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
// 获取用户登录账户的session队列,并将超过规定人数的用户进项标记
public void getSessionQue(Session session, Integer userId) {
Serializable sessionId = session.getId();
// 初始化用户的队列放在缓存中
Deque<Serializable> deque = (Deque<Serializable>) redisTemplate.opsForValue().get(getRedisKickoutKey(userId));
if (deque == null || deque.size() == 0) {
deque = new LinkedList<>();
}
// 队列中没有数据
if (!deque.contains(sessionId) && session.getAttribute("kickout") == null) {
deque.push(sessionId);
}
// 队列数据数量大于设置的用户登录数量
while (deque.size() > maxSession) {
Serializable kickoutSessionId = null;
// 为true踢出后面的登录者
if (kickoutAfter) {
kickoutSessionId = deque.removeFirst();
} else {
kickoutSessionId = deque.removeLast();
}
try {
Session kickoutSession = sessionManager.getSession(new DefaultSessionKey(kickoutSessionId));
if (kickoutSession != null) {
// 设置标记为被踢出
kickoutSession.setAttribute("kickout", true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 更新redis中的用户登录队列
redisTemplate.opsForValue().set(getRedisKickoutKey(userId), deque, EXPIRE_TIME, TimeUnit.SECONDS);
}
// 请求是为小程序或请求接口为登录接口、小程序退出接口
public boolean isMiniProgram(HttpServletRequest request) {
boolean isMini = null != request.getHeader("identity") && request.getHeader("identity").equals("miniprogram");
return isMini || request.getRequestURI().equals("/login") || request.getRequestURI().equals("/wxLogout");
}
// 抛出未登录异常
public void thrLogoutException(HttpServletResponse response, Result.RESULT_FLG resultFlg, BASE_RESP_CODE_ENUM respCodeEnum){
PrintWriter writer = null;
try {
Result result = new Result();
result.setResult(resultFlg.getValue());
if (respCodeEnum != null) {
result.setErrorCode(respCodeEnum.getCode());
result.setErrorMsg(respCodeEnum.getMsg());
}
response.setContentType("application/json; charset=UTF-8");
writer = response.getWriter();
writer.write(JSONObject.fromObject(result).toString());
writer.flush();
} catch (Exception e) {
IOUtils.closeQuietly(writer);
log.error("接口异常:{}", ExceptionUtils.getFullStackTrace(e));
} finally {
if (writer != null) {
writer.close();
}
}
}
}
package cn.wisenergy.shiro.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @description:
* @author: nh
* @create: 2021-04-06 11:31
**/
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
/**
* 根据Bean名称获取Bean对象
*
* @param name Bean名称
* @return 对应名称的Bean对象
*/
public static Object getBean(String name) {
return context.getBean(name);
}
/**
* 根据Bean的类型获取对应的Bean
*
* @param requiredType Bean类型
* @return 对应类型的Bean对象
*/
public static <T> T getBean(Class<T> requiredType) {
return context.getBean(requiredType);
}
/**
* 根据Bean名称获取指定类型的Bean对象
*
* @param name Bean名称
* @param requiredType Bean类型(可为空)
* @return 获取对应Bean名称的指定类型Bean对象
*/
public static <T> T getBean(String name, Class<T> requiredType) {
return context.getBean(name, requiredType);
}
/**
* 判断是否包含对应名称的Bean对象
*
* @param name Bean名称
* @return 包含:返回true,否则返回false。
*/
public static boolean containsBean(String name) {
return context.containsBean(name);
}
/**
* 获取对应Bean名称的类型
*
* @param name Bean名称
* @return 返回对应的Bean类型
*/
public static Class<?> getType(String name) {
return context.getType(name);
}
/**
* 获取上下文对象,可进行各种Spring的上下文操作
*
* @return Spring上下文对象
*/
public static ApplicationContext getContext() {
return context;
}
}
//package com.project.shiro.util;
//
//import cn.wisenergy.common.utils.Md5Util;
//import cn.wisenergy.mapper.WorkUserMapper;
//import cn.wisenergy.model.app.WorkRole;
//import cn.wisenergy.model.app.WorkUser;
//import cn.wisenergy.service.WorkUserService;
//import org.apache.commons.collections.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.shiro.authc.*;
//import org.apache.shiro.authz.AuthorizationInfo;
//import org.apache.shiro.authz.Permission;
//import org.apache.shiro.authz.SimpleAuthorizationInfo;
//import org.apache.shiro.realm.AuthorizingRealm;
//import org.apache.shiro.subject.PrincipalCollection;
//import org.springframework.beans.factory.annotation.Autowired;
//
//import java.util.Collection;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Set;
//
///**
// * 认证
// */
//public class AuthenticationRealm extends AuthorizingRealm {
// // 用户离职状态
// private final static int USER_STATUS = 0;
//
// @Autowired
// private WorkUserMapper workUserMapper;
//
//
// @Autowired
// private WorkUserService workUserService;
//
// /**
// * 获取认证信息
// */
// @Override
// protected AuthenticationInfo doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken token) {
// UsernamePasswordToken authToken = (UsernamePasswordToken) token;
// // 获取登录名、密码
// String username = authToken.getUsername();
// String password = new String(authToken.getPassword());
//
// if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) {
// WorkUser userInfo = workUserMapper.getUserByLoginName(username);
//
// if (userInfo == null) {
// throw new UnknownAccountException();
// }
//
// if (!userInfo.getStatus().equals(USER_STATUS)) {
// throw new DisabledAccountException();
// }
//
//// //用户锁定
//// if (admin.getIsLocked()) {
////
//// //账号锁定分钟数
//// Date lockedDate = admin.getLockedDate();
//// Date unlockedDate = DateUtils.addMinutes(lockedDate, 10);
////
//// //判断锁定时间是否已过
//// if (new Date().after(unlockedDate)) {
//// admin.setLoginFailCnt(0);
//// admin.setIsLocked(false);
//// admin.setLockedDate(null);
//// adminService.update(admin);
//// } else {
//// throw new LockedAccountException();
//// }
//// }
//
// //密码不正确
// if (!Md5Util.digestMD5(password).equals(userInfo.getPassword())) {
// throw new IncorrectCredentialsException();
// }
// return new SimpleAuthenticationInfo(userInfo, password, getName());
// }
// throw new UnknownAccountException();
// }
//
// /**
// * 获取授权信息
// */
// @Override
// protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// WorkUser user = (WorkUser) principals.getPrimaryPrincipal();
//
// if (user != null) {
// SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
//
//// //获取admin对象
//// List<Admin> admins = adminService.getAdminCascadeRole(adminTemp);
//// Admin admin = admins.get(0);
// List<WorkRole> userRole = workUserMapper.getUserRole(user.getId());
//
// //获取用户的角色信息
// Set<String> roleSet = new HashSet<>();
// for (WorkRole role : userRole) {
// roleSet.add(role.getName());
// }
//
// //根据角色ids获取权限信息
//// List<Menu> menuList = menuService.findOrdinaryMenu(principal.getId());
//// Set<String> menuSet = new HashSet<String>();
//// for (Menu menu : menuList) {
//// if (StringUtils.isNotBlank(menu.getCode())) {
//// menuSet.add(menu.getCode());
//// }
//// }
//
// //将角色和资源放入授权对象中
// authInfo.addRoles(roleSet);
//// authInfo.addStringPermissions(menuSet);
// return authInfo;
// }
//
// return null;
// }
//
// /**
// * 超级管理员自动获取所有权限
// */
//// @Override
//// public boolean isPermitted(PrincipalCollection principals, String permission) {
////// User user = ((User) principals.getPrimaryPrincipal());
////// if (Role.ADMIN_FLAG_SUPER_ADMIN == user.getRole().getAdminFlag()) {
////// return true;
////// }
////
//// return isPermitted(principals, getPermissionResolver().resolvePermission(permission));
//// }
//
// @Override
// public boolean isPermitted(PrincipalCollection principals, Permission permission) {
// AuthorizationInfo info = getAuthorizationInfo(principals);
// Collection<Permission> perms = getPermissions(info);
// if (CollectionUtils.isEmpty(perms)) {
// return false;
// }
//
// for (Permission perm : perms) {
// if (perm.implies(permission)) {
// return true;
// }
// }
//
// return false;
// }
//
// /**
// * 踢掉上一个登录的同名用户
// *
// * @param id 主键
// */
//
//// private void stopPreviousSession(Integer id) {
//// Collection<Session> sessions = sessionDAO.getActiveSessions();
//// Session currSession = SecurityUtils.getSubject().getSession();
//// Serializable sId = currSession.getId();
//// for (Session session : sessions) {
//// SimplePrincipalCollection collection = (SimplePrincipalCollection) session
//// .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
//// if (collection == null) {
//// continue;
//// }
////
//// User u = (User) collection.getPrimaryPrincipal();
//// if (id.equals(u.getId())) {
//// if (sId.equals(session.getId())) {
//// continue;
//// }
////
//// session.stop();
//// break;
//// }
//// }
//// }
//
//
//}
//package com.project.shiro.util;
//
//import org.apache.shiro.authc.UsernamePasswordToken;
//
///**
// * 登录令牌
// */
//public class AuthenticationToken extends UsernamePasswordToken {
//
// private static final long serialVersionUID = 4628652632307774263L;
//
// //验证码ID
// private String captchaId;
//
// //验证码
// private String captcha;
//
// //ip保留
// public AuthenticationToken(String loginName, String password, boolean remeberMe, String ip, String captchaId, String caprcha) {
// super(loginName, password, remeberMe);
// this.captchaId = captchaId;
// this.captcha = caprcha;
// }
//
// public String getCaptchaId() {
// return captchaId;
// }
//
// public void setCaptchaId(String captchaId) {
// this.captchaId = captchaId;
// }
//
// public String getCaptcha() {
// return captcha;
// }
//
// public void setCaptcha(String captcha) {
// this.captcha = captcha;
// }
//
//}
//package com.project.shiro.util;
//
//import com.alibaba.fastjson.JSONObject;
//import io.swagger.annotations.ResponseHeader;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
//
//import javax.servlet.ServletRequest;
//import javax.servlet.ServletResponse;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.io.PrintWriter;
//
///**
// * @author wyy
// * @date 2019-09-14 17:57
// */
//public class AuthorizationFilter extends PermissionsAuthorizationFilter {
// /**
// * shiro认证perms资源失败后回调方法
// * @param servletRequest
// * @param servletResponse
// * @return
// * @throws IOException
// */
// @Override
// protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
// HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
// String requestedWith = httpServletRequest.getHeader("X-Requested-With");
// if (StringUtils.isNotEmpty(requestedWith) && StringUtils.equals(requestedWith, "XMLHttpRequest")) {//如果是ajax返回指定格式数据
// httpServletResponse.setContentType("application/json");
// httpServletResponse.setCharacterEncoding("UTF-8");
// PrintWriter out = httpServletResponse.getWriter();
// JSONObject json = new JSONObject();
// json.put("result", "success");
// json.put("msg", "登录成功");
// out.write(json.toJSONString());
// out.flush();
// out.close();
// } else {//如果是普通请求进行重定向
// httpServletResponse.sendRedirect("/403");
// }
// return false;
// }
//}
package cn.wisenergy.shiro.util;
import cn.wisenergy.mapper.WorkUserMapper;
import cn.wisenergy.model.app.WorkUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @description:
* @author: nh
* @create: 2021-04-05 18:04
**/
public class CustomerRealm extends AuthorizingRealm {
@Autowired
private WorkUserMapper workUserMapper;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String principal = (String) token.getPrincipal();
WorkUser user = workUserMapper.getUserByLoginName(principal);
if (user != null) {
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
}
return null;
}
@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
// 存入redis中的认证信息是以"Authentication"+loginName为key
// 在认证信息中中存入的主体信息为WorkUser对象,需要将loginName取出为删除认证信息使用
WorkUser user = (WorkUser)principals.getPrimaryPrincipal();
SimplePrincipalCollection newPrincipals = new SimplePrincipalCollection(user.getLoginName(), this.getName());
super.clearCachedAuthenticationInfo(newPrincipals);
}
}
package cn.wisenergy.shiro.util;
/**
* @description:
* @author: nh
* @create: 2021-04-11 23:45
**/
public class ExceptionUtil {
}
//package com.project.shiro.util;
//
//import java.io.Serializable;
//
//public class Principal implements Serializable {
//
// private static final long serialVersionUID = 598764316789461315L;
//
// public Long id;
//
// public String loginName;
//
// public Principal(Long id, String loginName) {
// this.id = id;
// this.loginName = loginName;
// }
//
// public Principal() {
//
// }
//
// public Long getId() {
// return id;
// }
//
// public void setId(Long id) {
// this.id = id;
// }
//
// public String getLoginName() {
// return loginName;
// }
//
// public void setLoginName(String loginName) {
// this.loginName = loginName;
// }
//
//}
package cn.wisenergy.shiro.util;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
/**
* @description: 自定义sessionManager
* @author: nh
* @create: 2021-04-09 14:25
**/
public class ShiroSessionManager extends DefaultWebSessionManager {
private static final String AUTHORIZATION = "Authorization";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response){
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
if(StringUtils.isEmpty(id)){
//如果没有携带id参数则按照父类的方式在cookie进行获取
return super.getSessionId(request, response);
}else{
//如果请求头中有 authToken 则其值为sessionId
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
return id;
}
}
@Override
public Session getSession(SessionKey key) throws SessionException {
return super.getSession(key);
}
}
package cn.wisenergy.shiro.util.redis;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.BaseCustomException;
import cn.wisenergy.shiro.util.ApplicationContextUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @description:
* @author: nh
* @create: 2021-04-05 18:16
**/
public class RedisCache<K,V> implements Cache<K,V> {
//初始化Log日志
private Logger logger = LoggerFactory.getLogger(this.getClass());
private String cacheName;
private static final long EXPIRE_TIME = 30 * 60;
public RedisCache() {
}
public RedisCache(String cacheName) {
this.cacheName = cacheName;
}
@Override
public V get(K k) throws CacheException {
Object o = getRedisUtil().opsForValue().get(this.cacheName + k.toString());
return (V) o;
}
@Override
public V put(K k, V v) throws CacheException {
getRedisUtil().opsForValue().set(this.cacheName + k.toString(),v,EXPIRE_TIME, TimeUnit.SECONDS);
return null;
}
@Override
public V remove(K k) throws CacheException {
logger.debug("从redis中删除 key [" + k + "]");
try {
V previous = get(k);
getRedisUtil().delete(this.cacheName + k.toString());
return previous;
} catch (Exception e) {
e.printStackTrace();
throw new BaseCustomException(BASE_RESP_CODE_ENUM.RESOURCE_NOT_FOUND);
}
}
@Override
public void clear() throws CacheException {
}
@Override
public int size() {
return 0;
}
@Override
public Set<K> keys() {
return null;
}
@Override
public Collection<V> values() {
return null;
}
RedisTemplate getRedisUtil(){
return (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
}
}
package cn.wisenergy.shiro.util.redis;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
/**
* @description:
* @author: nh
* @create: 2021-04-05 18:17
**/
public class RedisCacheManager implements CacheManager {
@Override
public <K, V> Cache<K, V> getCache(String cacheName) throws CacheException {
return new RedisCache<K,V>(cacheName);
}
}
package com.project.shiro.util.redis; package cn.wisenergy.shiro.util.redis;
import cn.wisenergy.service.common.utils.ByteUtil; import cn.wisenergy.common.utils.ByteUtil;
import cn.wisenergy.service.common.utils.redis.RedisClient;
import cn.wisenergy.service.common.utils.redis.RedisConsts;
import org.apache.shiro.session.Session; import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired;
import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
public class ShiroRedisSessionDAO extends AbstractSessionDAO { /**
* @description:
* @author: nh
* @create: 2021-04-07 11:07
**/
public class RedisSessionDao extends AbstractSessionDAO {
private static Logger logger = LoggerFactory.getLogger(ShiroRedisSessionDAO.class); @Autowired
private RedisTemplate redisTemplate;
//注入redisClient实例 private static final String REDIS_SESSION_PREFIX = "SHIRO_SESSION";
@Resource(name = "redisClient")
private RedisClient redisClient;
/** private static final long EXPIRE_TIME = 30 * 60;
* shiro-redis的session对象前缀
*/
private String keyPrefix = RedisConsts.ADMIN_SHIRO_SESSION_KEY;
@Override @Override
public void update(Session session) throws UnknownSessionException { protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
this.saveSession(session); this.saveSession(session);
return sessionId;
} }
private void saveSession(Session session) throws UnknownSessionException { private void saveSession(Session session) {
if (session == null || session.getId() == null) { if (session == null || session.getId() == null) {
logger.error("session or session id is null");
return; return;
} }
this.redisClient.setAndExpire(this.getPreStringKey(session.getId()), session, RedisConsts.ADMIN_SHIRO_SESSION_EXPIRE); redisTemplate.opsForValue().set(getRedisSessionPrefix(session.getId()), session, EXPIRE_TIME, TimeUnit.SECONDS);
} }
String getRedisSessionPrefix(Serializable sessionId) {
return REDIS_SESSION_PREFIX + sessionId;
}
@Override @Override
public void delete(Session session) { protected Session doReadSession(Serializable sessionId) {
if (session == null || session.getId() == null) { Object o = redisTemplate.opsForValue().get(getRedisSessionPrefix(sessionId));
logger.error("session or session id is null"); return (Session) o;
return; }
}
redisClient.del(getPreStringKey(session.getId())); @Override
public void update(Session session) throws UnknownSessionException {
this.saveSession(session);
}
@Override
public void delete(Session session) {
redisTemplate.delete(getRedisSessionPrefix(session.getId()));
} }
@Override @Override
public Collection<Session> getActiveSessions() { public Collection<Session> getActiveSessions() {
Set<Session> sessions = new HashSet<Session>(); Set<Session> sessions = new HashSet<>();
Set<byte[]> keys = null; Set<byte[]> keys = null;
try { try {
keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*")); redisTemplate.keys(ByteUtil.objectToBytes(REDIS_SESSION_PREFIX + "*"));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -67,7 +79,7 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO { ...@@ -67,7 +79,7 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO {
for (byte[] key : keys) { for (byte[] key : keys) {
Session s = null; Session s = null;
try { try {
s = (Session) ByteUtil.bytesToObject(redisClient.get(key)); s = (Session) ByteUtil.bytesToObject((byte[]) redisTemplate.opsForValue().get(key));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
...@@ -79,51 +91,4 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO { ...@@ -79,51 +91,4 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO {
return sessions; return sessions;
} }
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
this.saveSession(session);
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
if (sessionId == null) {
logger.error("session id is null");
return null;
}
Session s = (Session) redisClient.get(this.getPreStringKey(sessionId));
return s;
}
/**
* 获得String类型的key
*
* @param
* @return
*/
private String getPreStringKey(Serializable sessionId) {
String preKey = this.keyPrefix + sessionId;
return preKey;
}
public String getKeyPrefix() {
return keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
public void setRedisClient(RedisClient redisClient) {
this.redisClient = redisClient;
}
public RedisClient getRedisClient() {
return redisClient;
}
} }
//package com.project.shiro.util.redis;
//
//import cn.wisenergy.service.common.utils.ByteUtil;
//import cn.wisenergy.service.common.utils.redis.RedisClient;
//import cn.wisenergy.service.common.utils.redis.RedisConsts;
//import org.apache.shiro.cache.Cache;
//import org.apache.shiro.cache.CacheException;
//import org.apache.shiro.util.CollectionUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import javax.annotation.Resource;
//import java.io.IOException;
//import java.util.*;
//
//public class ShiroRedisCache<K, V> implements Cache<K, V> {
//
// //初始化Log日志
// private Logger logger = LoggerFactory.getLogger(this.getClass());
//
// //注入redisClient实例
// @Resource(name = "redisClient")
// private RedisClient redisClient;
//
// //shiroSession的key值前缀
// private String keyPrefix;
//
// //通过redisClient实例和prefix参数构造redisCache
// public ShiroRedisCache(RedisClient redisClient, String prefix) {
// if (redisClient == null) {
// throw new IllegalArgumentException("shiroRedisCahe初始化时,redisClient参数不能为空");
// }
// this.redisClient = redisClient;
// this.keyPrefix = prefix;
// }
//
// /**
// * 获得String类型的KEY
// *
// * @param key
// * @return
// */
// private String getPreStringKey(K key) {
// String preKey = null;
// if (key instanceof String) {
// preKey = this.keyPrefix + key;
// return preKey;
// } else {
// try {
// preKey = keyPrefix + ByteUtil.bytesToHexString(ByteUtil.objectToBytes(key));
// } catch (IOException e) {
// e.printStackTrace();
// }
// return preKey;
// }
// }
//
// @Override
// public V get(K key) throws CacheException {
// logger.debug("根据key从Redis中获取对象 key [" + key + "]");
// try {
// if (key == null) {
// return null;
// } else {
// V Vvalue = (V) redisClient.get(getPreStringKey(key));
// if (Vvalue == null) {
// return null;
// }
// return Vvalue;
// }
// } catch (Throwable t) {
// throw new CacheException(t);
// }
//
// }
//
// @Override
// public V put(K key, V value) throws CacheException {
// logger.debug("根据key从存储 key [" + key + "]");
// try {
// redisClient.set(getPreStringKey(key), value);
// redisClient.setAndExpire(getPreStringKey(key), value, RedisConsts.ADMIN_SHIRO_REALM_EXPIRE);
// return value;
// } catch (Throwable t) {
// throw new CacheException(t);
// }
// }
//
// @Override
// public V remove(K key) throws CacheException {
// logger.debug("从redis中删除 key [" + key + "]");
// try {
// V previous = get(key);
// redisClient.del(getPreStringKey(key));
// return previous;
// } catch (Throwable t) {
// throw new CacheException(t);
// }
// }
//
// @Override
// public void clear() throws CacheException {
// logger.debug("从redis中删除所有元素");
// try {
//// redisClient.flushDB();
// } catch (Throwable t) {
// throw new CacheException(t);
// }
// }
//
// @Override
// public int size() {
//// try {
//// Long longSize = new Long(redisClient.dbSize());
//// return longSize.intValue();
//// } catch (Throwable t) {
//// throw new CacheException(t);
//// }
// return 0;
// }
//
// @SuppressWarnings("unchecked")
// @Override
// public Set<K> keys() {
// try {
// Set<byte[]> keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
// if (CollectionUtils.isEmpty(keys)) {
// return Collections.emptySet();
// } else {
// Set<K> newKeys = new HashSet<K>();
// for (byte[] key : keys) {
// newKeys.add((K) key);
// }
// return newKeys;
// }
// } catch (Throwable t) {
// throw new CacheException(t);
// }
// }
//
// @Override
// public Collection<V> values() {
// try {
// Set<byte[]> keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
// if (!CollectionUtils.isEmpty(keys)) {
// List<V> values = new ArrayList<V>(keys.size());
// for (byte[] key : keys) {
// @SuppressWarnings("unchecked")
// V value = get((K) key);
// if (value != null) {
// values.add(value);
// }
// }
// return Collections.unmodifiableList(values);
// } else {
// return Collections.emptyList();
// }
// } catch (Throwable t) {
// throw new CacheException(t);
// }
// }
//
// public String getKeyPrefix() {
// return keyPrefix;
// }
//
// public void setKeyPrefix(String keyPrefix) {
// this.keyPrefix = keyPrefix;
// }
//
// public RedisClient getRedisClient() {
// return redisClient;
// }
//
// public void setRedisClient(RedisClient redisClient) {
// this.redisClient = redisClient;
// }
//}
//package com.project.shiro.util.redis;
//
//
//import cn.wisenergy.service.common.utils.redis.RedisClient;
//import cn.wisenergy.service.common.utils.redis.RedisConsts;
//import org.apache.shiro.cache.Cache;
//import org.apache.shiro.cache.CacheException;
//import org.apache.shiro.cache.CacheManager;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import javax.annotation.Resource;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.ConcurrentMap;
//
//public class ShiroRedisCacheManager implements CacheManager {
//
// private static final Logger logger = LoggerFactory.getLogger(ShiroRedisCacheManager.class);
//
// private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
//
// //注入redisClient实例
// @Resource(name = "redisClient")
// private RedisClient redisClient;
//
// /**
// * shiro权限缓存前缀
// */
// private String keyPrefix = RedisConsts.ADMIN_SHIRO_REALM_KEY;
//
//
// @Override
// public <K, V> Cache<K, V> getCache(String name) throws CacheException {
//
// logger.debug("获取名称为: " + name + " 的RedisCache实例");
// Cache c = caches.get(keyPrefix + name);
// if (c == null) {
// c = new ShiroRedisCache<K, V>(redisClient, keyPrefix);
// caches.put(keyPrefix + name, c);
// }
// return c;
// }
//
// public RedisClient getRedisClient() {
// return redisClient;
// }
//
// public void setRedisClient(RedisClient redisClient) {
// this.redisClient = redisClient;
// }
//
// public String getKeyPrefix() {
// return keyPrefix;
// }
//
// public void setKeyPrefix(String keyPrefix) {
// this.keyPrefix = keyPrefix;
// }
//}
//package com.project.shiro.util.redis;
//
//import cn.wisenergy.service.common.utils.ByteUtil;
//import cn.wisenergy.service.common.utils.redis.RedisClient;
//import cn.wisenergy.service.common.utils.redis.RedisConsts;
//import org.apache.shiro.session.Session;
//import org.apache.shiro.session.UnknownSessionException;
//import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import javax.annotation.Resource;
//import java.io.IOException;
//import java.io.Serializable;
//import java.util.Collection;
//import java.util.HashSet;
//import java.util.Set;
//
//public class ShiroRedisSessionDAO extends AbstractSessionDAO {
//
// private static Logger logger = LoggerFactory.getLogger(ShiroRedisSessionDAO.class);
//
// //注入redisClient实例
// @Resource(name = "redisClient")
// private RedisClient redisClient;
//
// /**
// * shiro-redis的session对象前缀
// */
//
// private String keyPrefix = RedisConsts.ADMIN_SHIRO_SESSION_KEY;
//
// @Override
// public void update(Session session) throws UnknownSessionException {
// this.saveSession(session);
// }
//
// private void saveSession(Session session) throws UnknownSessionException {
// if (session == null || session.getId() == null) {
// logger.error("session or session id is null");
// return;
// }
// this.redisClient.setAndExpire(this.getPreStringKey(session.getId()), session, RedisConsts.ADMIN_SHIRO_SESSION_EXPIRE);
// }
//
// @Override
// public void delete(Session session) {
// if (session == null || session.getId() == null) {
// logger.error("session or session id is null");
// return;
// }
// redisClient.del(getPreStringKey(session.getId()));
//
// }
//
// @Override
// public Collection<Session> getActiveSessions() {
// Set<Session> sessions = new HashSet<Session>();
//
// Set<byte[]> keys = null;
// try {
// keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
// } catch (IOException e) {
// e.printStackTrace();
// }
// if (keys != null && keys.size() > 0) {
// for (byte[] key : keys) {
// Session s = null;
// try {
// s = (Session) ByteUtil.bytesToObject(redisClient.get(key));
// } catch (IOException e) {
// e.printStackTrace();
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// sessions.add(s);
// }
// }
//
// return sessions;
// }
//
// @Override
// protected Serializable doCreate(Session session) {
// Serializable sessionId = this.generateSessionId(session);
// this.assignSessionId(session, sessionId);
// this.saveSession(session);
// return sessionId;
// }
//
// @Override
// protected Session doReadSession(Serializable sessionId) {
// if (sessionId == null) {
// logger.error("session id is null");
// return null;
// }
//
// Session s = (Session) redisClient.get(this.getPreStringKey(sessionId));
// return s;
// }
//
// /**
// * 获得String类型的key
// *
// * @param
// * @return
// */
// private String getPreStringKey(Serializable sessionId) {
// String preKey = this.keyPrefix + sessionId;
// return preKey;
// }
//
// public String getKeyPrefix() {
// return keyPrefix;
// }
//
// public void setKeyPrefix(String keyPrefix) {
// this.keyPrefix = keyPrefix;
// }
//
// public void setRedisClient(RedisClient redisClient) {
// this.redisClient = redisClient;
// }
//
// public RedisClient getRedisClient() {
// return redisClient;
// }
//
//}
package com.project.shiro.config;
import com.project.shiro.util.AuthenticationFilter;
import com.project.shiro.util.AuthenticationRealm;
import com.project.shiro.util.AuthorizationFilter;
import com.project.shiro.util.redis.ShiroRedisCacheManager;
import com.project.shiro.util.redis.ShiroRedisSessionDAO;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Description: shiro配置类
* User: mxy
* Date: 2019-04-16
*/
@Configuration
public class ShiroConfig {
private static final transient Logger logger = LoggerFactory.getLogger(ShiroConfig.class);
/**
* 配置拦截器
* <p>
* 定义拦截URL权限,优先级从上到下
* 1). anon : 匿名访问,无需登录
* 2). authc : 登录后才能访问
* 3). logout: 登出
* 4). frameperms : 自定义的过滤器
* <p>
* URL 匹配风格
* 1). ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/;
* 2). *:匹配零个或多个字符串,如 /admin* 将匹配 /admin 或/admin123,但不匹配 /admin/1;
* 3). **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b
* <p>
* 配置身份验证成功,失败的跳转路径
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
logger.info("进入Shiro拦截工厂");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 设置securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 自定义的过滤器
Map<String, Filter> filterMap = new HashMap<>();
// map里面key值要为过滤器的名称,value为过滤器对象
filterMap.put("authc", authenticationFilter());
filterMap.put("frameperms", authorizationFilter());
// 将自定义的过滤器加入到过滤器集合中
shiroFilterFactoryBean.setFilters(filterMap);
// 设置拦截器集合
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/admin/", "anon"); // 后台资源-匿名访问
filterChainDefinitionMap.put("/admin/res/**", "anon"); // 静态资源-匿名访问
filterChainDefinitionMap.put("/admin/anon/**", "anon"); // 后台可匿名访问资源-匿名访问
filterChainDefinitionMap.put("/admin/login", "authc"); // 登录页面-身份认证
filterChainDefinitionMap.put("/admin/logout", "logout"); // 用户退出,只需配置logout即可实现该功能
filterChainDefinitionMap.put("/admin/common/**", "anon"); // 其他路径均需要身份认证,一般位于最下面,优先级最低
filterChainDefinitionMap.put("/admin/**", "authc,frameperms"); // 其他路径均需要身份认证,一般位于最下面,优先级最低
// 设置拦截器
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
shiroFilterFactoryBean.setLoginUrl("/admin/login"); // 登录的路径
// shiroFilterFactoryBean.setUnauthorizedUrl("/admin/common/unauthorized.jhtml"); // 验证失败后跳转的路径
logger.info("Shiro拦截工厂配置完成");
return shiroFilterFactoryBean;
}
/**
* 配置Shiro生命周期处理器
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* 自动创建代理类,若不添加,Shiro的注解可能不会生效。
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
/**
* 开启Shiro的注解
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
}
/**
* 配置加密匹配,使用MD5的方式,进行1024次加密
*/
// @Bean
// public HashedCredentialsMatcher hashedCredentialsMatcher() {
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName("MD5");
// hashedCredentialsMatcher.setHashIterations(1024);
// return hashedCredentialsMatcher;
// }
/**
* SecurityManager 安全管理器;Shiro的核心
*/
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 自定义的Realm
securityManager.setRealm(authenticationShiroRealm());
// 缓存管理
securityManager.setCacheManager(shiroRedisCacheManager());
// 会话管理
securityManager.setSessionManager(sessionManager());
return securityManager;
}
/**
* 自定义Realm,可以多个
*/
@Bean
public AuthenticationRealm authenticationShiroRealm() {
AuthenticationRealm authenticationRealm = new AuthenticationRealm();
//authenticationRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return authenticationRealm;
}
/**
* redis缓存管理
*/
@Bean
public ShiroRedisCacheManager shiroRedisCacheManager() {
return new ShiroRedisCacheManager();
}
/**
* 设置session会话管理者
*/
@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionIdCookie(simpleCookie());
defaultWebSessionManager.setSessionDAO(shiroRedisSessionDAO());
return defaultWebSessionManager;
}
/**
* session管理
*/
@Bean
public ShiroRedisSessionDAO shiroRedisSessionDAO() {
return new ShiroRedisSessionDAO();
}
/**
* 这里需要设置一个cookie的名称 原因就是会跟原来的session的id值重复的
*/
@Bean
public SimpleCookie simpleCookie() {
return new SimpleCookie("SHAREJSESSIONID");
}
@Bean
public AuthenticationFilter authenticationFilter() {
return new AuthenticationFilter();
}
@Bean
public AuthorizationFilter authorizationFilter() {
return new AuthorizationFilter();
}
}
package com.project.shiro.util;
import com.alibaba.fastjson.JSONObject;
import com.project.model.core.Admin;
import com.project.model.core.Menu;
import com.project.model.core.Role;
import com.project.service.core.AdminService;
import com.project.service.core.MenuService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import javax.annotation.Resource;
import java.io.PrintWriter;
import java.util.*;
/**
* 认证
*/
public class AuthenticationRealm extends AuthorizingRealm {
@Resource(name = "adminServiceImpl")
private AdminService adminService;
@Resource(name = "menuServiceImpl")
private MenuService menuService;
/**
* 获取认证信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken token) {
AuthenticationToken authToken = (AuthenticationToken) token;
// 获取登录名、密码
String username = authToken.getUsername();
String password = new String(authToken.getPassword());
if (username != null && password != null) {
Admin admin = adminService.getByLoginName(username);
if (admin == null) {
throw new UnknownAccountException();
}
if (!admin.getStatus().equals(Admin.STATUS_ENUM.ENABLE.getValue())) {
throw new DisabledAccountException();
}
//用户锁定
if (admin.getIsLocked()) {
//账号锁定分钟数
Date lockedDate = admin.getLockedDate();
Date unlockedDate = DateUtils.addMinutes(lockedDate, 10);
//判断锁定时间是否已过
if (new Date().after(unlockedDate)) {
admin.setLoginFailCnt(0);
admin.setIsLocked(false);
admin.setLockedDate(null);
adminService.update(admin);
} else {
throw new LockedAccountException();
}
}
//密码不正确
if (!DigestUtils.md5Hex(password).equals(admin.getLoginPwd())) {
int loginFailCount = admin.getLoginFailCnt() + 1;
if (loginFailCount >= 5) {
admin.setIsLocked(true);
admin.setLockedDate(new Date());
}
admin.setLoginFailCnt(loginFailCount);
adminService.update(admin);
throw new IncorrectCredentialsException();
}
admin.setLoginFailCnt(0);
adminService.update(admin);
return new SimpleAuthenticationInfo(new Principal(admin.getId(), username), password, getName());
}
throw new UnknownAccountException();
}
/**
* 获取授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Principal principal = (Principal) principals.fromRealm(getName()).iterator().next();
if (principal != null) {
SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
//获取admin对象
Admin adminTemp = new Admin();
adminTemp.setId(principal.getId());
List<Admin> admins = adminService.getAdminCascadeRole(adminTemp);
Admin admin = admins.get(0);
//获取用户的角色信息
Set<String> roleSet = new HashSet<String>();
for (Role role : admin.getRoles()) {
if (role.getStatus().equals(Role.STATUS_ENUM.ENABLE.getValue())) {
roleSet.add(role.getRoleCode());
}
}
//根据角色ids获取权限信息
List<Menu> menuList = menuService.findOrdinaryMenu(principal.getId());
Set<String> menuSet = new HashSet<String>();
for (Menu menu : menuList) {
if (StringUtils.isNotBlank(menu.getCode())) {
menuSet.add(menu.getCode());
}
}
//将角色和资源放入授权对象中
authInfo.addRoles(roleSet);
authInfo.addStringPermissions(menuSet);
return authInfo;
}
return null;
}
/**
* 超级管理员自动获取所有权限
*/
// @Override
// public boolean isPermitted(PrincipalCollection principals, String permission) {
//// User user = ((User) principals.getPrimaryPrincipal());
//// if (Role.ADMIN_FLAG_SUPER_ADMIN == user.getRole().getAdminFlag()) {
//// return true;
//// }
//
// return isPermitted(principals, getPermissionResolver().resolvePermission(permission));
// }
@Override
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
AuthorizationInfo info = getAuthorizationInfo(principals);
Collection<Permission> perms = getPermissions(info);
if (CollectionUtils.isEmpty(perms)) {
return false;
}
for (Permission perm : perms) {
if (perm.implies(permission)) {
return true;
}
}
return false;
}
/**
* 踢掉上一个登录的同名用户
*
* @param id 主键
*/
// private void stopPreviousSession(Integer id) {
// Collection<Session> sessions = sessionDAO.getActiveSessions();
// Session currSession = SecurityUtils.getSubject().getSession();
// Serializable sId = currSession.getId();
// for (Session session : sessions) {
// SimplePrincipalCollection collection = (SimplePrincipalCollection) session
// .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
// if (collection == null) {
// continue;
// }
//
// User u = (User) collection.getPrimaryPrincipal();
// if (id.equals(u.getId())) {
// if (sId.equals(session.getId())) {
// continue;
// }
//
// session.stop();
// break;
// }
// }
// }
}
package com.project.shiro.util;
import org.apache.shiro.authc.UsernamePasswordToken;
/**
* 登录令牌
*/
public class AuthenticationToken extends UsernamePasswordToken {
private static final long serialVersionUID = 4628652632307774263L;
//验证码ID
private String captchaId;
//验证码
private String captcha;
//ip保留
public AuthenticationToken(String loginName, String password, boolean remeberMe, String ip, String captchaId, String caprcha) {
super(loginName, password, remeberMe);
this.captchaId = captchaId;
this.captcha = caprcha;
}
public String getCaptchaId() {
return captchaId;
}
public void setCaptchaId(String captchaId) {
this.captchaId = captchaId;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
}
package com.project.shiro.util;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ResponseHeader;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author wyy
* @date 2019-09-14 17:57
*/
public class AuthorizationFilter extends PermissionsAuthorizationFilter {
/**
* shiro认证perms资源失败后回调方法
* @param servletRequest
* @param servletResponse
* @return
* @throws IOException
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
String requestedWith = httpServletRequest.getHeader("X-Requested-With");
if (StringUtils.isNotEmpty(requestedWith) && StringUtils.equals(requestedWith, "XMLHttpRequest")) {//如果是ajax返回指定格式数据
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding("UTF-8");
PrintWriter out = httpServletResponse.getWriter();
JSONObject json = new JSONObject();
json.put("result", "success");
json.put("msg", "登录成功");
out.write(json.toJSONString());
out.flush();
out.close();
} else {//如果是普通请求进行重定向
httpServletResponse.sendRedirect("/403");
}
return false;
}
}
package com.project.shiro.util;
import java.io.Serializable;
public class Principal implements Serializable {
private static final long serialVersionUID = 598764316789461315L;
public Long id;
public String loginName;
public Principal(Long id, String loginName) {
this.id = id;
this.loginName = loginName;
}
public Principal() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
}
package com.project.shiro.util.redis;
import cn.wisenergy.service.common.utils.ByteUtil;
import cn.wisenergy.service.common.utils.redis.RedisClient;
import cn.wisenergy.service.common.utils.redis.RedisConsts;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
public class ShiroRedisCache<K, V> implements Cache<K, V> {
//初始化Log日志
private Logger logger = LoggerFactory.getLogger(this.getClass());
//注入redisClient实例
@Resource(name = "redisClient")
private RedisClient redisClient;
//shiroSession的key值前缀
private String keyPrefix;
//通过redisClient实例和prefix参数构造redisCache
public ShiroRedisCache(RedisClient redisClient, String prefix) {
if (redisClient == null) {
throw new IllegalArgumentException("shiroRedisCahe初始化时,redisClient参数不能为空");
}
this.redisClient = redisClient;
this.keyPrefix = prefix;
}
/**
* 获得String类型的KEY
*
* @param key
* @return
*/
private String getPreStringKey(K key) {
String preKey = null;
if (key instanceof String) {
preKey = this.keyPrefix + key;
return preKey;
} else {
try {
preKey = keyPrefix + ByteUtil.bytesToHexString(ByteUtil.objectToBytes(key));
} catch (IOException e) {
e.printStackTrace();
}
return preKey;
}
}
@Override
public V get(K key) throws CacheException {
logger.debug("根据key从Redis中获取对象 key [" + key + "]");
try {
if (key == null) {
return null;
} else {
V Vvalue = (V) redisClient.get(getPreStringKey(key));
if (Vvalue == null) {
return null;
}
return Vvalue;
}
} catch (Throwable t) {
throw new CacheException(t);
}
}
@Override
public V put(K key, V value) throws CacheException {
logger.debug("根据key从存储 key [" + key + "]");
try {
redisClient.set(getPreStringKey(key), value);
redisClient.setAndExpire(getPreStringKey(key), value, RedisConsts.ADMIN_SHIRO_REALM_EXPIRE);
return value;
} catch (Throwable t) {
throw new CacheException(t);
}
}
@Override
public V remove(K key) throws CacheException {
logger.debug("从redis中删除 key [" + key + "]");
try {
V previous = get(key);
redisClient.del(getPreStringKey(key));
return previous;
} catch (Throwable t) {
throw new CacheException(t);
}
}
@Override
public void clear() throws CacheException {
logger.debug("从redis中删除所有元素");
try {
// redisClient.flushDB();
} catch (Throwable t) {
throw new CacheException(t);
}
}
@Override
public int size() {
// try {
// Long longSize = new Long(redisClient.dbSize());
// return longSize.intValue();
// } catch (Throwable t) {
// throw new CacheException(t);
// }
return 0;
}
@SuppressWarnings("unchecked")
@Override
public Set<K> keys() {
try {
Set<byte[]> keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
if (CollectionUtils.isEmpty(keys)) {
return Collections.emptySet();
} else {
Set<K> newKeys = new HashSet<K>();
for (byte[] key : keys) {
newKeys.add((K) key);
}
return newKeys;
}
} catch (Throwable t) {
throw new CacheException(t);
}
}
@Override
public Collection<V> values() {
try {
Set<byte[]> keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
if (!CollectionUtils.isEmpty(keys)) {
List<V> values = new ArrayList<V>(keys.size());
for (byte[] key : keys) {
@SuppressWarnings("unchecked")
V value = get((K) key);
if (value != null) {
values.add(value);
}
}
return Collections.unmodifiableList(values);
} else {
return Collections.emptyList();
}
} catch (Throwable t) {
throw new CacheException(t);
}
}
public String getKeyPrefix() {
return keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
public RedisClient getRedisClient() {
return redisClient;
}
public void setRedisClient(RedisClient redisClient) {
this.redisClient = redisClient;
}
}
package com.project.shiro.util.redis;
import cn.wisenergy.service.common.utils.redis.RedisClient;
import cn.wisenergy.service.common.utils.redis.RedisConsts;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ShiroRedisCacheManager implements CacheManager {
private static final Logger logger = LoggerFactory.getLogger(ShiroRedisCacheManager.class);
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
//注入redisClient实例
@Resource(name = "redisClient")
private RedisClient redisClient;
/**
* shiro权限缓存前缀
*/
private String keyPrefix = RedisConsts.ADMIN_SHIRO_REALM_KEY;
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
logger.debug("获取名称为: " + name + " 的RedisCache实例");
Cache c = caches.get(keyPrefix + name);
if (c == null) {
c = new ShiroRedisCache<K, V>(redisClient, keyPrefix);
caches.put(keyPrefix + name, c);
}
return c;
}
public RedisClient getRedisClient() {
return redisClient;
}
public void setRedisClient(RedisClient redisClient) {
this.redisClient = redisClient;
}
public String getKeyPrefix() {
return keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
}
This diff is collapsed.
...@@ -22,12 +22,17 @@ ...@@ -22,12 +22,17 @@
<artifactId>wisenergy-service</artifactId> <artifactId>wisenergy-service</artifactId>
<version>${moduleVersion.wisenergy-service}</version> <version>${moduleVersion.wisenergy-service}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.shiro</groupId> <groupId>cn.wisenergy</groupId>
<artifactId>shiro-spring</artifactId> <artifactId>wisenergy-shiro</artifactId>
<version>1.4.0</version> <version>${moduleVersion.wisenergy-shiro}</version>
</dependency> </dependency>
<!--<dependency>-->
<!--<groupId>org.apache.shiro</groupId>-->
<!--<artifactId>shiro-spring</artifactId>-->
<!--<version>1.4.0</version>-->
<!--</dependency>-->
</dependencies> </dependencies>
<!-- MAVEN构建 --> <!-- MAVEN构建 -->
......
package cn.wisenergy; package cn.wisenergy;
import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
...@@ -13,7 +16,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; ...@@ -13,7 +16,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
*/ */
@EnableCaching @EnableCaching
//排除原有的Multipart配置 spingboot接受不了multipartfile参数 //排除原有的Multipart配置 spingboot接受不了multipartfile参数
@SpringBootApplication(exclude = {MultipartAutoConfiguration.class}) @SpringBootApplication(exclude = {MultipartAutoConfiguration.class, ShiroAnnotationProcessorAutoConfiguration.class, ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
@MapperScan(basePackages = "cn.wisenergy.mapper") @MapperScan(basePackages = "cn.wisenergy.mapper")
@EnableSwagger2 @EnableSwagger2
@EnableScheduling @EnableScheduling
......
...@@ -11,12 +11,14 @@ import io.swagger.annotations.ApiImplicitParams; ...@@ -11,12 +11,14 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** /**
* @description: * @description:
...@@ -50,12 +52,15 @@ public class WorkUserController extends BaseController { ...@@ -50,12 +52,15 @@ public class WorkUserController extends BaseController {
@ApiImplicitParam(name = "source", value = "登录来源:PC/WAP", dataType = "string", required = true) @ApiImplicitParam(name = "source", value = "登录来源:PC/WAP", dataType = "string", required = true)
}) })
@GetMapping(value = "/login") @GetMapping(value = "/login")
public Result<ResultUser> login(String loginName, String password, String source, HttpServletRequest request) { public Result login(String loginName, String password, String source, HttpServletRequest request, HttpServletResponse response) {
log.info("WorkUserController[]login[]input.param" + loginName + password + source); log.info("WorkUserController[]login[]input.param" + loginName + password + source);
if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password) || StringUtils.isEmpty(source)) { if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password) || StringUtils.isEmpty(source)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL); throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
} }
ResultUser resultUser = workUserService.login(loginName, password, source, request); ResultUser resultUser = workUserService.login(loginName, password, source);
String sessionId = request.getSession().getId();
response.setHeader("sessionId", sessionId);
response.setHeader("Access-Control-Expose-Headers", "sessionId");
return getResult(resultUser); return getResult(resultUser);
} }
...@@ -77,10 +82,41 @@ public class WorkUserController extends BaseController { ...@@ -77,10 +82,41 @@ public class WorkUserController extends BaseController {
@ApiOperation(value = "组织架构", notes = "组织架构", httpMethod = "GET") @ApiOperation(value = "组织架构", notes = "组织架构", httpMethod = "GET")
@GetMapping(value = "/getOrganizationStructureDto") @GetMapping(value = "/getOrganizationStructureDto")
public Result<OrganizationDto> getOrganizationStructureDto(){ public Result<OrganizationDto> getOrganizationStructureDto() {
log.info("WorkUserController[]getOrganizationStructureDto[]"); log.info("WorkUserController[]getOrganizationStructureDto[]");
OrganizationDto organizationDto = workUserService.getOrganizationStructure(); OrganizationDto organizationDto = workUserService.getOrganizationStructure();
return getResult(organizationDto); return getResult(organizationDto);
} }
@ApiOperation(value = "PC端登出", notes = "PC端登出")
@GetMapping("/PCLogout")
public Result logout() {
SecurityUtils.getSubject().logout();
return getResult(null);
}
@ApiOperation(value = "微信登出", notes = "微信登出")
@GetMapping("/wxLogout")
public Result wxLogout(Integer userId) {
log.info("UserController[]wxLogout[].input.para{}userId" + userId);
workUserService.wxLogout(userId);
return getResult(null);
}
@ApiOperation(value = "微信登录", notes = "微信登录")
@GetMapping("/wxLogin")
public Result wxLogin(String code) {
log.info("UserController[]wxLogin[]input.param{}");
ResultUser user = workUserService.weChatLogin(code);
return getResult(user);
}
@ApiOperation(value = "用户绑定微信openid", notes = "用户绑定微信openid")
@GetMapping("/bindWeChat")
public Result bindWeChat(Integer userId, String code) {
log.info("UserController[]binWeChat[]input.param{}userId,code" + userId + "," + code);
boolean b = workUserService.bindWeChat(userId, code);
return getResult(b);
}
} }
package cn.wisenergy.web.config.hanlder; //package cn.wisenergy.web.config.hanlder;
//
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM; //import cn.wisenergy.common.utils.RedisUtil;
import cn.wisenergy.common.utils.exception.BaseCustomException; //import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import org.springframework.stereotype.Component; //import cn.wisenergy.common.utils.exception.BaseCustomException;
//import org.apache.commons.lang.StringUtils;
import javax.servlet.*; //import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest; //import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession; //
import java.io.IOException; //import javax.servlet.*;
import java.util.Arrays; //import javax.servlet.http.HttpServletRequest;
import java.util.Collection; //import javax.servlet.http.HttpSession;
import java.util.List; //import java.io.IOException;
import java.util.Map; //import java.util.Arrays;
//import java.util.List;
/** //
* @description: ///**
* @author: nh // * @description:
* @create: 2021-04-01 10:44 // * @author: nh
**/ // * @create: 2021-04-01 10:44
@Component // **/
public class LoginFilter implements Filter { //@Component
//public class LoginFilter implements Filter {
private final static List<String> URI_LIST = Arrays.asList("/login","/webjars","/swagger-resources", //
"/null","/v2","/swagger-ui.html","/work/collect","/work/order/addOrder","/work/order/examine","/work/order/getDeptNotOrderInfo", // @Autowired
"/work/order/getExamineApplets","/work/order/getProject","/work/order/noSubmit","/work/order/query","/work/order/reject", // private RedisUtil redisUtil;
"/changePassword","getUserInfo","/statistics/getCurrentMonthWorkTimeCollect","/statistics/getMonthlyWorkingHours"); //
// private static final int SESSION_EXPIRE = 30 * 60;
@Override //
public void init(FilterConfig filterConfig) throws ServletException { // private final static List<String> URI_LIST = Arrays.asList("/login","/webjars","/swagger-resources",
// "/null","/v2","/swagger-ui.html","/work/collect","/work/order/addOrder","/work/order/examine","/work/order/getDeptNotOrderInfo",
} // "/work/order/getExamineApplets","/work/order/getProject","/work/order/noSubmit","/work/order/query","/work/order/reject",
// "/changePassword","/getUserInfo","/statistics/getCurrentMonthWorkTimeCollect","/statistics/getMonthlyWorkingHours");
@Override //
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // @Override
HttpServletRequest httpServletRequest = (HttpServletRequest) request; // public void init(FilterConfig filterConfig) throws ServletException {
HttpSession session = httpServletRequest.getSession(); //
// }
ServletContext application = session.getServletContext(); //
Map<String, String> loginMap = (Map<String, String>) application.getAttribute("loginMap"); // @Override
// 请求接口不为登录再过滤 // public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String requestURI = ((HttpServletRequest) request).getRequestURI(); // HttpServletRequest httpServletRequest = (HttpServletRequest) request;
for (String s : URI_LIST) { // HttpSession session = httpServletRequest.getSession(false);
if (requestURI.startsWith(s)) { //
chain.doFilter(request,response); // // 请求接口不为指定接口再过滤
return; // String requestURI = ((HttpServletRequest) request).getRequestURI();
} // System.out.println("requestURI = " + requestURI);
} // for (String s : URI_LIST) {
if (loginMap == null) { // if (requestURI.startsWith(s)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN); // chain.doFilter(request,response);
} // return;
Collection<String> values = loginMap.values(); // }
if (!values.contains(session.getId())) { // }
throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN); //
} // // 请求没有携带session
} // if (session == null) {
// System.out.println("session Is Null");
@Override // throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
public void destroy() { // }
// System.out.println("session.getId() = " + session.getId());
} // // 获取redis中存储的登录时存放的session
} // String sessionCache = redisUtil.get(session.getId());
// // session为空,session与登录时的session不一致提示重新登录,不为空则进行下一个过滤
// if (StringUtils.isBlank(sessionCache)) {
// throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
// } else if (!sessionCache.equals(session)) {
// throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
// } else {
// redisUtil.set(session.getId(), session.toString(), SESSION_EXPIRE);
// chain.doFilter(request, response);
// }
//
// }
//
// @Override
// public void destroy() {
//
// }
//}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment