Commit 234a8e60 by giaogiao

优化token校验

parent e7471d7f
...@@ -21,6 +21,7 @@ import io.geekidea.springbootplus.framework.core.pagination.PageInfo; ...@@ -21,6 +21,7 @@ import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging; import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.shiro.cache.AppLoginRedisService; import io.geekidea.springbootplus.framework.shiro.cache.AppLoginRedisService;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken; import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.jwt.realm.LoginClientTypeEnum;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.util.SaltUtil; import io.geekidea.springbootplus.framework.shiro.util.SaltUtil;
import io.geekidea.springbootplus.framework.shiro.vo.LoginUserVo; import io.geekidea.springbootplus.framework.shiro.vo.LoginUserVo;
...@@ -115,7 +116,7 @@ public class AppUserServiceImpl extends BaseServiceImpl<AppUserMapper, AppUser> ...@@ -115,7 +116,7 @@ public class AppUserServiceImpl extends BaseServiceImpl<AppUserMapper, AppUser>
log.debug("token:{}", token); log.debug("token:{}", token);
// 创建AuthenticationToken // 创建AuthenticationToken
JwtToken jwtToken = JwtToken.build(token, appUser.getId().toString(), appUser.getId(), newSalt, expireSecond, "app"); JwtToken jwtToken = JwtToken.build(token, appUser.getId().toString(), appUser.getId(), newSalt, expireSecond, LoginClientTypeEnum.APP.getType());
boolean enableShiro = springBootPlusProperties.getShiro().isEnable(); boolean enableShiro = springBootPlusProperties.getShiro().isEnable();
if (enableShiro) { if (enableShiro) {
......
...@@ -26,6 +26,7 @@ import io.geekidea.springbootplus.framework.core.pagination.PageInfo; ...@@ -26,6 +26,7 @@ import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging; import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.shiro.cache.MerchantLoginRedisService; import io.geekidea.springbootplus.framework.shiro.cache.MerchantLoginRedisService;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken; import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.jwt.realm.LoginClientTypeEnum;
import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.util.SaltUtil; import io.geekidea.springbootplus.framework.shiro.util.SaltUtil;
...@@ -157,7 +158,7 @@ public class MerchantUserServiceImpl extends BaseServiceImpl<MerchantUserMapper, ...@@ -157,7 +158,7 @@ public class MerchantUserServiceImpl extends BaseServiceImpl<MerchantUserMapper,
log.debug("token:{}", token); log.debug("token:{}", token);
// 创建AuthenticationToken // 创建AuthenticationToken
JwtToken jwtToken = JwtToken.build(token, username,merchantUser.getId(), newSalt, expireSecond, "mer"); JwtToken jwtToken = JwtToken.build(token, username,merchantUser.getId(), newSalt, expireSecond, LoginClientTypeEnum.MERCHANT.getType());
boolean enableShiro = springBootPlusProperties.getShiro().isEnable(); boolean enableShiro = springBootPlusProperties.getShiro().isEnable();
if (enableShiro) { if (enableShiro) {
......
...@@ -52,6 +52,12 @@ public class StrokeServiceImpl extends BaseServiceImpl<StrokeMapper, Stroke> imp ...@@ -52,6 +52,12 @@ public class StrokeServiceImpl extends BaseServiceImpl<StrokeMapper, Stroke> imp
public boolean deleteStroke(Long id) throws Exception { public boolean deleteStroke(Long id) throws Exception {
JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal(); JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
Stroke byId = super.getById(id); Stroke byId = super.getById(id);
// 如果已删除 直接返回true
if (byId == null) {
return true;
}
// 判断该记录是否属于此用户 // 判断该记录是否属于此用户
if (!byId.getUserId().equals(jwtToken.getUserId())) { if (!byId.getUserId().equals(jwtToken.getUserId())) {
return false; return false;
......
...@@ -22,6 +22,7 @@ import io.geekidea.springbootplus.framework.common.api.ApiCode; ...@@ -22,6 +22,7 @@ import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult; import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService; import io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken; import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.jwt.realm.LoginClientTypeEnum;
import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.util.SaltUtil; import io.geekidea.springbootplus.framework.shiro.util.SaltUtil;
...@@ -161,7 +162,7 @@ public class SysLoginServiceImpl implements SysLoginService { ...@@ -161,7 +162,7 @@ public class SysLoginServiceImpl implements SysLoginService {
log.debug("token:{}", token); log.debug("token:{}", token);
// 创建AuthenticationToken // 创建AuthenticationToken
JwtToken jwtToken = JwtToken.build(token, username,sysUser.getId(), newSalt, expireSecond, "sys"); JwtToken jwtToken = JwtToken.build(token, username,sysUser.getId(), newSalt, expireSecond, LoginClientTypeEnum.SYSTEM.getType());
boolean enableShiro = springBootPlusProperties.getShiro().isEnable(); boolean enableShiro = springBootPlusProperties.getShiro().isEnable();
if (enableShiro) { if (enableShiro) {
......
...@@ -44,7 +44,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -44,7 +44,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/sysLoginLog") @RequestMapping("/sys/sysLoginLog")
@Module("log") @Module("log")
@Api(value = "系统登录日志API", tags = {"系统登录日志"}) @Api(value = "系统登录日志API", tags = {"系统登录日志"})
public class SysLoginLogController extends BaseController { public class SysLoginLogController extends BaseController {
......
...@@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/sysOperationLog") @RequestMapping("/sys/sysOperationLog")
@Api(value = "系统操作日志API", tags = {"系统操作日志"}) @Api(value = "系统操作日志API", tags = {"系统操作日志"})
public class SysOperationLogController extends BaseController { public class SysOperationLogController extends BaseController {
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package io.geekidea.springbootplus.framework.shiro.jwt; package io.geekidea.springbootplus.framework.shiro.jwt;
import io.geekidea.springbootplus.config.constant.CommonRedisKey;
import io.geekidea.springbootplus.config.properties.JwtProperties; import io.geekidea.springbootplus.config.properties.JwtProperties;
import io.geekidea.springbootplus.framework.common.api.ApiCode; import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult; import io.geekidea.springbootplus.framework.common.api.ApiResult;
...@@ -27,7 +26,6 @@ import io.geekidea.springbootplus.framework.shiro.util.JwtUtil; ...@@ -27,7 +26,6 @@ import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo; import io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo;
import io.geekidea.springbootplus.framework.util.HttpServletResponseUtil; import io.geekidea.springbootplus.framework.util.HttpServletResponseUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
...@@ -54,13 +52,12 @@ public class JwtFilter extends AuthenticatingFilter { ...@@ -54,13 +52,12 @@ public class JwtFilter extends AuthenticatingFilter {
private final ShiroLoginService shiroLoginService; private final ShiroLoginService shiroLoginService;
private final SysLoginRedisService sysLoginRedisService; private final SysLoginRedisService sysLoginRedisService;
private final JwtProperties jwtProperties; private final JwtProperties jwtProperties;
private RedisTemplate redisTemplate;
public JwtFilter(ShiroLoginService shiroLoginService, SysLoginRedisService loginRedisService, JwtProperties jwtProperties, RedisTemplate redisTemplate) { public JwtFilter(ShiroLoginService shiroLoginService, SysLoginRedisService loginRedisService, JwtProperties jwtProperties, RedisTemplate redisTemplate) {
this.shiroLoginService = shiroLoginService; this.shiroLoginService = shiroLoginService;
this.sysLoginRedisService = loginRedisService; this.sysLoginRedisService = loginRedisService;
this.jwtProperties = jwtProperties; this.jwtProperties = jwtProperties;
this.redisTemplate = redisTemplate;
} }
/** /**
...@@ -83,36 +80,14 @@ public class JwtFilter extends AuthenticatingFilter { ...@@ -83,36 +80,14 @@ public class JwtFilter extends AuthenticatingFilter {
throw new AuthenticationException("JWT Token已过期,token:" + token); throw new AuthenticationException("JWT Token已过期,token:" + token);
} }
Object jwtTokenRedisVo = null; JwtTokenRedisVo jwt = shiroLoginService.getTokenInfoForRedis(token);
// 如果开启redis二次校验,或者设置为单个用户token登录,则先在redis中判断token是否存在
if (jwtProperties.isRedisCheck() || jwtProperties.isSingleLogin()) {
String tokenMd5 = DigestUtils.md5Hex(token);
jwtTokenRedisVo = redisTemplate.opsForValue().get(String.format(CommonRedisKey.LOGIN_TOKEN, tokenMd5));
// boolean redisExpired = sysLoginRedisService.exists(token);
if (jwtTokenRedisVo == null) {
throw new AuthenticationException("Redis Token不存在,token:" + token);
}
}
JwtTokenRedisVo jwt = (JwtTokenRedisVo) jwtTokenRedisVo;
if (jwt == null) {
throw new AuthenticationException("Redis Token不存在,token:" + token);
}
String username = JwtUtil.getUsername(token); String username = JwtUtil.getUsername(token);
String salt; return JwtToken.build(token, username, jwt.getUserId(), shiroLoginService.getSalt(token), jwtProperties.getExpireSecond(), jwt.getType());
if (jwtProperties.isSaltCheck()) {
salt = sysLoginRedisService.getSalt(username);
} else {
salt = jwtProperties.getSecret();
}
return JwtToken.build(token, username, jwt.getUserId(), salt, jwtProperties.getExpireSecond(), jwt.getType());
} }
/** /**
* 访问失败处理 * 访问失败处理
* *
......
...@@ -63,7 +63,7 @@ public class JwtRealmAppUser extends AuthorizingRealm { ...@@ -63,7 +63,7 @@ public class JwtRealmAppUser extends AuthorizingRealm {
// 设置角色/权限信息 // 设置角色/权限信息
JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal(); JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal();
if (!jwtToken.getType().equals("app")) { if (!jwtToken.getType().equals(LoginClientTypeEnum.APP.getType())) {
return null; return null;
} }
/* /*
......
...@@ -66,7 +66,7 @@ public class JwtRealmMerchant extends AuthorizingRealm { ...@@ -66,7 +66,7 @@ public class JwtRealmMerchant extends AuthorizingRealm {
// 设置角色/权限信息 // 设置角色/权限信息
JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal(); JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal();
if (!jwtToken.getType().equals("mer")) { if (!jwtToken.getType().equals(LoginClientTypeEnum.MERCHANT.getType())) {
return null; return null;
} }
......
...@@ -63,7 +63,7 @@ public class JwtRealmSystem extends AuthorizingRealm { ...@@ -63,7 +63,7 @@ public class JwtRealmSystem extends AuthorizingRealm {
// 设置角色/权限信息 // 设置角色/权限信息
JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal(); JwtToken jwtToken = (JwtToken) principalCollection.getPrimaryPrincipal();
if (!jwtToken.getType().equals("sys")) { if (!jwtToken.getType().equals(LoginClientTypeEnum.SYSTEM.getType())) {
return null; return null;
} }
// 获取username // 获取username
......
package io.geekidea.springbootplus.framework.shiro.jwt.realm;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 客户端类型
*/
@Getter
@AllArgsConstructor
public enum LoginClientTypeEnum {
// app
APP("app"),
// 平台
SYSTEM("sys"),
// 商户
MERCHANT("mer");
private final String type;
}
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package io.geekidea.springbootplus.framework.shiro.service; package io.geekidea.springbootplus.framework.shiro.service;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken; import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -39,4 +40,20 @@ public interface ShiroLoginService { ...@@ -39,4 +40,20 @@ public interface ShiroLoginService {
*/ */
void refreshToken(JwtToken jwtToken, HttpServletResponse httpServletResponse) throws Exception; void refreshToken(JwtToken jwtToken, HttpServletResponse httpServletResponse) throws Exception;
/**
* 从redis获取token信息
*
* @param token
* @return
*/
JwtTokenRedisVo getTokenInfoForRedis(String token);
/**
* 获取盐
* @param token
* @return
*/
String getSalt(String token);
} }
...@@ -17,14 +17,16 @@ ...@@ -17,14 +17,16 @@
package io.geekidea.springbootplus.framework.shiro.service.impl; package io.geekidea.springbootplus.framework.shiro.service.impl;
import io.geekidea.springbootplus.config.constant.CommonConstant; import io.geekidea.springbootplus.config.constant.CommonConstant;
import io.geekidea.springbootplus.config.constant.CommonRedisKey;
import io.geekidea.springbootplus.config.properties.JwtProperties; import io.geekidea.springbootplus.config.properties.JwtProperties;
import io.geekidea.springbootplus.config.properties.SpringBootPlusProperties;
import io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService; import io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken; import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService; import io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService;
import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil;
import io.geekidea.springbootplus.framework.shiro.util.JwtUtil; import io.geekidea.springbootplus.framework.shiro.util.JwtUtil;
import io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
...@@ -47,7 +49,6 @@ import java.util.Date; ...@@ -47,7 +49,6 @@ import java.util.Date;
@Service @Service
public class ShiroLoginServiceImpl implements ShiroLoginService { public class ShiroLoginServiceImpl implements ShiroLoginService {
@Lazy @Lazy
@Autowired @Autowired
private SysLoginRedisService sysLoginRedisService; private SysLoginRedisService sysLoginRedisService;
...@@ -58,10 +59,6 @@ public class ShiroLoginServiceImpl implements ShiroLoginService { ...@@ -58,10 +59,6 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
@Lazy @Lazy
@Autowired @Autowired
private SpringBootPlusProperties springBootPlusProperties;
@Lazy
@Autowired
private RedisTemplate redisTemplate; private RedisTemplate redisTemplate;
...@@ -103,7 +100,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService { ...@@ -103,7 +100,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
// 生成新token字符串 // 生成新token字符串
String newToken = JwtUtil.generateToken(username, salt, Duration.ofSeconds(expireSecond)); String newToken = JwtUtil.generateToken(username, salt, Duration.ofSeconds(expireSecond));
// 生成新JwtToken对象 // 生成新JwtToken对象
JwtToken newJwtToken = JwtToken.build(newToken, username,jwtToken.getUserId(), salt, expireSecond, jwtToken.getType()); JwtToken newJwtToken = JwtToken.build(newToken, username, jwtToken.getUserId(), salt, expireSecond, jwtToken.getType());
// 更新redis缓存 // 更新redis缓存
sysLoginRedisService.refreshLoginInfo(token, username, newJwtToken); sysLoginRedisService.refreshLoginInfo(token, username, newJwtToken);
log.debug("刷新token成功,原token:{},新token:{}", token, newToken); log.debug("刷新token成功,原token:{},新token:{}", token, newToken);
...@@ -112,4 +109,30 @@ public class ShiroLoginServiceImpl implements ShiroLoginService { ...@@ -112,4 +109,30 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
httpServletResponse.setStatus(CommonConstant.JWT_REFRESH_TOKEN_CODE); httpServletResponse.setStatus(CommonConstant.JWT_REFRESH_TOKEN_CODE);
httpServletResponse.setHeader(JwtTokenUtil.getTokenName(), newToken); httpServletResponse.setHeader(JwtTokenUtil.getTokenName(), newToken);
} }
@Override
public JwtTokenRedisVo getTokenInfoForRedis(String token) {
Object jwtTokenRedisVo = null;
// 如果开启redis二次校验,或者设置为单个用户token登录,则先在redis中判断token是否存在
if (jwtProperties.isRedisCheck() || jwtProperties.isSingleLogin()) {
String tokenMd5 = DigestUtils.md5Hex(token);
jwtTokenRedisVo = redisTemplate.opsForValue().get(String.format(CommonRedisKey.LOGIN_TOKEN, tokenMd5));
// boolean redisExpired = sysLoginRedisService.exists(token); // 判断是否存在
if (jwtTokenRedisVo == null) {
throw new AuthenticationException("Redis Token不存在,token:" + token);
}
}
return (JwtTokenRedisVo) jwtTokenRedisVo;
}
@Override
public String getSalt(String token) {
String username = JwtUtil.getUsername(token);
if (jwtProperties.isSaltCheck()) {
return sysLoginRedisService.getSalt(username);
} else {
return jwtProperties.getSecret();
}
}
} }
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