From bd3a7bf55f8d128cf0ec7b132316255c08e05734 Mon Sep 17 00:00:00 2001 From: wubo25320 <1790043847@qq.com> Date: Mon, 20 Apr 2020 17:20:51 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD](20200420?= =?UTF-8?q?):=20=E9=89=B4=E6=9D=83=E7=B3=BB=E7=BB=9F-=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 解决 1. Token刷新并发处理问题 https://github.com/dolyw/ShiroJwt/issues/29 2. 授权部分完成 3. 添加授权异常拦截器 ControllerAspect 4. 测试授权.LocationController --- .../everyknow/common/bean/Constant.java | 5 ++ .../web/advice/ControllerAspect.java | 28 ++++++- .../everyknow/web/enums/EnumResponseType.java | 17 +++-- .../everyknow/seims/config/EknowConfig.java | 11 +++ .../seims/config/shiro/JWTFilter.java | 74 ++++++++++++------- .../seims/config/shiro/ShiroConfig.java | 2 +- .../seims/config/shiro/UserRealm.java | 53 +++++++++++-- .../everyknow/seims/dao/SysPermissionDao.java | 10 --- .../everyknow/seims/dao/SysRoleDao.java | 10 --- .../seims/dao/SysRolePermissionDao.java | 10 --- .../seims/dao/impl/SysPermissionDaoImpl.java | 57 ++++++++++++++ .../seims/dao/impl/SysRoleDaoImpl.java | 53 +++++++++++++ .../dao/impl/SysRolePermissionDaoImpl.java | 61 +++++++++++++++ .../service/SysRolePermissionService.java | 54 ++++++++++++++ .../seims/service/SysUserRoleService.java | 11 ++- .../impl/SysRolePermissionServiceImpl.java | 53 +++++++++++++ .../service/impl/SysUserRoleServiceImpl.java | 27 +++++-- .../src/main/resources/config.properties | 2 + .../facade/controller/LocationController.java | 2 + .../facade/controller/SysUserController.java | 2 +- 20 files changed, 459 insertions(+), 83 deletions(-) create mode 100644 everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysPermissionDaoImpl.java create mode 100644 everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRoleDaoImpl.java create mode 100644 everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRolePermissionDaoImpl.java create mode 100644 everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysRolePermissionService.java create mode 100644 everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysRolePermissionServiceImpl.java diff --git a/everyknow-common/src/main/java/com/herion/everyknow/common/bean/Constant.java b/everyknow-common/src/main/java/com/herion/everyknow/common/bean/Constant.java index 2a3c9bc..db7ea08 100644 --- a/everyknow-common/src/main/java/com/herion/everyknow/common/bean/Constant.java +++ b/everyknow-common/src/main/java/com/herion/everyknow/common/bean/Constant.java @@ -44,6 +44,11 @@ private Constant() {} */ public static final String PREFIX_SHIRO_REFRESH_TOKEN = "shiro:refresh_token:"; + /** + * redis-key-前缀-shiro:refresh_token:transition: + */ + public static final String PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION = "shiro:refresh_token_transition:"; + /** * JWT-account: */ diff --git a/everyknow-common/src/main/java/com/herion/everyknow/web/advice/ControllerAspect.java b/everyknow-common/src/main/java/com/herion/everyknow/web/advice/ControllerAspect.java index ef2db98..27ca396 100644 --- a/everyknow-common/src/main/java/com/herion/everyknow/web/advice/ControllerAspect.java +++ b/everyknow-common/src/main/java/com/herion/everyknow/web/advice/ControllerAspect.java @@ -12,11 +12,16 @@ import com.herion.everyknow.web.response.EKnowResponse; import com.herion.everyknow.web.utils.ResultUtils; import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.AuthorizationException; +import org.apache.shiro.authz.UnauthenticatedException; +import org.apache.shiro.authz.UnauthorizedException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RestControllerAdvice; import java.lang.annotation.Annotation; import java.util.Collection; @@ -29,7 +34,7 @@ @Order(1) @Aspect @Slf4j -//@RestControllerAdvice +@RestControllerAdvice public class ControllerAspect { // /** @@ -54,6 +59,23 @@ public class ControllerAspect { // return ResultUtils.getFailureResponse("500","未知异常", null); // } + /** + * aroundController 中的 异常处理只能处理 Controller 层中的异常.进入 Controller 层之前的异常无法捕获 + * 这个方法就是为了 捕获 Shiro 的 AuthorizationException(授权类异常) + * // TODO 后续需要完善, UnauthenticatedException UnauthenticatedException UnauthenticatedException + * @param e + * @return + * @throws Throwable + */ + @ExceptionHandler(AuthorizationException.class) + public EKnowResponse AuthorizationExceptionHandler(Exception e) { + log.info(e.getMessage()); + if (e instanceof UnauthenticatedException) { + UnauthorizedException unauthorizedException = (UnauthorizedException) e; + } + return ResultUtils.getFailureResponse(EnumResponseType.NO_PERMISSION.getHttp(),EnumResponseType.NO_PERMISSION.getMsg(), EnumResponseType.NO_PERMISSION, null); + } + @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)") public Object aroundController(ProceedingJoinPoint jp) throws Throwable { @@ -147,7 +169,7 @@ private Object getErr(Exception e, Object[] args) { boolean pageFlag = this.isPage(args); if (!pageFlag) { // result = ResultUtils.getFailureResponse("500", e.getClass().getName() + ": " + e.getMessage(), null); - result = ResultUtils.getFailureResponse("500", e.getMessage(), null); + result = ResultUtils.getFailureResponse(EnumResponseType.SYS_ERR.getHttp(), e.getMessage(), null); } else { EKnowPageRequest eKnowPageRequest = null; // 如果是分页请求入参只有一个 @@ -157,7 +179,7 @@ private Object getErr(Exception e, Object[] args) { if (args[0] instanceof CommonHttpPageRequest) { eKnowPageRequest = ((CommonHttpPageRequest) args[0]).geteKnowRequest(); } - result = ResultUtils.getPageResponse("500", "未知异常", EnumResponseType.SYS_ERR, null, eKnowPageRequest); + result = ResultUtils.getPageResponse(EnumResponseType.SYS_ERR.getHttp(), "未知异常", EnumResponseType.SYS_ERR, null, eKnowPageRequest); } return result; } diff --git a/everyknow-common/src/main/java/com/herion/everyknow/web/enums/EnumResponseType.java b/everyknow-common/src/main/java/com/herion/everyknow/web/enums/EnumResponseType.java index 85db162..e790915 100644 --- a/everyknow-common/src/main/java/com/herion/everyknow/web/enums/EnumResponseType.java +++ b/everyknow-common/src/main/java/com/herion/everyknow/web/enums/EnumResponseType.java @@ -6,15 +6,18 @@ * @create 2020-03-18 23:20 */ public enum EnumResponseType { - SUCCESS("EKNOW_SUCCESS","执行成功"), - SYS_ERR("EKNOW_SYS_ERR","系统错误"), - NO_LOGIN("EKNOW_NO_LOGIN", "登录已过期,请重新登录"), - ERR_TOKEN("EKNOW_ERR_TOKEN", "Token或秘钥不正确"); + SUCCESS("200","EKNOW_SUCCESS","执行成功"), + SYS_ERR("500","EKNOW_SYS_ERR","系统错误"), + NO_LOGIN("401","EKNOW_NO_LOGIN", "登录已过期,请重新登录"), + ERR_TOKEN("401","EKNOW_ERR_TOKEN", "Token或秘钥不正确"), + NO_PERMISSION("403","EKNOW_NO_PERMISSION", "没有权限"); + String http; String code; String msg; - EnumResponseType(String code, String msg) { + EnumResponseType(String http, String code, String msg) { + this.http = http; this.code = code; this.msg = msg; } @@ -33,6 +36,10 @@ public static EnumResponseType find(String code) { return null; } + public String getHttp() { + return http; + } + public String getCode() { return code; } diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/EknowConfig.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/EknowConfig.java index d323f3d..5333da5 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/EknowConfig.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/EknowConfig.java @@ -30,6 +30,8 @@ public class EknowConfig { private static String encryptJWTKey; + private static long refreshTokenTransitionExpireTime; + public static Boolean getMustLogin() { return mustLogin; } @@ -65,4 +67,13 @@ public static String getEncryptJWTKey() { public void setEncryptJWTKey(String encryptJWTKey) { EknowConfig.encryptJWTKey = encryptJWTKey; } + + public static long getRefreshTokenTransitionExpireTime() { + return refreshTokenTransitionExpireTime; + } + + @Value("${eknow.refreshTokenTransitionExpireTime}") + public void setRefreshTokenTransitionExpireTime(long refreshTokenTransitionExpireTime) { + EknowConfig.refreshTokenTransitionExpireTime = refreshTokenTransitionExpireTime; + } } diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/JWTFilter.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/JWTFilter.java index b508805..641bb4f 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/JWTFilter.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/JWTFilter.java @@ -14,6 +14,7 @@ import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; import org.apache.shiro.web.util.WebUtils; import org.springframework.stereotype.Component; +import redis.clients.jedis.Jedis; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -69,22 +70,22 @@ protected boolean isAccessAllowed(ServletRequest request, ServletResponse respon String msg = e.getMessage(); // 获取应用异常 (该 Cause是导致抛出 throwable(异常)的 throwable(异常)) Throwable throwable = e.getCause(); - EKnowResponse failureResponse = ResultUtils.getFailureResponse("401", msg, EnumResponseType.ERR_TOKEN, null);; + EKnowResponse failureResponse = ResultUtils.getFailureResponse(EnumResponseType.ERR_TOKEN.getHttp(), msg, EnumResponseType.ERR_TOKEN, null);; if (throwable instanceof SignatureVerificationException) { // 该异常为 JWT 异常, AccessToken 认证失败(Token 或 秘钥不对) - failureResponse = ResultUtils.getFailureResponse("401", "Token 或 秘钥不正确", EnumResponseType.ERR_TOKEN, null); + failureResponse = ResultUtils.getFailureResponse(EnumResponseType.ERR_TOKEN.getHttp(), "Token 或 秘钥不正确", EnumResponseType.ERR_TOKEN, null); } else if (throwable instanceof TokenExpiredException) { // 该异常为 JWT 的 AccessToken 已过期, 判断RefreshToken 未过期就进行 AccessToken 刷新 if (this.refreshToken(request, response)) { return true; } else { - failureResponse = ResultUtils.getFailureResponse("401", "登录已过期,请重新登录", EnumResponseType.ERR_TOKEN, null); + failureResponse = ResultUtils.getFailureResponse(EnumResponseType.ERR_TOKEN.getHttp(), "登录已过期,请重新登录", EnumResponseType.ERR_TOKEN, null); } } else { // 应用异常 if (throwable != null) { // 获取应用异常 - failureResponse = ResultUtils.getFailureResponse("401", throwable.getMessage(), EnumResponseType.ERR_TOKEN, null); + failureResponse = ResultUtils.getFailureResponse(EnumResponseType.ERR_TOKEN.getHttp(), throwable.getMessage(), EnumResponseType.ERR_TOKEN, null); } } // Token认证失败直接返回 Response信息 @@ -102,7 +103,7 @@ protected boolean isAccessAllowed(ServletRequest request, ServletResponse respon // mustLoginFlag = true 开启任何请求都必须登录才可访问 final Boolean mustLoginFlag = EknowConfig.getMustLogin(); if (mustLoginFlag) { - EKnowResponse failureResponse = ResultUtils.getFailureResponse("401", "登录已过期,请重新登录", EnumResponseType.NO_LOGIN, null); + EKnowResponse failureResponse = ResultUtils.getFailureResponse(EnumResponseType.ERR_TOKEN.getHttp(), "登录已过期,请重新登录", EnumResponseType.NO_LOGIN, null); this.response401(response, failureResponse); return false; } @@ -185,30 +186,49 @@ private boolean refreshToken(ServletRequest request, ServletResponse response) { String token = this.getAuthzHeader(request); // 获取 Token的账号信息 String username = JWTUtil.getUsername(token); - // 判断Redis 中 RefreshToken是否存在 - if (JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username)) { - // Redis中 RefreshToken还存在, 获取RefreshToken的时间戳 - String currentTimeMillisRedis = JedisUtil.getObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username).toString(); - // 获取当前AccessToken中的时间戳, 与 RefreshToken的时间戳作对比, 如果当前时间戳一致, 进行 AccessToken刷新 - if (JWTUtil.getCurrentTimeMillis(token).equals(currentTimeMillisRedis)) { - // 获取当前最新时间戳 - String currentTimeMillis = String.valueOf(System.currentTimeMillis()); - // 设置RefreshToken中的时间戳为当前最新时间戳, 且刷新过期时间重新设置为 30 分钟过期(配置文件可配置 RefreshTokenExpireTime属性) - JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username, currentTimeMillis, (int)EknowConfig.getRefreshTokenExpireTime()); - System.out.println(EknowConfig.getRefreshTokenExpireTime()); - // 刷新 AccessToken.设置时间戳为当前最新时间戳 - token = JWTUtil.sign(username, currentTimeMillis); - // 将刷新的AccessToken再次进行Shiro的登录 - JWTToken jwtToken = new JWTToken(token); - // 提交给 UserRealm 进行认证, 如果错误会抛出异常被捕获 - this.getSubject(request, response).login(jwtToken); - // 最后将刷新的AccessToken存放在Response的 Header中的 Authorization字段返回 - HttpServletResponse httpServletResponse = WebUtils.toHttp(response); - httpServletResponse.setHeader("Authorization", token); - httpServletResponse.setHeader("Access-Control-Expose-Headers", "Authorization"); - return true; + // 刷新Token 时需要进行同步防止出现问题. synchronized 为单机版, 需要使用集群时请使用 Redission 分布式锁 + synchronized (this) { + // 判断Redis 中 RefreshToken是否存在 + if (JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username)) { + // Redis中 RefreshToken还存在, 获取RefreshToken的时间戳 + String currentTimeMillisRedis = JedisUtil.getObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username).toString(); + // 获取当前AccessToken中的时间戳, 与 RefreshToken的时间戳作对比, 如果当前时间戳一致, 进行 AccessToken刷新 + if (JWTUtil.getCurrentTimeMillis(token).equals(currentTimeMillisRedis)) { + // 获取当前最新时间戳 + String currentTimeMillis = String.valueOf(System.currentTimeMillis()); + // 设置RefreshToken中的时间戳为当前最新时间戳, 且刷新过期时间重新设置为 30 分钟过期(配置文件可配置 RefreshTokenExpireTime属性) + JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username, currentTimeMillis, (int)EknowConfig.getRefreshTokenExpireTime()); + System.out.println(EknowConfig.getRefreshTokenExpireTime()); + // 刷新 AccessToken.设置时间戳为当前最新时间戳 + token = JWTUtil.sign(username, currentTimeMillis); + // 将刷新的AccessToken再次进行Shiro的登录 + JWTToken jwtToken = new JWTToken(token); + // 提交给 UserRealm 进行认证, 如果错误会抛出异常被捕获 + this.getSubject(request, response).login(jwtToken); + + // 刷新AccessToken成功, Redis设置RefreshToken过渡时间, value为旧token,这个是为了解决Token刷新并发的问题 + JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION + username, this.getAuthzHeader(request), (int) EknowConfig.getRefreshTokenTransitionExpireTime()); + + // 最后将刷新的AccessToken存放在Response的 Header中的 Authorization字段返回 + HttpServletResponse httpServletResponse = WebUtils.toHttp(response); + httpServletResponse.setHeader("Authorization", token); + httpServletResponse.setHeader("Access-Control-Expose-Headers", "Authorization"); + return true; + } else { + // 说明当前Token已经被刷新,判断当前账号是否存在RefreshToken 过渡时间, 是就放行 + if (JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION + username)) { + String oldToken = JedisUtil.getObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION + username).toString(); + // 判断Token是否一致 + if (this.getAuthzHeader(request).equals(oldToken)) { + // 提交给UserRealm进行认证, 如果错误他回抛出异常并被捕获, 如果没有抛出异常则代表登入成功, 返回 true + this.getSubject(request, response).login(new JWTToken(oldToken)); + return true; + } + } + } } } + return false; } } diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/ShiroConfig.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/ShiroConfig.java index a72e0a7..140f115 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/ShiroConfig.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/ShiroConfig.java @@ -89,7 +89,7 @@ public ShiroFilterFactoryBean shiroFilterFactoryBean(@Autowired SecurityManager * http://shiro.apache.org/web.html#urls- */ LinkedHashMap filterRuleMap = new LinkedHashMap<>(); -// filterRuleMap.put("/user/login", "anon"); + filterRuleMap.put("/user/login", "anon"); filterRuleMap.put("/**", "jwt"); factoryBean.setFilterChainDefinitionMap(filterRuleMap); return factoryBean; diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/UserRealm.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/UserRealm.java index 4b84211..0321c85 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/UserRealm.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/config/shiro/UserRealm.java @@ -2,8 +2,8 @@ import com.herion.everyknow.common.bean.Constant; import com.herion.everyknow.seims.dao.SysUserDao; -import com.herion.everyknow.seims.dao.entity.SysUser; -import com.herion.everyknow.seims.service.SysUserService; +import com.herion.everyknow.seims.dao.entity.*; +import com.herion.everyknow.seims.service.*; import com.herion.everyknow.seims.utils.JWTUtil; import com.herion.everyknow.seims.utils.JedisUtil; import lombok.extern.slf4j.Slf4j; @@ -14,8 +14,12 @@ import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + /** - * @Description 自定义 Realm(用来认证授权) + * @Description 自定义 Realm(用来认证授权) 在 ShiroConfig 中 注入 * @auther wubo25320 * @create 2020-04-15 16:44 */ @@ -25,6 +29,18 @@ public class UserRealm extends AuthorizingRealm { @Autowired private SysUserService sysUserService; + @Autowired + private SysUserRoleService sysUserRoleService; + + @Autowired + private SysRoleService sysRoleService; + + @Autowired + private SysRolePermissionService sysRolePermissionService; + + @Autowired + private SysPermissionService sysPermissionService; + // 大坑!!! 必须重写此方法, 不然shiro 会报错 @Override public boolean supports(AuthenticationToken token) { @@ -40,9 +56,24 @@ public boolean supports(AuthenticationToken token) { protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); String username = JWTUtil.getUsername(principalCollection.toString()); - - System.out.println("授权逻辑测试"); - return null; + // 查询当前用户信息 + SysUser user = sysUserService.getUser(username); + // 查询当前用户角色信息 + SysUserRole sysUserRole = sysUserRoleService.queryByUserId(user.getId()); + if (sysUserRole != null) { + // 添加角色 + SysRole sysRole = sysRoleService.queryById(sysUserRole.getRoleId()); + simpleAuthorizationInfo.addRole(sysRole.getRoleName()); + // 查询当前角色权限信息 + List sysRolePermissionList = sysRolePermissionService.queryByRoleId(sysUserRole.getRoleId()); + List sysPermisssionList = new ArrayList<>(); + for (SysRolePermission sysRolePermission : sysRolePermissionList) { + sysPermisssionList.add(sysPermissionService.queryById(sysRolePermission.getPermissionId())); + } + // 添加权限 + simpleAuthorizationInfo.addStringPermissions(sysPermisssionList.stream().map(permission -> permission.getPermissionCode()).collect(Collectors.toList())); + } + return simpleAuthorizationInfo; } /** @@ -93,6 +124,16 @@ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authent throw new UnknownAccountException("该帐号不存在(The account does not exist.)"); } + // 判断当前账号是否在 RefreshToken过渡时间, 是就放行 + if (JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION + username)) { + // 获取RefreshToken过渡时间Key保存的旧的 token + String oldToken = JedisUtil.getObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN_TRANSITION + username).toString(); + // 判断旧Token是否一致 + if (token.equals(oldToken)) { + return new SimpleAuthenticationInfo(token, token, getName()); + } + } + // 开始认证,要 AccessToken 认证通过, 且Redis中存在RefreshToken, 且两个Token时间戳一致 // AccessToken 认证通过.主要就是判断有没有过期(AccessTokenExpireTime) if (JWTUtil.verify(token) && JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN + username)) { diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysPermissionDao.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysPermissionDao.java index 5a8aef8..ddc2737 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysPermissionDao.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysPermissionDao.java @@ -20,16 +20,6 @@ public interface SysPermissionDao { */ SysPermission queryById(Integer id); - /** - * 查询指定行数据 - * - * @param offset 查询起始位置 - * @param limit 查询条数 - * @return 对象列表 - */ - List queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit); - - /** * 通过实体作为筛选条件查询 * diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRoleDao.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRoleDao.java index a20e9ee..e8eefc0 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRoleDao.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRoleDao.java @@ -20,16 +20,6 @@ public interface SysRoleDao { */ SysRole queryById(Integer id); - /** - * 查询指定行数据 - * - * @param offset 查询起始位置 - * @param limit 查询条数 - * @return 对象列表 - */ - List queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit); - - /** * 通过实体作为筛选条件查询 * diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRolePermissionDao.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRolePermissionDao.java index 0dd0336..69fd9dc 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRolePermissionDao.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/SysRolePermissionDao.java @@ -20,16 +20,6 @@ public interface SysRolePermissionDao { */ SysRolePermission queryById(Integer id); - /** - * 查询指定行数据 - * - * @param offset 查询起始位置 - * @param limit 查询条数 - * @return 对象列表 - */ - List queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit); - - /** * 通过实体作为筛选条件查询 * diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysPermissionDaoImpl.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysPermissionDaoImpl.java new file mode 100644 index 0000000..7096ea9 --- /dev/null +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysPermissionDaoImpl.java @@ -0,0 +1,57 @@ +package com.herion.everyknow.seims.dao.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.herion.everyknow.seims.dao.SysPermissionDao; +import com.herion.everyknow.seims.dao.entity.SysPermission; +import com.herion.everyknow.seims.dao.mapper.SysPermissionMapper; +import com.herion.everyknow.seims.dao.mapper.SysRolePermissionMapper; +import com.herion.everyknow.seims.service.SysRolePermissionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @Description 用户 权限表 数据访问层 + * @auther wubo25320 + * @create 2020-04-20 16:02 + */ +@Repository +public class SysPermissionDaoImpl implements SysPermissionDao { + + @Autowired + private SysPermissionMapper mapper; + + @Override + public SysPermission queryById(Integer id) { + return mapper.selectById(id); + } + + @Override + public List queryAll(SysPermission sysPermission) { + return mapper.selectList(this.createWrapper(sysPermission)); + } + + @Override + public int insert(SysPermission sysPermission) { + return mapper.insert(sysPermission); + } + + @Override + public int update(SysPermission sysPermission) { + return mapper.updateById(sysPermission); + } + + @Override + public int deleteById(Integer id) { + return mapper.deleteById(id); + } + + private LambdaQueryWrapper createWrapper(SysPermission sysPermission) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (sysPermission.getId() != null) { + wrapper.eq(SysPermission::getId, sysPermission.getId()); + } + return wrapper; + } +} diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRoleDaoImpl.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRoleDaoImpl.java new file mode 100644 index 0000000..51ad273 --- /dev/null +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRoleDaoImpl.java @@ -0,0 +1,53 @@ +package com.herion.everyknow.seims.dao.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.herion.everyknow.seims.dao.SysRoleDao; +import com.herion.everyknow.seims.dao.entity.SysRole; +import com.herion.everyknow.seims.dao.mapper.SysRoleMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @Description 用户 角色 数据访问层 + * @auther wubo25320 + * @create 2020-04-20 16:22 + */ +@Repository +public class SysRoleDaoImpl implements SysRoleDao { + + @Autowired + private SysRoleMapper mapper; + + @Override + public SysRole queryById(Integer id) { + return mapper.selectById(id); + } + + @Override + public List queryAll(SysRole sysRole) { + return null; + } + + @Override + public int insert(SysRole sysRole) { + return 0; + } + + @Override + public int update(SysRole sysRole) { + return 0; + } + + @Override + public int deleteById(Integer id) { + return 0; + } + + private LambdaQueryWrapper createWrapper(SysRole sysRole) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + return wrapper; + } +} diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRolePermissionDaoImpl.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRolePermissionDaoImpl.java new file mode 100644 index 0000000..2be1874 --- /dev/null +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/dao/impl/SysRolePermissionDaoImpl.java @@ -0,0 +1,61 @@ +package com.herion.everyknow.seims.dao.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.herion.everyknow.seims.dao.SysRolePermissionDao; +import com.herion.everyknow.seims.dao.entity.SysRolePermission; +import com.herion.everyknow.seims.dao.mapper.SysRolePermissionMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @Description 用户 角色权限表 数据访问层 + * @auther wubo25320 + * @create 2020-04-20 15:45 + */ +@Repository +public class SysRolePermissionDaoImpl implements SysRolePermissionDao { + + @Autowired + private SysRolePermissionMapper mapper; + + @Override + public SysRolePermission queryById(Integer id) { + return mapper.selectById(id); + } + + @Override + public List queryAll(SysRolePermission sysRolePermission) { + return mapper.selectList(this.createWrapper(sysRolePermission)); + } + + @Override + public int insert(SysRolePermission sysRolePermission) { + return mapper.insert(sysRolePermission); + } + + @Override + public int update(SysRolePermission sysRolePermission) { + return mapper.updateById(sysRolePermission); + } + + @Override + public int deleteById(Integer id) { + return mapper.deleteById(id); + } + + private LambdaQueryWrapper createWrapper(SysRolePermission sysRolePermission) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (sysRolePermission.getId() != null) { + wrapper.eq(SysRolePermission::getId, sysRolePermission.getId()); + } + if (sysRolePermission.getRoleId() != null) { + wrapper.eq(SysRolePermission::getRoleId, sysRolePermission.getRoleId()); + } + if (sysRolePermission.getPermissionId() != null) { + wrapper.eq(SysRolePermission::getPermissionId, sysRolePermission.getPermissionId()); + } + return wrapper; + } +} diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysRolePermissionService.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysRolePermissionService.java new file mode 100644 index 0000000..3f2e8d0 --- /dev/null +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysRolePermissionService.java @@ -0,0 +1,54 @@ +package com.herion.everyknow.seims.service; + +import com.herion.everyknow.seims.dao.entity.SysRolePermission; + +import java.util.List; + +/** + * 角色权限表(SysRolePermission)表服务接口 + * + * @author wubo25320 + * @since 2020-04-20 15:51:07 + */ +public interface SysRolePermissionService { + + /** + * 通过ID查询单条数据 + * + * @param id 主键 + * @return 实例对象 + */ + SysRolePermission queryById(Integer id); + + /** + * 新增数据 + * + * @param sysRolePermission 实例对象 + * @return 实例对象 + */ + int insert(SysRolePermission sysRolePermission); + + /** + * 修改数据 + * + * @param sysRolePermission 实例对象 + * @return 实例对象 + */ + int update(SysRolePermission sysRolePermission); + + /** + * 通过主键删除数据 + * + * @param id 主键 + * @return 是否成功 + */ + boolean deleteById(Integer id); + + /** + * 根据 roleId 获取 角色权限表 + * @param roleId + * @return + */ + List queryByRoleId(Integer roleId); + +} \ No newline at end of file diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysUserRoleService.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysUserRoleService.java index ccd66bc..167ef32 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysUserRoleService.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/SysUserRoleService.java @@ -25,7 +25,7 @@ public interface SysUserRoleService { * @param sysUserRole 实例对象 * @return 实例对象 */ - SysUserRole insert(SysUserRole sysUserRole); + int insert(SysUserRole sysUserRole); /** * 修改数据 @@ -33,7 +33,7 @@ public interface SysUserRoleService { * @param sysUserRole 实例对象 * @return 实例对象 */ - SysUserRole update(SysUserRole sysUserRole); + int update(SysUserRole sysUserRole); /** * 通过主键删除数据 @@ -43,4 +43,11 @@ public interface SysUserRoleService { */ boolean deleteById(Integer id); + /** + * 根据 用户id 获取 用户角色 + * @param userId + * @return + */ + SysUserRole queryByUserId(Integer userId); + } \ No newline at end of file diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysRolePermissionServiceImpl.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysRolePermissionServiceImpl.java new file mode 100644 index 0000000..c1d7452 --- /dev/null +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysRolePermissionServiceImpl.java @@ -0,0 +1,53 @@ +package com.herion.everyknow.seims.service.impl; + +import com.herion.everyknow.seims.dao.SysRolePermissionDao; +import com.herion.everyknow.seims.dao.entity.SysRolePermission; +import com.herion.everyknow.seims.service.SysRolePermissionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; + +/** + * @Description 用户 角色权限表 业务层 + * @auther wubo25320 + * @create 2020-04-20 15:51 + */ +@Service +public class SysRolePermissionServiceImpl implements SysRolePermissionService { + + @Autowired + private SysRolePermissionDao sysRolePermissionDao; + + @Override + public SysRolePermission queryById(Integer id) { + return sysRolePermissionDao.queryById(id); + } + + @Override + public int insert(SysRolePermission sysRolePermission) { + return sysRolePermissionDao.insert(sysRolePermission); + } + + @Override + public int update(SysRolePermission sysRolePermission) { + return sysRolePermissionDao.update(sysRolePermission); + } + + @Override + public boolean deleteById(Integer id) { + return false; + } + + @Override + public List queryByRoleId(Integer roleId) { + SysRolePermission query = new SysRolePermission(); + query.setRoleId(roleId); + List sysRolePermissionList = sysRolePermissionDao.queryAll(query); + if (sysRolePermissionList == null) { + return Collections.EMPTY_LIST; + } + return sysRolePermissionList; + } +} diff --git a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysUserRoleServiceImpl.java b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysUserRoleServiceImpl.java index 19d19f8..5efc89d 100644 --- a/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysUserRoleServiceImpl.java +++ b/everyknow-seims-core/src/main/java/com/herion/everyknow/seims/service/impl/SysUserRoleServiceImpl.java @@ -3,6 +3,7 @@ import com.herion.everyknow.seims.dao.SysUserRoleDao; import com.herion.everyknow.seims.dao.entity.SysUserRole; import com.herion.everyknow.seims.service.SysUserRoleService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -14,9 +15,10 @@ * @author wubo25320 * @since 2020-04-20 14:03:22 */ -@Service("sysUserRoleService") +@Service public class SysUserRoleServiceImpl implements SysUserRoleService { - @Resource + + @Autowired private SysUserRoleDao sysUserRoleDao; /** @@ -37,9 +39,8 @@ public SysUserRole queryById(Integer id) { * @return 实例对象 */ @Override - public SysUserRole insert(SysUserRole sysUserRole) { - this.sysUserRoleDao.insert(sysUserRole); - return sysUserRole; + public int insert(SysUserRole sysUserRole) { + return this.sysUserRoleDao.insert(sysUserRole); } /** @@ -49,9 +50,8 @@ public SysUserRole insert(SysUserRole sysUserRole) { * @return 实例对象 */ @Override - public SysUserRole update(SysUserRole sysUserRole) { - this.sysUserRoleDao.update(sysUserRole); - return this.queryById(sysUserRole.getId()); + public int update(SysUserRole sysUserRole) { + return this.sysUserRoleDao.update(sysUserRole); } /** @@ -64,4 +64,15 @@ public SysUserRole update(SysUserRole sysUserRole) { public boolean deleteById(Integer id) { return this.sysUserRoleDao.deleteById(id) > 0; } + + @Override + public SysUserRole queryByUserId(Integer userId) { + SysUserRole query = new SysUserRole(); + query.setUserId(userId); + List sysUserRoleList = sysUserRoleDao.queryAll(query); + if (sysUserRoleList == null || sysUserRoleList.size() == 0) { + return new SysUserRole(); + } + return sysUserRoleList.get(0); + } } \ No newline at end of file diff --git a/everyknow-seims-core/src/main/resources/config.properties b/everyknow-seims-core/src/main/resources/config.properties index 624587c..1f6c7ec 100644 --- a/everyknow-seims-core/src/main/resources/config.properties +++ b/everyknow-seims-core/src/main/resources/config.properties @@ -10,6 +10,8 @@ eknow.refreshTokenExpireTime=1800 eknow.accessTokenExpireTime=300000 # Shiro ʱ-5-5*60(Ϊλ)-һAccessTokenʱһ eknow.shiroCacheExpireTime=300 +# RefreshTokenɹʱ-15(Ϊλ) +eknow.refreshTokenTransitionExpireTime=15 #Redis diff --git a/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/LocationController.java b/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/LocationController.java index 65ab045..8c3d662 100644 --- a/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/LocationController.java +++ b/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/LocationController.java @@ -10,6 +10,7 @@ import com.herion.everyknow.web.utils.ResultUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -35,6 +36,7 @@ public class LocationController { private LocationService locationService; @ApiOperation(value = "获取全部省份") + @RequiresPermissions("dddd") @RequestMapping(path = "/getProvinces", method = RequestMethod.POST) public EKnowResponse getProvinces() { List provinces = provinceService.selectAll(); diff --git a/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/SysUserController.java b/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/SysUserController.java index 121be23..ce55496 100644 --- a/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/SysUserController.java +++ b/everyknow-seims-web/src/main/java/com/herion/everyknow/seims/facade/controller/SysUserController.java @@ -76,7 +76,7 @@ public EKnowResponse login(@RequestBody CommonHttpRequest request, Http String currentTimeMillis = String.valueOf(System.currentTimeMillis()); JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + request.getRequest().getUsername(), currentTimeMillis, (int)EknowConfig.getRefreshTokenExpireTime()); // 在 Header 中的Authorization 设置AccessToken.时间戳为当前时间 - String token = JWTUtil.sign(request.getRequest().getUsername(), String.valueOf(System.currentTimeMillis())); + String token = JWTUtil.sign(request.getRequest().getUsername(), currentTimeMillis); // // 这里不能做 login. 因为此时 // Subject subject = SecurityUtils.getSubject();