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

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

parent e4a08e6e
......@@ -20,6 +20,7 @@
<module>wisenergy-model</module>
<module>wisenergy-mapper</module>
<module>wisenergy-service</module>
<module>wisenergy-shiro</module>
<module>wisenergy-web-admin</module>
</modules>
......@@ -36,6 +37,7 @@
<moduleVersion.wisenergy-model>1.0.0-${projectDevMode}</moduleVersion.wisenergy-model>
<moduleVersion.wisenergy-mapper>1.0.0-${projectDevMode}</moduleVersion.wisenergy-mapper>
<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>
</properties>
......
......@@ -123,16 +123,16 @@
<artifactId>joda-time</artifactId>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.apache.shiro</groupId>-->
<!--<artifactId>shiro-core</artifactId>-->
<!--<version>1.4.0</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.apache.shiro</groupId>-->
<!--<artifactId>shiro-spring</artifactId>-->
<!--<version>1.4.0</version>-->
<!--</dependency>-->
<!-- POI -->
<dependency>
<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.context.annotation.Bean;
......@@ -13,16 +13,17 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
*/
@Configuration
public class RedisConfig {
@Autowired
private RedisConnectionFactory factory;
@Bean
@Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new SerializeUtils());
redisTemplate.setValueSerializer(new SerializeUtils());
redisTemplate.setConnectionFactory(factory);
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;
import cn.wisenergy.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
......@@ -37,10 +36,10 @@ public class BaseExceptionHandler {
return R.error("数据库中已存在该记录");
}
@ExceptionHandler(AuthorizationException.class)
public R<?> handleAuthorizationException(AuthorizationException e){
log.error(e.getMessage(), e);
return R.error("没有权限,请联系管理员授权");
}
// @ExceptionHandler(AuthorizationException.class)
// public R<?> handleAuthorizationException(AuthorizationException e){
// log.error(e.getMessage(), e);
// return R.error("没有权限,请联系管理员授权");
// }
}
......@@ -29,7 +29,7 @@ public class RedisUtil {
public final static long NOT_EXPIRE = -1;
public void set(String key, Object value){
set(key, value);
valueOperations.set(key, toJson(value));
}
public void set(String key, Object value, long expire){
......@@ -68,6 +68,7 @@ public class RedisUtil {
return redisTemplate.delete(key);
}
/**
* 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 {
PLEASE_CANCELTHE_MANAGEMENTROLE("669", "注销账号,请取消管理角色"),
ATLEASTONEADMINISTRATORISREQUIRED("670", "至少需要一个系统管理员!"),
PLEASESELECTANITEM("671", "请选择一个项目"),
PLEASESELECTADEPARTMENT("672","请选择一个部门")
PLEASESELECTADEPARTMENT("672","请选择一个部门"),
WECHAT_NOT_BIND("673","微信未绑定")
;
......
......@@ -32,7 +32,7 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> {
*/
WorkUser getUserById(Integer userId);
Integer updateUserInfo(WorkUser user);
int updateUserInfo(WorkUser user);
/**
* 获取用户主键、姓名、部门名称
......@@ -46,7 +46,16 @@ public interface WorkUserMapper extends BaseMapper<WorkUser> {
List<WorkRole> getUserRole(Integer id);
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 @@
</sql>
<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 id="values">
......@@ -87,6 +87,7 @@
from <include refid="table"/>
where id = #{userId}
</select>
<select id="getStatisticsTableDtos" resultType="cn.wisenergy.model.dto.StatisticsTableDto">
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
......@@ -102,6 +103,7 @@
set <include refid="updateCondition"/>
where id = #{id}
</update>
<update id="updateStatusAndSubmitOrderById">
update <include refid="table"/>
<set>
......@@ -115,6 +117,12 @@
where id = #{userId}
</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">
<id column="id" property="id"/>
......@@ -171,4 +179,20 @@ LEFT JOIN work_role r on ur.role_id = r.id
ORDER BY CONVERT( `name` USING gbk )
</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>
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 @@
<artifactId>wisenergy-mapper</artifactId>
<version>${moduleVersion.wisenergy-mapper}</version>
</dependency>
<dependency>
<groupId>cn.wisenergy</groupId>
<artifactId>wisenergy-shiro</artifactId>
<version>${moduleVersion.wisenergy-shiro}</version>
</dependency>
<!--综合安防管理平台提供了OpenAPI安全认证库(Java、C++)快速实现接口调用。-->
<dependency>
<groupId>com.hikvision.ga</groupId>
......
package cn.wisenergy.service;
import cn.wisenergy.model.app.WorkUser;
import cn.wisenergy.model.dto.AllRoleAndUserRoleDto;
import cn.wisenergy.model.dto.OrganizationDto;
import cn.wisenergy.model.dto.OrganizationStructureDto;
import cn.wisenergy.model.dto.ResultUser;
import cn.wisenergy.model.dto.*;
import cn.wisenergy.model.vo.GetUserListVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
......@@ -27,10 +23,9 @@ public interface WorkUserService {
* @param loginName 登录名
* @param password 密码
* @param source 登录来源
* @param request
* @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 {
Boolean reSetPassword(Integer userId);
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 {
return insert1 > 0;
}
private OrderChangeDto getProjevtAndTypeOfDept(Integer userId, Boolean isFillIn, Boolean addProjectOfDept) {
if (null == userId) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
......
package cn.wisenergy.service.impl;
import cn.hutool.json.JSONObject;
import cn.wisenergy.common.utils.Md5Util;
import cn.wisenergy.common.utils.WeChatUtil;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.BaseCustomException;
import cn.wisenergy.mapper.WorkRoleMapper;
......@@ -17,21 +19,25 @@ import cn.wisenergy.service.WorkDeptService;
import cn.wisenergy.service.WorkSubmitAdoptService;
import cn.wisenergy.service.WorkUserService;
import cn.wisenergy.service.utils.UserRoleLevelUtils;
import cn.wisenergy.shiro.filter.KickoutSessionControlFilter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
/**
......@@ -68,6 +74,8 @@ public class WorkUserServiceImpl implements WorkUserService {
// 用户在职状态码
private static final Integer ON_THE_JOB_STATUS = 1;
@Autowired
private KickoutSessionControlFilter kickoutSessionControlFilter;
@Override
public WorkUser getById(Integer id) {
......@@ -97,11 +105,10 @@ public class WorkUserServiceImpl implements WorkUserService {
@Override
public ResultUser changePassword(Integer userId, String oldPassword, String newPassword) {
log.info("WorkUserServiceImpl[]changePassword[]input.param{}" + userId + oldPassword + newPassword);
log.info("WorkUserServiceImpl[]changePassword[]input.param{}" + userId + "," + oldPassword + "," + newPassword);
if (userId == null || StringUtils.isEmpty(oldPassword) || StringUtils.isEmpty(newPassword)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
}
//新密码与旧密码相同
if (oldPassword.equals(newPassword)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.NEW_PASSWORD_IS_HTE_SAME_OLD_PASSWORD);
......@@ -241,7 +248,7 @@ public class WorkUserServiceImpl implements WorkUserService {
int DeptUpdateIndex = 0;
int centreUpdateIndex = 0;
if (!CollectionUtils.isEmpty(roles) && 1==workUser.getStatus()) {
if (!CollectionUtils.isEmpty(roles) && 1 == workUser.getStatus()) {
for (Integer role : roles) {
// 部门经理
if (2 == role) {
......@@ -325,22 +332,91 @@ public class WorkUserServiceImpl implements WorkUserService {
}
@Override
public ResultUser login(String loginName, String password, String source, HttpServletRequest request) {
public ResultUser weChatLogin(String code) {
// 2.开发者服务器 登录凭证校验接口 appId + appSecret + 接收小程序发送的code
JSONObject SessionKeyOpenId = WeChatUtil.getSessionKeyOrOpenId(code);
// 3.接收微信接口服务 获取返回的参数
String openid = SessionKeyOpenId.get("openid", String.class);
if (StringUtils.isEmpty(openid)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.WECHAT_NOT_BIND);
}
// 5.根据返回的User实体类,判断用户是否存在
WorkUser user = workUserMapper.getUserByOpenId(openid);
if (user == null) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.WECHAT_NOT_BIND);
}
// 调用shiro登录
// UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), user.getPassword());
List<Integer> roles = UserRoleLevelUtils.getRole(user.getId());
// 限制审核的天数
WorkSubmitAdopt byId = workSubmitAdoptService.getById(1);
ResultUser resultUser = getResultUser(user, byId, roles);
return resultUser;
}
@Override
public boolean bindWeChat(Integer userId, String code) {
log.info("WorkUserServiceImpl[]bindWeChat[]input.param{}userName,code" + userId + "," + code);
if (userId == null || StringUtils.isEmpty(code)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
}
// 获取用户信息
WorkUser userById = workUserMapper.getUserById(userId);
// 获取openid
JSONObject SessionKeyOpenId = WeChatUtil.getSessionKeyOrOpenId(code);
String openid = SessionKeyOpenId.get("openid", String.class);
// 将用户与openid绑定
userById.setWxId(openid);
int integer = workUserMapper.updateUserInfo(userById);
if (integer == 0) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
}
return true;
}
@Override
public void wxLogout(Integer userId) {
log.info("WorkUserServiceImpl[]wxLogout[]input.param{}userId" + userId);
int update = workUserMapper.clearOpenidByUserId(userId);
if (update == 0) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
}
log.info("WorkUserServiceImpl[]wxLogout[]" + userId + "退出");
}
@Override
public ResultUser login(String loginName, String password, String source) {
log.info("WorkUserServiceImpl[]login[].input.param" + loginName + password + source);
if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
}
//MD5加密
String md5Password = Md5Util.digestMD5(password);
HashMap<String, Object> map = new HashMap<>();
map.put("loginName", loginName);
map.put("password", md5Password);
WorkUser user = workUserMapper.getUserInfo(map);
if (null == user) {
// shiro验证
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
WorkUser user = null;
try {
// shiro登录处理
subject.login(token);
// 用户信息
user = (WorkUser) subject.getPrincipal();
// 登录请求不进入自定义shiro拦截器,在这里进行一次,统一账户多登录踢出处理
kickoutSessionControlFilter.getSessionQue(subject.getSession(), user.getId());
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_LOGIN_NAME_OR_PASSWORD_IS_ERROR);
} catch (UnknownAccountException e) {
e.printStackTrace();
throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_LOGIN_NAME_OR_PASSWORD_IS_ERROR);
} catch (AuthenticationException e) {
e.printStackTrace();
throw new BaseCustomException(BASE_RESP_CODE_ENUM.NO_AUTH_REQUEST);
}
// 是否离职状态
// 是否离职状态,抛出异常
if (!user.getStatus().equals(ON_THE_JOB_STATUS)) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.LEAVE_JOB_USER);
}
......@@ -351,49 +427,13 @@ public class WorkUserServiceImpl implements WorkUserService {
if (roles.contains(ManagerEnum.NOT_MANAGER.getCode())) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
}
// 限制单设备登录
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
// 获取存储登录
Map<String, String> loginMap = (Map<String, String>) application.getAttribute("loginMap");
Map<String, HttpSession> sessionMap = (Map<String, HttpSession>) application.getAttribute("sessionMap");
String id = String.valueOf(user.getId());
if (loginMap == null) {
loginMap = new HashMap<>();
sessionMap = new HashMap<>();
}
if (loginMap.get(id) == null) {
loginMap.put(id, session.getId());
System.out.println("session.getId() = " + session.getId());
sessionMap.put(session.getId(), session);
System.out.println("session = " + session);
} else {
String sessionId = loginMap.get(id); //根据id获取上一个用户的sessionId
HttpSession oldSession = sessionMap.get(sessionId); //根据sessionId获取上一个用户的session
oldSession.invalidate();
sessionMap.remove(oldSession.getId()); //根据sessionId删除旧session
sessionMap.put(session.getId(), session);
loginMap.remove(id); //移除id和oldSession对应关系
loginMap.put(id, session.getId()); //添加新的id和oldSession对应关系
}
application.setAttribute("loginMap", loginMap); // 添加两个HashMap到Application,重要
application.setAttribute("sessionMap", sessionMap);
}
// 限制审核的天数
WorkSubmitAdopt byId = workSubmitAdoptService.getById(1);
//将用户对象转换为dto
ResultUser resultUser = getResultUser(user);
resultUser.setDay(byId.getSubmitTime());
List<Integer> levelIds = UserRoleLevelUtils.getlevelIds(roles);
List<WorkLevel> workLevels = UserRoleLevelUtils.getlevelByIds(levelIds);
if (!CollectionUtils.isEmpty(workLevels)) {
Collections.sort(workLevels);
resultUser.setWorkLevels(workLevels);
}
ResultUser resultUser = getResultUser(user, byId, roles);
return resultUser;
}
......@@ -436,4 +476,16 @@ public class WorkUserServiceImpl implements WorkUserService {
return userDto;
}
private ResultUser getResultUser(WorkUser workUser, WorkSubmitAdopt workSubmitAdopt, List<Integer> roles) {
ResultUser resultUser = getResultUser(workUser);
resultUser.setDay(workSubmitAdopt.getSubmitTime());
List<Integer> levelIds = UserRoleLevelUtils.getlevelIds(roles);
List<WorkLevel> workLevels = UserRoleLevelUtils.getlevelByIds(levelIds);
if (!CollectionUtils.isEmpty(workLevels)) {
Collections.sort(workLevels);
resultUser.setWorkLevels(workLevels);
}
return resultUser;
}
}
......@@ -3,12 +3,15 @@
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">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>wisenergy-parent</artifactId>
<groupId>org.yun</groupId>
<groupId>cn.wisenergy</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>wisenergy-shiro</artifactId>
<version>${moduleVersion.wisenergy-shiro}</version>
<packaging>jar</packaging>
......@@ -17,19 +20,22 @@
<dependencies>
<!-- 模块依赖 -->
<dependency>
<groupId>org.yun</groupId>
<artifactId>wisenergy-service</artifactId>
<version>${moduleVersion.wisenergy-service}</version>
<groupId>cn.wisenergy</groupId>
<artifactId>wisenergy-mapper</artifactId>
<version>${moduleVersion.wisenergy-mapper}</version>
</dependency>
<!-- Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
<!-- MAVEN构建 -->
<build>
<finalName>${project.artifactId}-${moduleVersion.project-shiro}</finalName>
<finalName>${project.artifactId}-${moduleVersion.wisenergy-shiro}</finalName>
</build>
</project>
\ No newline at end of file
package cn.wisenergy.shiro.config;
import cn.wisenergy.shiro.filter.CustomerLogoutFilter;
import cn.wisenergy.shiro.filter.KickoutSessionControlFilter;
import cn.wisenergy.shiro.util.CustomerRealm;
import cn.wisenergy.shiro.util.ShiroSessionManager;
import cn.wisenergy.shiro.util.redis.RedisCacheManager;
import cn.wisenergy.shiro.util.redis.RedisSessionDao;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
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 getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultSecurityManager securityManager){
logger.info("进入Shiro拦截工厂");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 给shiroFilterFactoryBean设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 自定义过滤器
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("kickout", kickoutSessionControlFilter());
filterMap.put("wxLogout", customerLogoutFilter());
shiroFilterFactoryBean.setFilters(filterMap);
// 配置系统公共受限资源和公共资源
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("/login", "anon");
map.put("/swagger-ui.html","anon");
map.put("/swagger/**","anon");
map.put("/webjars/**", "anon");
map.put("/swagger-resources/**","anon");
map.put("/v2/**","anon");
map.put("/static/**", "anon");
map.put("/**", "kickout");
map.put("/wxLogout", "wxLogout");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
// 未登录返回
// shiroFilterFactoryBean.setLoginUrl("/unLogin");
return shiroFilterFactoryBean;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultSecurityManager(@Qualifier("realm") Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
securityManager.setSessionManager(sessionManager());
return securityManager;
}
@Bean(name = "realm")
public Realm getRealm(){
CustomerRealm customerRealm = new CustomerRealm();
// 凭证校验匹配器
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// 设置加密算法为MD5
hashedCredentialsMatcher.setHashAlgorithmName("MD5");
hashedCredentialsMatcher.setHashIterations(1);
// 设置realm的凭证校验器
customerRealm.setCredentialsMatcher(hashedCredentialsMatcher);
// 全局缓存
customerRealm.setCacheManager(new RedisCacheManager());
customerRealm.setCachingEnabled(true);
// 开启认证缓存管理
customerRealm.setAuthenticationCachingEnabled(true);
// 认证缓存的名称
customerRealm.setAuthenticationCacheName("AuthenticationRedisCache");
return customerRealm;
}
@Bean
public SessionManager sessionManager(){
ShiroSessionManager sessionManager = new ShiroSessionManager();
sessionManager.setSessionIdCookie(simpleCookie());
sessionManager.setSessionDAO(sessionDAO());
return sessionManager;
}
@Bean
public SessionDAO sessionDAO(){
RedisSessionDao redisSessionDao = new RedisSessionDao();
return redisSessionDao;
}
@Bean
public SimpleCookie simpleCookie(){
SimpleCookie sharejsessionid = new SimpleCookie("SHAREJSESSIONID");
sharejsessionid.setHttpOnly(false);
return sharejsessionid;
}
/**
* 并发登录控制,限制登录人数为1
*/
@Bean("kickout")
public KickoutSessionControlFilter kickoutSessionControlFilter(){
KickoutSessionControlFilter kickoutSessionControlFilter = new KickoutSessionControlFilter();
kickoutSessionControlFilter.setSessionManager(sessionManager());
return kickoutSessionControlFilter;
}
@Bean("wxLogout")
public CustomerLogoutFilter customerLogoutFilter(){
CustomerLogoutFilter customerLogoutFilter = new CustomerLogoutFilter();
return customerLogoutFilter;
}
// @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("/getUserInfo", "authc");
//// filterChainDefinitionMap.put("/admin/logout", "logout"); // 用户退出,只需配置logout即可实现该功能
//// filterChainDefinitionMap.put("/admin/common/**", "anon"); // 其他路径均需要身份认证,一般位于最下面,优先级最低
//// filterChainDefinitionMap.put("/admin/**", "authc,frameperms"); // 其他路径均需要身份认证,一般位于最下面,优先级最低
//
// // 设置拦截器
// shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// shiroFilterFactoryBean.setLoginUrl("/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 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 com.alibaba.fastjson.JSONObject;
//import org.apache.shiro.authc.AuthenticationException;
//import org.apache.shiro.authc.AuthenticationToken;
//import org.apache.shiro.subject.Subject;
//import org.apache.shiro.util.StringUtils;
//import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
//import org.apache.shiro.web.util.WebUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//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/07/26
// */
//public class AuthenticationFilter extends FormAuthenticationFilter {
// private static final Logger log = LoggerFactory.getLogger(AuthenticationFilter.class);
//
// //加密密码参数
// private static final String DEFAULT_EN_PASSWORD_PARAM = "enPassword";
//
// //默认的登录名称
// private static final String DEFAULT_USERNAME_PARAM = "loginName";
//
// //默认验证码ID参数
// private static final String DEFAULT_CAPTCHA_ID_PARAM = "captchaId";
//
// //默认验证码参数
// private static final String DEFAULT_CAPTCHA_PARAM = "captcha";
//
// private String captchaIdParam = DEFAULT_CAPTCHA_ID_PARAM;
//
// private String captchaParam = DEFAULT_CAPTCHA_PARAM;
//
// private String usernameParam = DEFAULT_USERNAME_PARAM;
//
// private String enPasswordParam = DEFAULT_EN_PASSWORD_PARAM;
//
// /**
// * 创建token
// */
// @Override
// protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
// String loginName = getUsername(request);
// String password = getPassword(request);
// boolean isRemeberMe = isRememberMe(request);
// String ip = getHost(request);
// return new com.project.shiro.util.AuthenticationToken(loginName, password, isRemeberMe, ip, "", "");
// }
//
// /**
// * 登录拒绝;增加Ajax异步处理
// *
// * @param servletRequest 请求对象
// * @param servletResponse 响应对象
// * @return
// * @throws Exception
// */
// @Override
// protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
// // 判断是否为ajax异步请求
// HttpServletRequest request = (HttpServletRequest) servletRequest;
// HttpServletResponse response = (HttpServletResponse) servletResponse;
//
// // 判断是否为登录请求
// if (this.isLoginRequest(servletRequest, response)) {
// if (this.isLoginSubmission(servletRequest, response)) {
//
// if (log.isTraceEnabled()) {
// log.trace("Login submission detected. Attempting to execute login.");
// }
// boolean b = executeLogin(servletRequest, response);
// return b;
// } else {
// if (log.isTraceEnabled()) {
// log.trace("Login page view.");
// }
// return true;
// }
// } else {
// if (log.isTraceEnabled()) {
// log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
// }
//
// // 异步请求报错
// if (isAjaxReq(request, response)) {
// response.setContentType("application/json");
// response.setCharacterEncoding("UTF-8");
// PrintWriter out = response.getWriter();
// JSONObject json = new JSONObject();
// json.put("result", "fail");
// json.put("msg", "未登录");
// out.println(json);
// out.flush();
// out.close();
// return false;
// }
//
//// 如果同步请求继续执行基类方法(当为同步方法的时候,基类会直接跳转登录页面)
// return super.onAccessDenied(request, response);
// }
//
// }
//
// /**
// * 重写登录成功的方法;如果为异步请求,直接返回成功响应
// *
// * @param token
// * @param subject
// * @param servletRequest
// * @param servletResponse
// * @return
// * @throws Exception
// */
// @Override
// protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
// // 如果为异步请求,登录成功后,直接返回数据,前台跳转登录后的页面处理
// if (isAjaxReq(servletRequest, servletResponse)) {
// HttpServletResponse response = (HttpServletResponse) servletResponse;
// response.setContentType("application/json");
// response.setCharacterEncoding("UTF-8");
// PrintWriter out = response.getWriter();
// JSONObject json = new JSONObject();
// json.put("result", "success");
// json.put("msg", "登录成功");
// out.write(json.toJSONString());
// out.flush();
// out.close();
// return true;
// }
// return super.onLoginSuccess(token, subject, servletRequest, servletResponse);
// }
//
// @Override
// public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
// //Always return true if the request's method is OPTIONSif (request instanceof HttpServletRequest) {
// if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
// return true;
// }
// return super.isAccessAllowed(request, response, mappedValue);
// }
//
// /**
// * 重写登录失败的方法;如果为异步请求,直接返回失败响应
// *
// * @param token
// * @param e
// * @param request
// * @param response
// * @return
// */
// @Override
// protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
// // 如果为异步登录,直接返回错误结果
// if (isAjaxReq(request, response)) {
// PrintWriter out = null;
// try {
// response = (HttpServletResponse) response;
// response.setContentType("application/json");
// response.setCharacterEncoding("UTF-8");
// out = response.getWriter();
// JSONObject json = new JSONObject();
// if (e.equals("org.apache.shiro.authc.pam.UnsupportedTokenException")) {
// String message = "验证码错误!";
// json.put("result", "fail");
// json.put("msg", message);
// } else if (e.equals("org.apache.shiro.authc.UnknownAccountException")) {
// String message = "此账号不存在!";
// json.put("result", "fail");
// json.put("msg", message);
// } else if (e.equals("org.apache.shiro.authc.DisabledAccountException")) {
// String message = "此账号已被禁用!";
// json.put("result", "fail");
// json.put("msg", message);
// } else if (e.equals("org.apache.shiro.authc.LockedAccountException")) {
// String message = "此账号已被锁定";
// json.put("result", "fail");
// json.put("msg", message);
// } else if (e.equals("org.apache.shiro.authc.IncorrectCredentialsException")) {
// String message = "密码错误";
// json.put("result", "fail");
// json.put("msg", message);
// } else if (e.equals("org.apache.shiro.authc.AuthenticationException")) {
// String message = "账号认证失败!";
// json.put("result", "fail");
// json.put("msg", message);
// }
// out.write(json.toJSONString());
// out.flush();
// out.close();
// return false;
// } catch (IOException ex) {
// ex.printStackTrace();
// log.error("shiro认证失败");
// }
//
// }
//
// // 同步请求走基类
// return super.onLoginFailure(token, e, request, response);
// }
//
//
// /**
// * 获取密码
// *
// * @param servletRequest
// * @return
// */
// @Override
// protected String getPassword(ServletRequest servletRequest) {
// String parameter = servletRequest.getParameter(enPasswordParam);
// HttpServletRequest request = (HttpServletRequest) servletRequest;
// String enPasswor = request.getParameter(enPasswordParam);
// String password = enPasswor;
// return password;
// }
//
// /**
// * 判断是否为Ajax请求
// *
// * @param servletRequest
// * @param servletResponse
// * @return
// */
// public boolean isAjaxReq(ServletRequest servletRequest, ServletResponse servletResponse) {
// boolean isAjaxReq = false;
// HttpServletRequest request = (HttpServletRequest) servletRequest;
// HttpServletResponse response = (HttpServletResponse) servletResponse;
// String requestType = request.getHeader("X-Requested-With");
// if (requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest")) {
// isAjaxReq = true;
// }
// return isAjaxReq;
// }
//
// public String getEnPasswordParam() {
// return enPasswordParam;
// }
//
// public void setEnPasswordParam(String enPasswordParam) {
// this.enPasswordParam = enPasswordParam;
// }
//
// public String getUsernameParam() {
// return usernameParam;
// }
//
// public String getCaptchaIdParam() {
// return captchaIdParam;
// }
//
// public void setCaptchaIdParam(String captchaIdParam) {
// this.captchaIdParam = captchaIdParam;
// }
//
// public String getCaptchaParam() {
// return captchaParam;
// }
//
// public void setCaptchaParam(String captchaParam) {
// this.captchaParam = captchaParam;
// }
//
//}
//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.service.common.utils.redis.RedisClient;
import cn.wisenergy.service.common.utils.redis.RedisConsts;
import cn.wisenergy.common.utils.ByteUtil;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
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实例
@Resource(name = "redisClient")
private RedisClient redisClient;
private static final String REDIS_SESSION_PREFIX = "SHIRO_SESSION";
/**
* shiro-redis的session对象前缀
*/
private String keyPrefix = RedisConsts.ADMIN_SHIRO_SESSION_KEY;
private static final long EXPIRE_TIME = 30 * 60;
@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);
return sessionId;
}
private void saveSession(Session session) throws UnknownSessionException {
private void saveSession(Session session) {
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);
redisTemplate.opsForValue().set(getRedisSessionPrefix(session.getId()), session, EXPIRE_TIME, TimeUnit.SECONDS);
}
String getRedisSessionPrefix(Serializable sessionId) {
return REDIS_SESSION_PREFIX + sessionId;
}
@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()));
protected Session doReadSession(Serializable sessionId) {
Object o = redisTemplate.opsForValue().get(getRedisSessionPrefix(sessionId));
return (Session) o;
}
@Override
public void update(Session session) throws UnknownSessionException {
this.saveSession(session);
}
@Override
public void delete(Session session) {
redisTemplate.delete(getRedisSessionPrefix(session.getId()));
}
@Override
public Collection<Session> getActiveSessions() {
Set<Session> sessions = new HashSet<Session>();
Set<Session> sessions = new HashSet<>();
Set<byte[]> keys = null;
try {
keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
redisTemplate.keys(ByteUtil.objectToBytes(REDIS_SESSION_PREFIX + "*"));
} catch (IOException e) {
e.printStackTrace();
}
......@@ -67,7 +79,7 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO {
for (byte[] key : keys) {
Session s = null;
try {
s = (Session) ByteUtil.bytesToObject(redisClient.get(key));
s = (Session) ByteUtil.bytesToObject((byte[]) redisTemplate.opsForValue().get(key));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
......@@ -79,51 +91,4 @@ public class ShiroRedisSessionDAO extends AbstractSessionDAO {
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 org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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/07/26
*/
public class AuthenticationFilter extends FormAuthenticationFilter {
private static final Logger log = LoggerFactory.getLogger(AuthenticationFilter.class);
//加密密码参数
private static final String DEFAULT_EN_PASSWORD_PARAM = "enPassword";
//默认的登录名称
private static final String DEFAULT_USERNAME_PARAM = "loginName";
//默认验证码ID参数
private static final String DEFAULT_CAPTCHA_ID_PARAM = "captchaId";
//默认验证码参数
private static final String DEFAULT_CAPTCHA_PARAM = "captcha";
private String captchaIdParam = DEFAULT_CAPTCHA_ID_PARAM;
private String captchaParam = DEFAULT_CAPTCHA_PARAM;
private String usernameParam = DEFAULT_USERNAME_PARAM;
private String enPasswordParam = DEFAULT_EN_PASSWORD_PARAM;
/**
* 创建token
*/
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String loginName = getUsername(request);
String password = getPassword(request);
boolean isRemeberMe = isRememberMe(request);
String ip = getHost(request);
return new com.project.shiro.util.AuthenticationToken(loginName, password, isRemeberMe, ip, "", "");
}
/**
* 登录拒绝;增加Ajax异步处理
*
* @param servletRequest 请求对象
* @param servletResponse 响应对象
* @return
* @throws Exception
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
// 判断是否为ajax异步请求
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 判断是否为登录请求
if (this.isLoginRequest(servletRequest, response)) {
if (this.isLoginSubmission(servletRequest, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
boolean b = executeLogin(servletRequest, response);
return b;
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
}
// 异步请求报错
if (isAjaxReq(request, response)) {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
JSONObject json = new JSONObject();
json.put("result", "fail");
json.put("msg", "未登录");
out.println(json);
out.flush();
out.close();
return false;
}
// 如果同步请求继续执行基类方法(当为同步方法的时候,基类会直接跳转登录页面)
return super.onAccessDenied(request, response);
}
}
/**
* 重写登录成功的方法;如果为异步请求,直接返回成功响应
*
* @param token
* @param subject
* @param servletRequest
* @param servletResponse
* @return
* @throws Exception
*/
@Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
// 如果为异步请求,登录成功后,直接返回数据,前台跳转登录后的页面处理
if (isAjaxReq(servletRequest, servletResponse)) {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
JSONObject json = new JSONObject();
json.put("result", "success");
json.put("msg", "登录成功");
out.write(json.toJSONString());
out.flush();
out.close();
return true;
}
return super.onLoginSuccess(token, subject, servletRequest, servletResponse);
}
@Override
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
//Always return true if the request's method is OPTIONSif (request instanceof HttpServletRequest) {
if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
return true;
}
return super.isAccessAllowed(request, response, mappedValue);
}
/**
* 重写登录失败的方法;如果为异步请求,直接返回失败响应
*
* @param token
* @param e
* @param request
* @param response
* @return
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
// 如果为异步登录,直接返回错误结果
if (isAjaxReq(request, response)) {
PrintWriter out = null;
try {
response = (HttpServletResponse) response;
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
out = response.getWriter();
JSONObject json = new JSONObject();
if (e.equals("org.apache.shiro.authc.pam.UnsupportedTokenException")) {
String message = "验证码错误!";
json.put("result", "fail");
json.put("msg", message);
} else if (e.equals("org.apache.shiro.authc.UnknownAccountException")) {
String message = "此账号不存在!";
json.put("result", "fail");
json.put("msg", message);
} else if (e.equals("org.apache.shiro.authc.DisabledAccountException")) {
String message = "此账号已被禁用!";
json.put("result", "fail");
json.put("msg", message);
} else if (e.equals("org.apache.shiro.authc.LockedAccountException")) {
String message = "此账号已被锁定";
json.put("result", "fail");
json.put("msg", message);
} else if (e.equals("org.apache.shiro.authc.IncorrectCredentialsException")) {
String message = "密码错误";
json.put("result", "fail");
json.put("msg", message);
} else if (e.equals("org.apache.shiro.authc.AuthenticationException")) {
String message = "账号认证失败!";
json.put("result", "fail");
json.put("msg", message);
}
out.write(json.toJSONString());
out.flush();
out.close();
return false;
} catch (IOException ex) {
ex.printStackTrace();
log.error("shiro认证失败");
}
}
// 同步请求走基类
return super.onLoginFailure(token, e, request, response);
}
/**
* 获取密码
*
* @param servletRequest
* @return
*/
@Override
protected String getPassword(ServletRequest servletRequest) {
String parameter = servletRequest.getParameter(enPasswordParam);
HttpServletRequest request = (HttpServletRequest) servletRequest;
String enPasswor = request.getParameter(enPasswordParam);
String password = enPasswor;
return password;
}
/**
* 判断是否为Ajax请求
*
* @param servletRequest
* @param servletResponse
* @return
*/
public boolean isAjaxReq(ServletRequest servletRequest, ServletResponse servletResponse) {
boolean isAjaxReq = false;
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestType = request.getHeader("X-Requested-With");
if (requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest")) {
isAjaxReq = true;
}
return isAjaxReq;
}
public String getEnPasswordParam() {
return enPasswordParam;
}
public void setEnPasswordParam(String enPasswordParam) {
this.enPasswordParam = enPasswordParam;
}
public String getUsernameParam() {
return usernameParam;
}
public String getCaptchaIdParam() {
return captchaIdParam;
}
public void setCaptchaIdParam(String captchaIdParam) {
this.captchaIdParam = captchaIdParam;
}
public String getCaptchaParam() {
return captchaParam;
}
public void setCaptchaParam(String captchaParam) {
this.captchaParam = captchaParam;
}
}
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;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="wisenergy-mapper" />
<orderEntry type="module" module-name="wisenergy-model" />
<orderEntry type="module" module-name="wisenergy-common" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.26" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.19" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.19" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.19" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.16.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.0" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
<orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-undertow:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.undertow:undertow-core:2.0.20.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.xnio:xnio-api:3.3.8.Final" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.jboss.xnio:xnio-nio:3.3.8.Final" level="project" />
<orderEntry type="library" name="Maven: io.undertow:undertow-servlet:2.0.20.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec:1.0.2.Final" level="project" />
<orderEntry type="library" name="Maven: io.undertow:undertow-websockets-jsr:2.0.20.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.spec.javax.websocket:jboss-websocket-api_1.1_spec:1.1.3.Final" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish:javax.el:3.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-test:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.12" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.12" level="project" />
<orderEntry type="library" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-test:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.4" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.10" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.2.10" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.16" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.36.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.2.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.54" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.2" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:4.6.7" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-generator:3.4.1" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.velocity:velocity-engine-core:2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.8" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.8" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:22.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.0.18" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.68" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:easyexcel:2.2.6" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: cglib:cglib:3.1" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:4.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.26" level="project" />
<orderEntry type="library" name="Maven: org.ehcache:ehcache:3.6.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.2" level="project" />
</component>
</module>
\ No newline at end of file
......@@ -22,12 +22,17 @@
<artifactId>wisenergy-service</artifactId>
<version>${moduleVersion.wisenergy-service}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
<groupId>cn.wisenergy</groupId>
<artifactId>wisenergy-shiro</artifactId>
<version>${moduleVersion.wisenergy-shiro}</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.apache.shiro</groupId>-->
<!--<artifactId>shiro-spring</artifactId>-->
<!--<version>1.4.0</version>-->
<!--</dependency>-->
</dependencies>
<!-- MAVEN构建 -->
......
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.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
......@@ -13,7 +16,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
*/
@EnableCaching
//排除原有的Multipart配置 spingboot接受不了multipartfile参数
@SpringBootApplication(exclude = {MultipartAutoConfiguration.class})
@SpringBootApplication(exclude = {MultipartAutoConfiguration.class, ShiroAnnotationProcessorAutoConfiguration.class, ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
@MapperScan(basePackages = "cn.wisenergy.mapper")
@EnableSwagger2
@EnableScheduling
......
......@@ -11,12 +11,14 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @description:
......@@ -50,12 +52,15 @@ public class WorkUserController extends BaseController {
@ApiImplicitParam(name = "source", value = "登录来源:PC/WAP", dataType = "string", required = true)
})
@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);
if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password) || StringUtils.isEmpty(source)) {
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);
}
......@@ -77,10 +82,41 @@ public class WorkUserController extends BaseController {
@ApiOperation(value = "组织架构", notes = "组织架构", httpMethod = "GET")
@GetMapping(value = "/getOrganizationStructureDto")
public Result<OrganizationDto> getOrganizationStructureDto(){
public Result<OrganizationDto> getOrganizationStructureDto() {
log.info("WorkUserController[]getOrganizationStructureDto[]");
OrganizationDto organizationDto = workUserService.getOrganizationStructure();
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;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.BaseCustomException;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @description:
* @author: nh
* @create: 2021-04-01 10:44
**/
@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",
"/work/order/getExamineApplets","/work/order/getProject","/work/order/noSubmit","/work/order/query","/work/order/reject",
"/changePassword","getUserInfo","/statistics/getCurrentMonthWorkTimeCollect","/statistics/getMonthlyWorkingHours");
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
ServletContext application = session.getServletContext();
Map<String, String> loginMap = (Map<String, String>) application.getAttribute("loginMap");
// 请求接口不为登录再过滤
String requestURI = ((HttpServletRequest) request).getRequestURI();
for (String s : URI_LIST) {
if (requestURI.startsWith(s)) {
chain.doFilter(request,response);
return;
}
}
if (loginMap == null) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
}
Collection<String> values = loginMap.values();
if (!values.contains(session.getId())) {
throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
}
}
@Override
public void destroy() {
}
}
//package cn.wisenergy.web.config.hanlder;
//
//import cn.wisenergy.common.utils.RedisUtil;
//import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
//import cn.wisenergy.common.utils.exception.BaseCustomException;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import javax.servlet.*;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpSession;
//import java.io.IOException;
//import java.util.Arrays;
//import java.util.List;
//
///**
// * @description:
// * @author: nh
// * @create: 2021-04-01 10:44
// **/
//@Component
//public class LoginFilter implements Filter {
//
// @Autowired
// private RedisUtil redisUtil;
//
// private static final int SESSION_EXPIRE = 30 * 60;
//
// 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 init(FilterConfig filterConfig) throws ServletException {
//
// }
//
// @Override
// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// HttpSession session = httpServletRequest.getSession(false);
//
// // 请求接口不为指定接口再过滤
// String requestURI = ((HttpServletRequest) request).getRequestURI();
// System.out.println("requestURI = " + requestURI);
// for (String s : URI_LIST) {
// if (requestURI.startsWith(s)) {
// chain.doFilter(request,response);
// return;
// }
// }
//
// // 请求没有携带session
// if (session == null) {
// System.out.println("session Is Null");
// throw new BaseCustomException(BASE_RESP_CODE_ENUM.PLEASE_RE_LOGIN);
// }
// 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