diff --git a/pom.xml b/pom.xml index 16501c330..7763720bc 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ 2.2.11 3.3.0 2.3 + 1.28.0 3.5.0 3.9.1 5.7.18 @@ -137,6 +138,19 @@ ${velocity.version} + + + cn.dev33 + sa-token-spring-boot-starter + ${satoken.version} + + + + cn.dev33 + sa-token-jwt + ${satoken.version} + + com.sun.xml.bind diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java index ef81c99a3..255f0b11b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.monitor; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; import io.swagger.annotations.Api; @@ -9,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -30,7 +30,7 @@ public class CacheController { private final RedisTemplate redisTemplate; @ApiOperation("获取缓存监控详细信息") - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @SaCheckPermission("monitor:cache:list") @GetMapping() public AjaxResult> getInfo() throws Exception { Properties info = (Properties) redisTemplate.execute((RedisCallback) RedisServerCommands::info); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java index 106605ae3..22acf3181 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.monitor; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -13,7 +14,6 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -35,7 +35,7 @@ public class SysLogininforController extends BaseController { private final ISysLogininforService logininforService; @ApiOperation("查询系统访问记录列表") - @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @SaCheckPermission("monitor:logininfor:list") @GetMapping("/list") public TableDataInfo list(SysLogininfor logininfor, PageQuery pageQuery) { return logininforService.selectPageLogininforList(logininfor, pageQuery); @@ -43,7 +43,7 @@ public class SysLogininforController extends BaseController { @ApiOperation("导出系统访问记录列表") @Log(title = "登录日志", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @SaCheckPermission("monitor:logininfor:export") @PostMapping("/export") public void export(SysLogininfor logininfor, HttpServletResponse response) { List list = logininforService.selectLogininforList(logininfor); @@ -51,7 +51,7 @@ public class SysLogininforController extends BaseController { } @ApiOperation("删除系统访问记录") - @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @SaCheckPermission("monitor:logininfor:remove") @Log(title = "登录日志", businessType = BusinessType.DELETE) @DeleteMapping("/{infoIds}") public AjaxResult remove(@PathVariable Long[] infoIds) { @@ -59,7 +59,7 @@ public class SysLogininforController extends BaseController { } @ApiOperation("清空系统访问记录") - @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @SaCheckPermission("monitor:logininfor:remove") @Log(title = "登录日志", businessType = BusinessType.CLEAN) @DeleteMapping("/clean") public AjaxResult clean() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java index 8af583277..e51042952 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.monitor; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -13,7 +14,6 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -35,7 +35,7 @@ public class SysOperlogController extends BaseController { private final ISysOperLogService operLogService; @ApiOperation("查询操作日志记录列表") - @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @SaCheckPermission("monitor:operlog:list") @GetMapping("/list") public TableDataInfo list(SysOperLog operLog, PageQuery pageQuery) { return operLogService.selectPageOperLogList(operLog, pageQuery); @@ -43,7 +43,7 @@ public class SysOperlogController extends BaseController { @ApiOperation("导出操作日志记录列表") @Log(title = "操作日志", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @SaCheckPermission("monitor:operlog:export") @PostMapping("/export") public void export(SysOperLog operLog, HttpServletResponse response) { List list = operLogService.selectOperLogList(operLog); @@ -52,7 +52,7 @@ public class SysOperlogController extends BaseController { @ApiOperation("删除操作日志记录") @Log(title = "操作日志", businessType = BusinessType.DELETE) - @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @SaCheckPermission("monitor:operlog:remove") @DeleteMapping("/{operIds}") public AjaxResult remove(@PathVariable Long[] operIds) { return toAjax(operLogService.deleteOperLogByIds(operIds)); @@ -60,7 +60,7 @@ public class SysOperlogController extends BaseController { @ApiOperation("清空操作日志记录") @Log(title = "操作日志", businessType = BusinessType.CLEAN) - @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @SaCheckPermission("monitor:operlog:remove") @DeleteMapping("/clean") public AjaxResult clean() { operLogService.cleanOperLog(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java index 6c96564cb..90003ef4e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java @@ -1,27 +1,30 @@ package com.ruoyi.web.controller.monitor; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.dto.UserOnlineDTO; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.redis.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SysUserOnline; -import com.ruoyi.system.service.ISysUserOnlineService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; /** * 在线用户监控 @@ -34,34 +37,38 @@ import java.util.List; @RequestMapping("/monitor/online") public class SysUserOnlineController extends BaseController { - private final ISysUserOnlineService userOnlineService; - @ApiOperation("在线用户列表") - @PreAuthorize("@ss.hasPermi('monitor:online:list')") + @SaCheckPermission("monitor:online:list") @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { - Collection keys = RedisUtils.keys(Constants.LOGIN_TOKEN_KEY + "*"); - List userOnlineList = new ArrayList(); + // 获取所有未过期的 token + List keys = StpUtil.searchTokenValue("", -1, 0); + List userOnlineDTOList = new ArrayList<>(); for (String key : keys) { - LoginUser user = RedisUtils.getCacheObject(key); - if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { - if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) { - userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); - } - } else if (StringUtils.isNotEmpty(ipaddr)) { - if (StringUtils.equals(ipaddr, user.getIpaddr())) { - userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); - } - } else if (StringUtils.isNotEmpty(userName)) { - if (StringUtils.equals(userName, user.getUsername())) { - userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); - } - } else { - userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + String token = key.replace(Constants.LOGIN_TOKEN_KEY, ""); + // 如果已经过期则踢下线 + if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < 0) { + continue; } + userOnlineDTOList.add(RedisUtils.getCacheObject(Constants.ONLINE_TOKEN_KEY + token)); } - Collections.reverse(userOnlineList); - userOnlineList.removeAll(Collections.singleton(null)); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { + userOnlineDTOList = userOnlineDTOList.stream().filter(userOnline -> + StringUtils.equals(ipaddr, userOnline.getIpaddr()) && + StringUtils.equals(userName, userOnline.getUserName()) + ).collect(Collectors.toList()); + } else if (StringUtils.isNotEmpty(ipaddr)) { + userOnlineDTOList = userOnlineDTOList.stream().filter(userOnline -> + StringUtils.equals(ipaddr, userOnline.getIpaddr())) + .collect(Collectors.toList()); + } else if (StringUtils.isNotEmpty(userName)) { + userOnlineDTOList = userOnlineDTOList.stream().filter(userOnline -> + StringUtils.equals(userName, userOnline.getUserName()) + ).collect(Collectors.toList()); + } + Collections.reverse(userOnlineDTOList); + userOnlineDTOList.removeAll(Collections.singleton(null)); + List userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); return TableDataInfo.build(userOnlineList); } @@ -69,11 +76,14 @@ public class SysUserOnlineController extends BaseController { * 强退用户 */ @ApiOperation("强退用户") - @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") + @SaCheckPermission("monitor:online:forceLogout") @Log(title = "在线用户", businessType = BusinessType.FORCE) @DeleteMapping("/{tokenId}") public AjaxResult forceLogout(@PathVariable String tokenId) { - RedisUtils.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); + try { + StpUtil.kickoutByTokenValue(tokenId); + } catch (NotLoginException e) { + } return AjaxResult.success(); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java index e646b9a86..0b8a9284b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; @@ -15,7 +16,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -40,7 +40,7 @@ public class SysConfigController extends BaseController { * 获取参数配置列表 */ @ApiOperation("获取参数配置列表") - @PreAuthorize("@ss.hasPermi('system:config:list')") + @SaCheckPermission("system:config:list") @GetMapping("/list") public TableDataInfo list(SysConfig config, PageQuery pageQuery) { return configService.selectPageConfigList(config, pageQuery); @@ -48,7 +48,7 @@ public class SysConfigController extends BaseController { @ApiOperation("导出参数配置列表") @Log(title = "参数管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:config:export')") + @SaCheckPermission("system:config:export") @PostMapping("/export") public void export(SysConfig config, HttpServletResponse response) { List list = configService.selectConfigList(config); @@ -59,7 +59,7 @@ public class SysConfigController extends BaseController { * 根据参数编号获取详细信息 */ @ApiOperation("根据参数编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:config:query')") + @SaCheckPermission("system:config:query") @GetMapping(value = "/{configId}") public AjaxResult getInfo(@ApiParam("参数ID") @PathVariable Long configId) { return AjaxResult.success(configService.selectConfigById(configId)); @@ -78,7 +78,7 @@ public class SysConfigController extends BaseController { * 新增参数配置 */ @ApiOperation("新增参数配置") - @PreAuthorize("@ss.hasPermi('system:config:add')") + @SaCheckPermission("system:config:add") @Log(title = "参数管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysConfig config) { @@ -92,7 +92,7 @@ public class SysConfigController extends BaseController { * 修改参数配置 */ @ApiOperation("修改参数配置") - @PreAuthorize("@ss.hasPermi('system:config:edit')") + @SaCheckPermission("system:config:edit") @Log(title = "参数管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysConfig config) { @@ -106,7 +106,7 @@ public class SysConfigController extends BaseController { * 删除参数配置 */ @ApiOperation("删除参数配置") - @PreAuthorize("@ss.hasPermi('system:config:remove')") + @SaCheckPermission("system:config:remove") @Log(title = "参数管理", businessType = BusinessType.DELETE) @DeleteMapping("/{configIds}") public AjaxResult remove(@ApiParam("参数ID串") @PathVariable Long[] configIds) { @@ -118,7 +118,7 @@ public class SysConfigController extends BaseController { * 刷新参数缓存 */ @ApiOperation("刷新参数缓存") - @PreAuthorize("@ss.hasPermi('system:config:remove')") + @SaCheckPermission("system:config:remove") @Log(title = "参数管理", businessType = BusinessType.CLEAN) @DeleteMapping("/refreshCache") public AjaxResult refreshCache() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java index e47b1e885..08ebf9606 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.util.ArrayUtil; import com.ruoyi.common.annotation.Log; @@ -15,7 +16,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -41,7 +41,7 @@ public class SysDeptController extends BaseController { * 获取部门列表 */ @ApiOperation("获取部门列表") - @PreAuthorize("@ss.hasPermi('system:dept:list')") + @SaCheckPermission("system:dept:list") @GetMapping("/list") public AjaxResult> list(SysDept dept) { List depts = deptService.selectDeptList(dept); @@ -52,7 +52,7 @@ public class SysDeptController extends BaseController { * 查询部门列表(排除节点) */ @ApiOperation("查询部门列表(排除节点)") - @PreAuthorize("@ss.hasPermi('system:dept:list')") + @SaCheckPermission("system:dept:list") @GetMapping("/list/exclude/{deptId}") public AjaxResult> excludeChild(@ApiParam("部门ID") @PathVariable(value = "deptId", required = false) Long deptId) { List depts = deptService.selectDeptList(new SysDept()); @@ -65,7 +65,7 @@ public class SysDeptController extends BaseController { * 根据部门编号获取详细信息 */ @ApiOperation("根据部门编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:dept:query')") + @SaCheckPermission("system:dept:query") @GetMapping(value = "/{deptId}") public AjaxResult getInfo(@ApiParam("部门ID") @PathVariable Long deptId) { deptService.checkDeptDataScope(deptId); @@ -99,7 +99,7 @@ public class SysDeptController extends BaseController { * 新增部门 */ @ApiOperation("新增部门") - @PreAuthorize("@ss.hasPermi('system:dept:add')") + @SaCheckPermission("system:dept:add") @Log(title = "部门管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysDept dept) { @@ -113,7 +113,7 @@ public class SysDeptController extends BaseController { * 修改部门 */ @ApiOperation("修改部门") - @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @SaCheckPermission("system:dept:edit") @Log(title = "部门管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysDept dept) { @@ -132,7 +132,7 @@ public class SysDeptController extends BaseController { * 删除部门 */ @ApiOperation("删除部门") - @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @SaCheckPermission("system:dept:remove") @Log(title = "部门管理", businessType = BusinessType.DELETE) @DeleteMapping("/{deptId}") public AjaxResult remove(@ApiParam("部门ID串") @PathVariable Long deptId) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java index 07cb74e03..851cf4ee0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -16,7 +17,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -40,7 +40,7 @@ public class SysDictDataController extends BaseController { private final ISysDictTypeService dictTypeService; @ApiOperation("查询字典数据列表") - @PreAuthorize("@ss.hasPermi('system:dict:list')") + @SaCheckPermission("system:dict:list") @GetMapping("/list") public TableDataInfo list(SysDictData dictData, PageQuery pageQuery) { return dictDataService.selectPageDictDataList(dictData, pageQuery); @@ -48,7 +48,7 @@ public class SysDictDataController extends BaseController { @ApiOperation("导出字典数据列表") @Log(title = "字典数据", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:dict:export')") + @SaCheckPermission("system:dict:export") @PostMapping("/export") public void export(SysDictData dictData, HttpServletResponse response) { List list = dictDataService.selectDictDataList(dictData); @@ -59,7 +59,7 @@ public class SysDictDataController extends BaseController { * 查询字典数据详细 */ @ApiOperation("查询字典数据详细") - @PreAuthorize("@ss.hasPermi('system:dict:query')") + @SaCheckPermission("system:dict:query") @GetMapping(value = "/{dictCode}") public AjaxResult getInfo(@ApiParam("字典code") @PathVariable Long dictCode) { return AjaxResult.success(dictDataService.selectDictDataById(dictCode)); @@ -82,7 +82,7 @@ public class SysDictDataController extends BaseController { * 新增字典类型 */ @ApiOperation("新增字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:add')") + @SaCheckPermission("system:dict:add") @Log(title = "字典数据", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysDictData dict) { @@ -93,7 +93,7 @@ public class SysDictDataController extends BaseController { * 修改保存字典类型 */ @ApiOperation("修改保存字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @SaCheckPermission("system:dict:edit") @Log(title = "字典数据", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysDictData dict) { @@ -104,7 +104,7 @@ public class SysDictDataController extends BaseController { * 删除字典类型 */ @ApiOperation("删除字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.DELETE) @DeleteMapping("/{dictCodes}") public AjaxResult remove(@ApiParam("字典code串") @PathVariable Long[] dictCodes) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java index ca43783b2..9d98f9b3d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; @@ -15,7 +16,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -37,7 +37,7 @@ public class SysDictTypeController extends BaseController { private final ISysDictTypeService dictTypeService; @ApiOperation("查询字典类型列表") - @PreAuthorize("@ss.hasPermi('system:dict:list')") + @SaCheckPermission("system:dict:list") @GetMapping("/list") public TableDataInfo list(SysDictType dictType, PageQuery pageQuery) { return dictTypeService.selectPageDictTypeList(dictType, pageQuery); @@ -45,7 +45,7 @@ public class SysDictTypeController extends BaseController { @ApiOperation("导出字典类型列表") @Log(title = "字典类型", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:dict:export')") + @SaCheckPermission("system:dict:export") @PostMapping("/export") public void export(SysDictType dictType, HttpServletResponse response) { List list = dictTypeService.selectDictTypeList(dictType); @@ -56,7 +56,7 @@ public class SysDictTypeController extends BaseController { * 查询字典类型详细 */ @ApiOperation("查询字典类型详细") - @PreAuthorize("@ss.hasPermi('system:dict:query')") + @SaCheckPermission("system:dict:query") @GetMapping(value = "/{dictId}") public AjaxResult getInfo(@ApiParam("字典ID") @PathVariable Long dictId) { return AjaxResult.success(dictTypeService.selectDictTypeById(dictId)); @@ -66,7 +66,7 @@ public class SysDictTypeController extends BaseController { * 新增字典类型 */ @ApiOperation("新增字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:add')") + @SaCheckPermission("system:dict:add") @Log(title = "字典类型", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysDictType dict) { @@ -80,7 +80,7 @@ public class SysDictTypeController extends BaseController { * 修改字典类型 */ @ApiOperation("修改字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @SaCheckPermission("system:dict:edit") @Log(title = "字典类型", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysDictType dict) { @@ -94,7 +94,7 @@ public class SysDictTypeController extends BaseController { * 删除字典类型 */ @ApiOperation("删除字典类型") - @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.DELETE) @DeleteMapping("/{dictIds}") public AjaxResult remove(@ApiParam("字典ID串") @PathVariable Long[] dictIds) { @@ -106,7 +106,7 @@ public class SysDictTypeController extends BaseController { * 刷新字典缓存 */ @ApiOperation("刷新字典缓存") - @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.CLEAN) @DeleteMapping("/refreshCache") public AjaxResult refreshCache() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 9e518234d..6322ed5e0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -1,14 +1,17 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.stp.StpUtil; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginBody; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.core.service.UserService; +import com.ruoyi.common.utils.LoginUtils; +import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.vo.RouterVo; import com.ruoyi.system.service.ISysMenuService; -import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.SysLoginService; import com.ruoyi.system.service.SysPermissionService; import io.swagger.annotations.Api; @@ -39,7 +42,6 @@ public class SysLoginController { private final SysLoginService loginService; private final ISysMenuService menuService; - private final ISysUserService userService; private final SysPermissionService permissionService; /** @@ -59,6 +61,16 @@ public class SysLoginController { return AjaxResult.success(ajax); } + @ApiOperation("登出方法") + @PostMapping("/logout") + public AjaxResult logout(){ + try { + StpUtil.logout(); + } catch (NotLoginException e) { + } + return AjaxResult.success("退出成功"); + } + /** * 获取用户信息 * @@ -67,7 +79,7 @@ public class SysLoginController { @ApiOperation("获取用户信息") @GetMapping("getInfo") public AjaxResult> getInfo() { - SysUser user = userService.selectUserById(SecurityUtils.getUserId()); + SysUser user = SpringUtils.getBean(UserService.class).selectUserById(LoginUtils.getUserId()); // 角色集合 Set roles = permissionService.getRolePermission(user); // 权限集合 @@ -87,7 +99,7 @@ public class SysLoginController { @ApiOperation("获取路由信息") @GetMapping("getRouters") public AjaxResult> getRouters() { - Long userId = SecurityUtils.getUserId(); + Long userId = LoginUtils.getUserId(); List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java index a525ac422..118f87b1b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.tree.Tree; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; @@ -14,7 +15,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -40,7 +40,7 @@ public class SysMenuController extends BaseController { * 获取菜单列表 */ @ApiOperation("获取菜单列表") - @PreAuthorize("@ss.hasPermi('system:menu:list')") + @SaCheckPermission("system:menu:list") @GetMapping("/list") public AjaxResult> list(SysMenu menu) { List menus = menuService.selectMenuList(menu, getUserId()); @@ -51,7 +51,7 @@ public class SysMenuController extends BaseController { * 根据菜单编号获取详细信息 */ @ApiOperation("根据菜单编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:menu:query')") + @SaCheckPermission("system:menu:query") @GetMapping(value = "/{menuId}") public AjaxResult getInfo(@ApiParam("菜单ID") @PathVariable Long menuId) { return AjaxResult.success(menuService.selectMenuById(menuId)); @@ -84,7 +84,7 @@ public class SysMenuController extends BaseController { * 新增菜单 */ @ApiOperation("新增菜单") - @PreAuthorize("@ss.hasPermi('system:menu:add')") + @SaCheckPermission("system:menu:add") @Log(title = "菜单管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysMenu menu) { @@ -100,7 +100,7 @@ public class SysMenuController extends BaseController { * 修改菜单 */ @ApiOperation("修改菜单") - @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @SaCheckPermission("system:menu:edit") @Log(title = "菜单管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysMenu menu) { @@ -118,7 +118,7 @@ public class SysMenuController extends BaseController { * 删除菜单 */ @ApiOperation("删除菜单") - @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @SaCheckPermission("system:menu:remove") @Log(title = "菜单管理", businessType = BusinessType.DELETE) @DeleteMapping("/{menuId}") public AjaxResult remove(@ApiParam("菜单ID") @PathVariable("menuId") Long menuId) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java index 337bf32a3..23e8593ec 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -8,14 +9,13 @@ import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.system.domain.SysNotice; import com.ruoyi.system.service.ISysNoticeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; /** * 公告 信息操作处理 @@ -35,7 +35,7 @@ public class SysNoticeController extends BaseController { * 获取通知公告列表 */ @ApiOperation("获取通知公告列表") - @PreAuthorize("@ss.hasPermi('system:notice:list')") + @SaCheckPermission("system:notice:list") @GetMapping("/list") public TableDataInfo list(SysNotice notice, PageQuery pageQuery) { return noticeService.selectPageNoticeList(notice, pageQuery); @@ -45,7 +45,7 @@ public class SysNoticeController extends BaseController { * 根据通知公告编号获取详细信息 */ @ApiOperation("根据通知公告编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:notice:query')") + @SaCheckPermission("system:notice:query") @GetMapping(value = "/{noticeId}") public AjaxResult getInfo(@ApiParam("公告ID") @PathVariable Long noticeId) { return AjaxResult.success(noticeService.selectNoticeById(noticeId)); @@ -55,7 +55,7 @@ public class SysNoticeController extends BaseController { * 新增通知公告 */ @ApiOperation("新增通知公告") - @PreAuthorize("@ss.hasPermi('system:notice:add')") + @SaCheckPermission("system:notice:add") @Log(title = "通知公告", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysNotice notice) { @@ -66,7 +66,7 @@ public class SysNoticeController extends BaseController { * 修改通知公告 */ @ApiOperation("修改通知公告") - @PreAuthorize("@ss.hasPermi('system:notice:edit')") + @SaCheckPermission("system:notice:edit") @Log(title = "通知公告", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysNotice notice) { @@ -77,7 +77,7 @@ public class SysNoticeController extends BaseController { * 删除通知公告 */ @ApiOperation("删除通知公告") - @PreAuthorize("@ss.hasPermi('system:notice:remove')") + @SaCheckPermission("system:notice:remove") @Log(title = "通知公告", businessType = BusinessType.DELETE) @DeleteMapping("/{noticeIds}") public AjaxResult remove(@ApiParam("公告ID串") @PathVariable Long[] noticeIds) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java index 803f95ece..0562cdf8d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; @@ -18,7 +19,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -46,7 +46,7 @@ public class SysOssConfigController extends BaseController { * 查询对象存储配置列表 */ @ApiOperation("查询对象存储配置列表") - @PreAuthorize("@ss.hasPermi('system:oss:list')") + @SaCheckPermission("system:oss:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { return iSysOssConfigService.queryPageList(bo, pageQuery); @@ -56,7 +56,7 @@ public class SysOssConfigController extends BaseController { * 获取对象存储配置详细信息 */ @ApiOperation("获取对象存储配置详细信息") - @PreAuthorize("@ss.hasPermi('system:oss:query')") + @SaCheckPermission("system:oss:query") @GetMapping("/{ossConfigId}") public AjaxResult getInfo(@ApiParam("OSS配置ID") @NotNull(message = "主键不能为空") @@ -68,7 +68,7 @@ public class SysOssConfigController extends BaseController { * 新增对象存储配置 */ @ApiOperation("新增对象存储配置") - @PreAuthorize("@ss.hasPermi('system:oss:add')") + @SaCheckPermission("system:oss:add") @Log(title = "对象存储配置", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() @@ -80,7 +80,7 @@ public class SysOssConfigController extends BaseController { * 修改对象存储配置 */ @ApiOperation("修改对象存储配置") - @PreAuthorize("@ss.hasPermi('system:oss:edit')") + @SaCheckPermission("system:oss:edit") @Log(title = "对象存储配置", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() @@ -92,7 +92,7 @@ public class SysOssConfigController extends BaseController { * 删除对象存储配置 */ @ApiOperation("删除对象存储配置") - @PreAuthorize("@ss.hasPermi('system:oss:remove')") + @SaCheckPermission("system:oss:remove") @Log(title = "对象存储配置", businessType = BusinessType.DELETE) @DeleteMapping("/{ossConfigIds}") public AjaxResult remove(@ApiParam("OSS配置ID串") @@ -105,7 +105,7 @@ public class SysOssConfigController extends BaseController { * 状态修改 */ @ApiOperation("状态修改") - @PreAuthorize("@ss.hasPermi('system:oss:edit')") + @SaCheckPermission("system:oss:edit") @Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public AjaxResult changeStatus(@RequestBody SysOssConfigBo bo) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java index b96687961..5a35a49e4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java @@ -1,6 +1,7 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpException; @@ -27,7 +28,6 @@ import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -59,7 +59,7 @@ public class SysOssController extends BaseController { * 查询OSS对象存储列表 */ @ApiOperation("查询OSS对象存储列表") - @PreAuthorize("@ss.hasPermi('system:oss:list')") + @SaCheckPermission("system:oss:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { return iSysOssService.queryPageList(bo, pageQuery); @@ -72,7 +72,7 @@ public class SysOssController extends BaseController { @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = File.class, required = true), }) - @PreAuthorize("@ss.hasPermi('system:oss:upload')") + @SaCheckPermission("system:oss:upload") @Log(title = "OSS对象存储", businessType = BusinessType.INSERT) @RepeatSubmit @PostMapping("/upload") @@ -88,7 +88,7 @@ public class SysOssController extends BaseController { } @ApiOperation("下载OSS对象存储") - @PreAuthorize("@ss.hasPermi('system:oss:download')") + @SaCheckPermission("system:oss:download") @GetMapping("/download/{ossId}") public void download(@ApiParam("OSS对象ID") @PathVariable Long ossId, HttpServletResponse response) throws IOException { SysOss sysOss = iSysOssService.getById(ossId); @@ -115,7 +115,7 @@ public class SysOssController extends BaseController { * 删除OSS对象存储 */ @ApiOperation("删除OSS对象存储") - @PreAuthorize("@ss.hasPermi('system:oss:remove')") + @SaCheckPermission("system:oss:remove") @Log(title = "OSS对象存储", businessType = BusinessType.DELETE) @DeleteMapping("/{ossIds}") public AjaxResult remove(@ApiParam("OSS对象ID串") @@ -128,7 +128,7 @@ public class SysOssController extends BaseController { * 变更图片列表预览状态 */ @ApiOperation("变更图片列表预览状态") - @PreAuthorize("@ss.hasPermi('system:oss:edit')") + @SaCheckPermission("system:oss:edit") @Log(title = "OSS对象存储", businessType = BusinessType.UPDATE) @PutMapping("/changePreviewListResource") public AjaxResult changePreviewListResource(@RequestBody String body) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java index 4f119e411..6b383a409 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; @@ -15,7 +16,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -40,7 +40,7 @@ public class SysPostController extends BaseController { * 获取岗位列表 */ @ApiOperation("获取岗位列表") - @PreAuthorize("@ss.hasPermi('system:post:list')") + @SaCheckPermission("system:post:list") @GetMapping("/list") public TableDataInfo list(SysPost post, PageQuery pageQuery) { return postService.selectPagePostList(post, pageQuery); @@ -48,7 +48,7 @@ public class SysPostController extends BaseController { @ApiOperation("导出岗位列表") @Log(title = "岗位管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:post:export')") + @SaCheckPermission("system:post:export") @PostMapping("/export") public void export(SysPost post, HttpServletResponse response) { List list = postService.selectPostList(post); @@ -59,7 +59,7 @@ public class SysPostController extends BaseController { * 根据岗位编号获取详细信息 */ @ApiOperation("根据岗位编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:post:query')") + @SaCheckPermission("system:post:query") @GetMapping(value = "/{postId}") public AjaxResult getInfo(@ApiParam("岗位ID") @PathVariable Long postId) { return AjaxResult.success(postService.selectPostById(postId)); @@ -69,7 +69,7 @@ public class SysPostController extends BaseController { * 新增岗位 */ @ApiOperation("新增岗位") - @PreAuthorize("@ss.hasPermi('system:post:add')") + @SaCheckPermission("system:post:add") @Log(title = "岗位管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysPost post) { @@ -85,7 +85,7 @@ public class SysPostController extends BaseController { * 修改岗位 */ @ApiOperation("修改岗位") - @PreAuthorize("@ss.hasPermi('system:post:edit')") + @SaCheckPermission("system:post:edit") @Log(title = "岗位管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysPost post) { @@ -101,7 +101,7 @@ public class SysPostController extends BaseController { * 删除岗位 */ @ApiOperation("删除岗位") - @PreAuthorize("@ss.hasPermi('system:post:remove')") + @SaCheckPermission("system:post:remove") @Log(title = "岗位管理", businessType = BusinessType.DELETE) @DeleteMapping("/{postIds}") public AjaxResult remove(@ApiParam("岗位ID串") @PathVariable Long[] postIds) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java index 6a7f5ed51..5e432ab3e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -5,10 +5,12 @@ import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.service.UserService; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.service.ISysOssService; import com.ruoyi.system.service.ISysUserService; @@ -47,12 +49,11 @@ public class SysProfileController extends BaseController { @ApiOperation("个人信息") @GetMapping public AjaxResult> profile() { - LoginUser loginUser = getLoginUser(); - SysUser user = userService.selectUserById(loginUser.getUserId()); - Map ajax = new HashMap<>(); - ajax.put("user", user); - ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); - ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + SysUser user = userService.getById(getUserId()); + Map ajax = new HashMap<>(); + ajax.put("user", user); + ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); + ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); return AjaxResult.success(ajax); } @@ -71,9 +72,7 @@ public class SysProfileController extends BaseController { && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } - LoginUser loginUser = getLoginUser(); - SysUser sysUser = userService.selectUserById(loginUser.getUserId()); - user.setUserId(sysUser.getUserId()); + user.setUserId(getUserId()); user.setUserName(null); user.setPassword(null); if (userService.updateUserProfile(user) > 0) { @@ -93,7 +92,7 @@ public class SysProfileController extends BaseController { @Log(title = "个人信息", businessType = BusinessType.UPDATE) @PutMapping("/updatePwd") public AjaxResult updatePwd(String oldPassword, String newPassword) { - SysUser user = userService.selectUserById(SecurityUtils.getUserId()); + SysUser user = SpringUtils.getBean(UserService.class).selectUserById(LoginUtils.getUserId()); String userName = user.getUserName(); String password = user.getPassword(); if (!SecurityUtils.matchesPassword(oldPassword, password)) { @@ -118,12 +117,11 @@ public class SysProfileController extends BaseController { @Log(title = "用户头像", businessType = BusinessType.UPDATE) @PostMapping("/avatar") public AjaxResult> avatar(@RequestPart("avatarfile") MultipartFile file) { - Map ajax = new HashMap<>(); + Map ajax = new HashMap<>(); if (!file.isEmpty()) { - LoginUser loginUser = getLoginUser(); - SysOss oss = iSysOssService.upload(file); - String avatar = oss.getUrl(); - if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) { + SysOss oss = iSysOssService.upload(file); + String avatar = oss.getUrl(); + if (userService.updateUserAvatar(getUsername(), avatar)) { ajax.put("imgUrl", avatar); return AjaxResult.success(ajax); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java index 9ddb2178d..ee0a4d4d2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; @@ -9,8 +10,8 @@ import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.core.service.TokenService; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.SysUserRole; @@ -20,7 +21,6 @@ import com.ruoyi.system.service.SysPermissionService; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -40,12 +40,11 @@ import java.util.List; public class SysRoleController extends BaseController { private final ISysRoleService roleService; - private final TokenService tokenService; private final ISysUserService userService; private final SysPermissionService permissionService; @ApiOperation("查询角色信息列表") - @PreAuthorize("@ss.hasPermi('system:role:list')") + @SaCheckPermission("system:role:list") @GetMapping("/list") public TableDataInfo list(SysRole role, PageQuery pageQuery) { return roleService.selectPageRoleList(role, pageQuery); @@ -53,7 +52,7 @@ public class SysRoleController extends BaseController { @ApiOperation("导出角色信息列表") @Log(title = "角色管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:role:export')") + @SaCheckPermission("system:role:export") @PostMapping("/export") public void export(SysRole role, HttpServletResponse response) { List list = roleService.selectRoleList(role); @@ -64,7 +63,7 @@ public class SysRoleController extends BaseController { * 根据角色编号获取详细信息 */ @ApiOperation("根据角色编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:role:query')") + @SaCheckPermission("system:role:query") @GetMapping(value = "/{roleId}") public AjaxResult getInfo(@ApiParam("角色ID") @PathVariable Long roleId) { roleService.checkRoleDataScope(roleId); @@ -75,7 +74,7 @@ public class SysRoleController extends BaseController { * 新增角色 */ @ApiOperation("新增角色") - @PreAuthorize("@ss.hasPermi('system:role:add')") + @SaCheckPermission("system:role:add") @Log(title = "角色管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysRole role) { @@ -92,7 +91,7 @@ public class SysRoleController extends BaseController { * 修改保存角色 */ @ApiOperation("修改保存角色") - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysRole role) { @@ -108,8 +107,8 @@ public class SysRoleController extends BaseController { LoginUser loginUser = getLoginUser(); SysUser sysUser = userService.selectUserById(loginUser.getUserId()); if (StringUtils.isNotNull(sysUser) && !sysUser.isAdmin()) { - loginUser.setMenuPermissions(permissionService.getMenuPermission(sysUser)); - tokenService.setLoginUser(loginUser); + loginUser.setMenuPermission(permissionService.getMenuPermission(sysUser)); + LoginUtils.setLoginUser(loginUser); } return AjaxResult.success(); } @@ -120,7 +119,7 @@ public class SysRoleController extends BaseController { * 修改保存数据权限 */ @ApiOperation("修改保存数据权限") - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.UPDATE) @PutMapping("/dataScope") public AjaxResult dataScope(@RequestBody SysRole role) { @@ -132,7 +131,7 @@ public class SysRoleController extends BaseController { * 状态修改 */ @ApiOperation("状态修改") - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public AjaxResult changeStatus(@RequestBody SysRole role) { @@ -144,7 +143,7 @@ public class SysRoleController extends BaseController { * 删除角色 */ @ApiOperation("删除角色") - @PreAuthorize("@ss.hasPermi('system:role:remove')") + @SaCheckPermission("system:role:remove") @Log(title = "角色管理", businessType = BusinessType.DELETE) @DeleteMapping("/{roleIds}") public AjaxResult remove(@ApiParam("岗位ID串") @PathVariable Long[] roleIds) { @@ -155,7 +154,7 @@ public class SysRoleController extends BaseController { * 获取角色选择框列表 */ @ApiOperation("获取角色选择框列表") - @PreAuthorize("@ss.hasPermi('system:role:query')") + @SaCheckPermission("system:role:query") @GetMapping("/optionselect") public AjaxResult> optionselect() { return AjaxResult.success(roleService.selectRoleAll()); @@ -165,7 +164,7 @@ public class SysRoleController extends BaseController { * 查询已分配用户角色列表 */ @ApiOperation("查询已分配用户角色列表") - @PreAuthorize("@ss.hasPermi('system:role:list')") + @SaCheckPermission("system:role:list") @GetMapping("/authUser/allocatedList") public TableDataInfo allocatedList(SysUser user, PageQuery pageQuery) { return userService.selectAllocatedList(user, pageQuery); @@ -175,7 +174,7 @@ public class SysRoleController extends BaseController { * 查询未分配用户角色列表 */ @ApiOperation("查询未分配用户角色列表") - @PreAuthorize("@ss.hasPermi('system:role:list')") + @SaCheckPermission("system:role:list") @GetMapping("/authUser/unallocatedList") public TableDataInfo unallocatedList(SysUser user, PageQuery pageQuery) { return userService.selectUnallocatedList(user, pageQuery); @@ -185,7 +184,7 @@ public class SysRoleController extends BaseController { * 取消授权用户 */ @ApiOperation("取消授权用户") - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.GRANT) @PutMapping("/authUser/cancel") public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) { @@ -200,7 +199,7 @@ public class SysRoleController extends BaseController { @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query", dataTypeClass = String.class), @ApiImplicitParam(name = "userIds", value = "用户ID串", paramType = "query", dataTypeClass = String.class) }) - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.GRANT) @PutMapping("/authUser/cancelAll") public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) { @@ -215,7 +214,7 @@ public class SysRoleController extends BaseController { @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query", dataTypeClass = String.class), @ApiImplicitParam(name = "userIds", value = "用户ID串", paramType = "query", dataTypeClass = String.class) }) - @PreAuthorize("@ss.hasPermi('system:role:edit')") + @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.GRANT) @PutMapping("/authUser/selectAll") public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 5471baa68..c80bf802c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; @@ -26,7 +27,6 @@ import com.ruoyi.system.service.ISysUserService; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -58,7 +58,7 @@ public class SysUserController extends BaseController { * 获取用户列表 */ @ApiOperation("获取用户列表") - @PreAuthorize("@ss.hasPermi('system:user:list')") + @SaCheckPermission("system:user:list") @GetMapping("/list") public TableDataInfo list(SysUser user, PageQuery pageQuery) { return userService.selectPageUserList(user, pageQuery); @@ -66,7 +66,7 @@ public class SysUserController extends BaseController { @ApiOperation("导出用户列表") @Log(title = "用户管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:user:export')") + @SaCheckPermission("system:user:export") @PostMapping("/export") public void export(SysUser user, HttpServletResponse response) { List list = userService.selectUserList(user); @@ -87,7 +87,7 @@ public class SysUserController extends BaseController { @ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true), }) @Log(title = "用户管理", businessType = BusinessType.IMPORT) - @PreAuthorize("@ss.hasPermi('system:user:import')") + @SaCheckPermission("system:user:import") @PostMapping("/importData") public AjaxResult importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { ExcelResult result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); @@ -104,10 +104,10 @@ public class SysUserController extends BaseController { * 根据用户编号获取详细信息 */ @ApiOperation("根据用户编号获取详细信息") - @PreAuthorize("@ss.hasPermi('system:user:query')") - @GetMapping(value = {"/", "/{userId}"}) + @SaCheckPermission("system:user:query") + @GetMapping(value = {"/", "/{userId}" }) public AjaxResult> getInfo(@ApiParam("用户ID") @PathVariable(value = "userId", required = false) Long userId) { - userService.checkUserDataScope(userId); + userService.checkUserDataScope(userId); Map ajax = new HashMap<>(); List roles = roleService.selectRoleAll(); ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); @@ -125,7 +125,7 @@ public class SysUserController extends BaseController { * 新增用户 */ @ApiOperation("新增用户") - @PreAuthorize("@ss.hasPermi('system:user:add')") + @SaCheckPermission("system:user:add") @Log(title = "用户管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysUser user) { @@ -146,7 +146,7 @@ public class SysUserController extends BaseController { * 修改用户 */ @ApiOperation("修改用户") - @PreAuthorize("@ss.hasPermi('system:user:edit')") + @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysUser user) { @@ -165,7 +165,7 @@ public class SysUserController extends BaseController { * 删除用户 */ @ApiOperation("删除用户") - @PreAuthorize("@ss.hasPermi('system:user:remove')") + @SaCheckPermission("system:user:remove") @Log(title = "用户管理", businessType = BusinessType.DELETE) @DeleteMapping("/{userIds}") public AjaxResult remove(@ApiParam("角色ID串") @PathVariable Long[] userIds) { @@ -179,7 +179,7 @@ public class SysUserController extends BaseController { * 重置密码 */ @ApiOperation("重置密码") - @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @SaCheckPermission("system:user:resetPwd") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping("/resetPwd") public AjaxResult resetPwd(@RequestBody SysUser user) { @@ -192,7 +192,7 @@ public class SysUserController extends BaseController { * 状态修改 */ @ApiOperation("状态修改") - @PreAuthorize("@ss.hasPermi('system:user:edit')") + @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public AjaxResult changeStatus(@RequestBody SysUser user) { @@ -204,7 +204,7 @@ public class SysUserController extends BaseController { * 根据用户编号获取授权角色 */ @ApiOperation("根据用户编号获取授权角色") - @PreAuthorize("@ss.hasPermi('system:user:query')") + @SaCheckPermission("system:user:query") @GetMapping("/authRole/{userId}") public AjaxResult> authRole(@ApiParam("用户ID") @PathVariable("userId") Long userId) { SysUser user = userService.selectUserById(userId); @@ -223,7 +223,7 @@ public class SysUserController extends BaseController { @ApiImplicitParam(name = "userId", value = "用户Id", paramType = "query", dataTypeClass = String.class), @ApiImplicitParam(name = "roleIds", value = "角色ID串", paramType = "query", dataTypeClass = String.class) }) - @PreAuthorize("@ss.hasPermi('system:user:edit')") + @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.GRANT) @PutMapping("/authRole") public AjaxResult insertAuthRole(Long userId, Long[] roleIds) { diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index ed9f1d294..ab692f056 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -95,24 +95,46 @@ spring: # 允许对象忽略json中不存在的属性 fail_on_unknown_properties: false -# token配置 -token: - # 令牌自定义标识 - header: Authorization - # 令牌密钥 - secret: abcdefghijklmnopqrstuvwxyz - # 令牌有效期(默认30分钟) - expireTime: 30 +# Sa-Token配置 +sa-token: + # token名称 (同时也是cookie名称) + token-name: Authorization + # token有效期 设为一天 (必定过期) 单位: 秒 + timeout: 86400 + # token临时有效期 (指定时间无操作就过期) 单位: 秒 + activity-timeout: 1800 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: false + # 是否尝试从请求体里读取token + is-read-body: false + # 是否尝试从header里读取token + is-read-head: true + # 是否尝试从cookie里读取token + is-read-cookie: false + # token前缀 + token-prefix: "Bearer" + # token风格 + token-style: uuid + # jwt秘钥 + jwt-secret-key: abcdefghijklmnopqrstuvwxyz + # 是否输出操作日志 + is-log: true # security配置 security: - # 登出路径 - logout-url: /logout - # 匿名路径 - anonymous: + # 排除路径 + excludes: - /login + - /logout - /register - /captchaImage + # 静态资源 + - /*.html + - /**/*.html + - /**/*.css + - /**/*.js # swagger 文档配置 - /doc.html - /swagger-resources/** diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index a91b5b4f4..91a741a4b 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -29,10 +29,20 @@ spring-web - + - org.springframework.boot - spring-boot-starter-security + cn.dev33 + sa-token-spring-boot-starter + + + + cn.dev33 + sa-token-jwt + + + + org.springframework.security + spring-security-crypto diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 617567d0b..5e07c96c0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -1,6 +1,5 @@ package com.ruoyi.common.constant; - /** * 通用常量信息 * @@ -66,7 +65,12 @@ public interface Constants { /** * 登录用户 redis key */ - String LOGIN_TOKEN_KEY = "login_tokens:"; + public static final String LOGIN_TOKEN_KEY = "Authorization:login:token:"; + + /** + * 在线用户 redis key + */ + public static final String ONLINE_TOKEN_KEY = "online_tokens:"; /** * 防重提交 redis key @@ -103,41 +107,11 @@ public interface Constants { */ String TOKEN = "token"; - /** - * 令牌前缀 - */ - String TOKEN_PREFIX = "Bearer "; - /** * 令牌前缀 */ String LOGIN_USER_KEY = "login_user_key"; - /** - * 用户ID - */ - String JWT_USERID = "userid"; - - /** - * 用户名称 - */ - String JWT_USERNAME = "sub"; - - /** - * 用户头像 - */ - String JWT_AVATAR = "avatar"; - - /** - * 创建时间 - */ - String JWT_CREATED = "created"; - - /** - * 用户权限 - */ - String JWT_AUTHORITIES = "authorities"; - /** * 参数管理 cache key */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java index bad8f77a5..4c5e1977c 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java @@ -2,7 +2,7 @@ package com.ruoyi.common.core.controller; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.StringUtils; /** @@ -71,27 +71,27 @@ public class BaseController { * 获取用户缓存信息 */ public LoginUser getLoginUser() { - return SecurityUtils.getLoginUser(); + return LoginUtils.getLoginUser(); } /** * 获取登录用户id */ public Long getUserId() { - return getLoginUser().getUserId(); + return LoginUtils.getUserId(); } /** * 获取登录部门id */ public Long getDeptId() { - return getLoginUser().getDeptId(); + return LoginUtils.getDeptId(); } /** * 获取登录用户名 */ public String getUsername() { - return getLoginUser().getUsername(); + return LoginUtils.getUsername(); } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java new file mode 100644 index 000000000..5eb52806c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java @@ -0,0 +1,62 @@ +package com.ruoyi.common.core.domain.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * 当前在线会话 + * + * @author ruoyi + */ + +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class UserOnlineDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 会话编号 + */ + private String tokenId; + + /** + * 部门名称 + */ + private String deptName; + + /** + * 用户名称 + */ + private String userName; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地址 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 登录时间 + */ + private Long loginTime; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java index 0506883b2..7554e3f4b 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java @@ -1,13 +1,10 @@ package com.ruoyi.common.core.domain.model; -import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import java.util.Collection; +import java.io.Serializable; import java.util.Set; /** @@ -19,7 +16,7 @@ import java.util.Set; @Data @NoArgsConstructor @Accessors(chain = true) -public class LoginUser implements UserDetails { +public class LoginUser implements Serializable { private static final long serialVersionUID = 1L; @@ -71,72 +68,16 @@ public class LoginUser implements UserDetails { /** * 菜单权限 */ - private Set menuPermissions; + private Set menuPermission; /** * 角色权限 */ - private Set rolePermissions; + private Set rolePermission; /** * 用户名 */ private String username; - /** - * 密码 - */ - private String password; - - @JsonIgnore - @Override - public String getPassword() { - return password; - } - - @Override - public String getUsername() { - return username; - } - - /** - * 账户是否未过期,过期无法验证 - */ - @JsonIgnore - @Override - public boolean isAccountNonExpired() { - return true; - } - - /** - * 指定用户是否解锁,锁定的用户无法进行身份验证 - */ - @JsonIgnore - @Override - public boolean isAccountNonLocked() { - return true; - } - - /** - * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 - */ - @JsonIgnore - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - /** - * 是否可用 ,禁用的用户不能身份验证 - */ - @JsonIgnore - @Override - public boolean isEnabled() { - return true; - } - - @Override - public Collection getAuthorities() { - return null; - } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/TokenService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/TokenService.java deleted file mode 100644 index d9a9f0acf..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/TokenService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.common.core.service; - -import com.ruoyi.common.core.domain.model.LoginUser; - -import javax.servlet.http.HttpServletRequest; - -/** - * token验证处理 - * - * @author Lion Li - */ -public interface TokenService { - - /** - * 获取用户身份信息 - * - * @return 用户信息 - */ - LoginUser getLoginUser(HttpServletRequest request); - - /** - * 设置用户身份信息 - */ - void setLoginUser(LoginUser loginUser); - - /** - * 删除用户身份信息 - */ - void delLoginUser(String token); - - /** - * 创建令牌 - * - * @param loginUser 用户信息 - * @return 令牌 - */ - String createToken(LoginUser loginUser); - - /** - * 验证令牌有效期,相差不足20分钟,自动刷新缓存 - * - * @param loginUser - * @return 令牌 - */ - void verifyToken(LoginUser loginUser); - - /** - * 刷新令牌有效期 - * - * @param loginUser 登录信息 - */ - void refreshToken(LoginUser loginUser); - - /** - * 设置用户代理信息 - * - * @param loginUser 登录信息 - */ - void setUserAgent(LoginUser loginUser); - - /** - * 从令牌中获取用户名 - * - * @param token 令牌 - * @return 用户名 - */ - String getUsernameFromToken(String token); - -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DeviceType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DeviceType.java new file mode 100644 index 000000000..e6ac849df --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DeviceType.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 设备类型 + * 针对一套 用户体系 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum DeviceType { + + /** + * pc端 + */ + PC("pc"), + + /** + * app端 + */ + APP("app"); + + private final String device; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserType.java new file mode 100644 index 000000000..9c3b53195 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/UserType.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 设备类型 + * 针对两套 用户体系 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum UserType { + + /** + * pc端 + */ + SYS_USER("sys_user:"), + + /** + * app端 + */ + APP_USER("app_user:"); + + private final String userType; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/properties/TokenProperties.java b/ruoyi-common/src/main/java/com/ruoyi/common/properties/TokenProperties.java deleted file mode 100644 index 927a9413d..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/properties/TokenProperties.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.ruoyi.common.properties; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -/** - * token 配置属性 - * - * @author Lion Li - */ -@Data -@Component -@ConfigurationProperties(prefix = "token") -public class TokenProperties { - - /** - * 令牌自定义标识 - */ - private String header; - - /** - * 令牌秘钥 - */ - private String secret; - - /** - * 令牌有效期(默认30分钟) - */ - private int expireTime; -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/LoginUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/LoginUtils.java new file mode 100644 index 000000000..a5dc50eb1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/LoginUtils.java @@ -0,0 +1,107 @@ +package com.ruoyi.common.utils; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.ObjectUtil; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.DeviceType; +import com.ruoyi.common.enums.UserType; +import com.ruoyi.common.exception.UtilException; + +/** + * 登录鉴权工具 + * 为适配多端登录而封装 + * + * @author Lion Li + */ +public class LoginUtils { + + private final static String LOGIN_USER_KEY = "loginUser"; + + /** + * 登录系统 + * 针对两套用户体系 + * @param loginUser 登录用户信息 + */ + public static void login(LoginUser loginUser, UserType userType) { + StpUtil.login(userType.getUserType() + loginUser.getUserId()); + setLoginUser(loginUser); + } + + /** + * 登录系统 基于 设备类型 + * 针对一套用户体系 + * @param loginUser 登录用户信息 + */ + public static void loginByDevice(LoginUser loginUser, UserType userType, DeviceType deviceType) { + StpUtil.login(userType.getUserType() + loginUser.getUserId(), deviceType.getDevice()); + setLoginUser(loginUser); + } + + /** + * 设置用户数据 + */ + public static void setLoginUser(LoginUser loginUser) { + StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); + } + + /** + * 获取用户 + **/ + public static LoginUser getLoginUser() { + return (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY); + } + + /** + * 获取用户id + */ + public static Long getUserId() { + LoginUser loginUser = getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + String loginId = StpUtil.getLoginIdAsString(); + String userId; + String replace = ""; + if (StringUtils.contains(loginId, UserType.SYS_USER.getUserType())) { + userId = StringUtils.replace(loginId, UserType.SYS_USER.getUserType(), replace); + } else if (StringUtils.contains(loginId, UserType.APP_USER.getUserType())){ + userId = StringUtils.replace(loginId, UserType.APP_USER.getUserType(), replace); + } else { + throw new UtilException("登录用户: LoginId异常 => " + loginId); + } + return Long.parseLong(userId); + } + return loginUser.getUserId(); + } + + /** + * 获取部门ID + **/ + public static Long getDeptId() { + return getLoginUser().getDeptId(); + } + + /** + * 获取用户账户 + **/ + public static String getUsername() { + return getLoginUser().getUsername(); + } + + /** + * 获取用户类型 + */ + public static UserType getUserType() { + String loginId = StpUtil.getLoginIdAsString(); + return getUserType(loginId); + } + + public static UserType getUserType(Object loginId) { + if (StringUtils.contains(loginId.toString(), UserType.SYS_USER.getUserType())) { + return UserType.SYS_USER; + } else if (StringUtils.contains(loginId.toString(), UserType.APP_USER.getUserType())){ + return UserType.APP_USER; + } else { + throw new UtilException("登录用户: LoginId异常 => " + loginId); + } + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java index 43cb8fe17..72c9453c0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java @@ -1,73 +1,17 @@ package com.ruoyi.common.utils; -import cn.hutool.http.HttpStatus; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.exception.ServiceException; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * 安全服务工具类 * - * @author ruoyi + * @author Long Li */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class SecurityUtils { - /** - * 用户ID - **/ - public static Long getUserId() { - try { - return getLoginUser().getUserId(); - } catch (Exception e) { - throw new ServiceException("获取用户ID异常", HttpStatus.HTTP_UNAUTHORIZED); - } - } - - /** - * 获取部门ID - **/ - public static Long getDeptId() { - try { - return getLoginUser().getDeptId(); - } catch (Exception e) { - throw new ServiceException("获取部门ID异常", HttpStatus.HTTP_UNAUTHORIZED); - } - } - - /** - * 获取用户账户 - **/ - public static String getUsername() { - try { - return getLoginUser().getUsername(); - } catch (Exception e) { - throw new ServiceException("获取用户账户异常", HttpStatus.HTTP_UNAUTHORIZED); - } - } - - /** - * 获取用户 - **/ - public static LoginUser getLoginUser() { - try { - return (LoginUser) getAuthentication().getPrincipal(); - } catch (Exception e) { - throw new ServiceException("获取用户信息异常", HttpStatus.HTTP_UNAUTHORIZED); - } - } - - /** - * 获取Authentication - */ - public static Authentication getAuthentication() { - return SecurityContextHolder.getContext().getAuthentication(); - } - /** * 生成BCryptPasswordEncoder密码 * diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java index 003d7dc45..9a8cf63c8 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java @@ -1,5 +1,6 @@ package com.ruoyi.demo.controller; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; @@ -22,7 +23,6 @@ import com.ruoyi.demo.service.ITestDemoService; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -53,28 +53,28 @@ public class TestDemoController extends BaseController { * 查询测试单表列表 */ @ApiOperation("查询测试单表列表") - @PreAuthorize("@ss.hasPermi('demo:demo:list')") + @SaCheckPermission("demo:demo:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { return iTestDemoService.queryPageList(bo, pageQuery); } - /** - * 自定义分页查询 - */ - @ApiOperation("自定义分页查询") - @PreAuthorize("@ss.hasPermi('demo:demo:list')") - @GetMapping("/page") - public TableDataInfo page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { - return iTestDemoService.customPageList(bo, pageQuery); - } + /** + * 自定义分页查询 + */ + @ApiOperation("自定义分页查询") + @SaCheckPermission("demo:demo:list") + @GetMapping("/page") + public TableDataInfo page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { + return iTestDemoService.customPageList(bo, pageQuery); + } @ApiOperation("导入测试-校验") @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true), }) @Log(title = "测试单表", businessType = BusinessType.IMPORT) - @PreAuthorize("@ss.hasPermi('demo:demo:import')") + @SaCheckPermission("demo:demo:import") @PostMapping("/importData") public AjaxResult importData(@RequestPart("file") MultipartFile file) throws Exception { ExcelResult excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true); @@ -88,7 +88,7 @@ public class TestDemoController extends BaseController { * 导出测试单表列表 */ @ApiOperation("导出测试单表列表") - @PreAuthorize("@ss.hasPermi('demo:demo:export')") + @SaCheckPermission("demo:demo:export") @Log(title = "测试单表", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(@Validated TestDemoBo bo, HttpServletResponse response) { @@ -104,7 +104,7 @@ public class TestDemoController extends BaseController { * 获取测试单表详细信息 */ @ApiOperation("获取测试单表详细信息") - @PreAuthorize("@ss.hasPermi('demo:demo:query')") + @SaCheckPermission("demo:demo:query") @GetMapping("/{id}") public AjaxResult getInfo(@ApiParam("测试ID") @NotNull(message = "主键不能为空") @@ -116,7 +116,7 @@ public class TestDemoController extends BaseController { * 新增测试单表 */ @ApiOperation("新增测试单表") - @PreAuthorize("@ss.hasPermi('demo:demo:add')") + @SaCheckPermission("demo:demo:add") @Log(title = "测试单表", businessType = BusinessType.INSERT) @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交") @PostMapping() @@ -131,7 +131,7 @@ public class TestDemoController extends BaseController { * 修改测试单表 */ @ApiOperation("修改测试单表") - @PreAuthorize("@ss.hasPermi('demo:demo:edit')") + @SaCheckPermission("demo:demo:edit") @Log(title = "测试单表", businessType = BusinessType.UPDATE) @RepeatSubmit @PutMapping() @@ -143,8 +143,8 @@ public class TestDemoController extends BaseController { * 删除测试单表 */ @ApiOperation("删除测试单表") - @PreAuthorize("@ss.hasPermi('demo:demo:remove')") - @Log(title = "测试单表", businessType = BusinessType.DELETE) + @SaCheckPermission("demo:demo:remove") + @Log(title = "测试单表" , businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult remove(@ApiParam("测试ID串") @NotEmpty(message = "主键不能为空") diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java index 463ea3bf6..f0231bb2c 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java @@ -1,5 +1,6 @@ package com.ruoyi.demo.controller; +import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; @@ -17,7 +18,6 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -46,7 +46,7 @@ public class TestTreeController extends BaseController { * 查询测试树表列表 */ @ApiOperation("查询测试树表列表") - @PreAuthorize("@ss.hasPermi('demo:tree:list')") + @SaCheckPermission("demo:tree:list") @GetMapping("/list") public AjaxResult> list(@Validated(QueryGroup.class) TestTreeBo bo) { List list = iTestTreeService.queryList(bo); @@ -57,7 +57,7 @@ public class TestTreeController extends BaseController { * 导出测试树表列表 */ @ApiOperation("导出测试树表列表") - @PreAuthorize("@ss.hasPermi('demo:tree:export')") + @SaCheckPermission("demo:tree:export") @Log(title = "测试树表", businessType = BusinessType.EXPORT) @GetMapping("/export") public void export(@Validated TestTreeBo bo, HttpServletResponse response) { @@ -69,7 +69,7 @@ public class TestTreeController extends BaseController { * 获取测试树表详细信息 */ @ApiOperation("获取测试树表详细信息") - @PreAuthorize("@ss.hasPermi('demo:tree:query')") + @SaCheckPermission("demo:tree:query") @GetMapping("/{id}") public AjaxResult getInfo(@ApiParam("测试树ID") @NotNull(message = "主键不能为空") @@ -81,7 +81,7 @@ public class TestTreeController extends BaseController { * 新增测试树表 */ @ApiOperation("新增测试树表") - @PreAuthorize("@ss.hasPermi('demo:tree:add')") + @SaCheckPermission("demo:tree:add") @Log(title = "测试树表", businessType = BusinessType.INSERT) @RepeatSubmit @PostMapping() @@ -93,7 +93,7 @@ public class TestTreeController extends BaseController { * 修改测试树表 */ @ApiOperation("修改测试树表") - @PreAuthorize("@ss.hasPermi('demo:tree:edit')") + @SaCheckPermission("demo:tree:edit") @Log(title = "测试树表", businessType = BusinessType.UPDATE) @RepeatSubmit @PutMapping() @@ -105,8 +105,8 @@ public class TestTreeController extends BaseController { * 删除测试树表 */ @ApiOperation("删除测试树表") - @PreAuthorize("@ss.hasPermi('demo:tree:remove')") - @Log(title = "测试树表", businessType = BusinessType.DELETE) + @SaCheckPermission("demo:tree:remove") + @Log(title = "测试树表" , businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult remove(@ApiParam("测试树ID串") @NotEmpty(message = "主键不能为空") diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java new file mode 100644 index 000000000..58427da66 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,138 @@ +package com.ruoyi.framework.aspectj; + +import com.ruoyi.common.annotation.DataScope; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.service.UserService; +import com.ruoyi.common.utils.LoginUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; + +/** + * 数据过滤处理 + * + * @author Lion Li + * @deprecated 3.6.0 移除 {@link com.ruoyi.framework.handler.PlusDataPermissionHandler} + */ +@Aspect +@Component +@Deprecated +public class DataScopeAspect { + + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) { + // 获取当前的用户 + SysUser currentUser = SpringUtils.getBean(UserService.class).selectUserById(LoginUtils.getUserId()); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) { + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), controllerDataScope.isUser()); + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param userAlias 别名 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, boolean isUser) { + StringBuilder sqlString = new StringBuilder(); + + // 将 "." 提取出,不写别名为单表查询,写别名为多表查询 + deptAlias = StringUtils.isNotBlank(deptAlias) ? deptAlias + "." : ""; + userAlias = StringUtils.isNotBlank(userAlias) ? userAlias + "." : ""; + + for (SysRole role : user.getRoles()) { + String dataScope = role.getDataScope(); + if (DATA_SCOPE_ALL.equals(dataScope)) { + sqlString = new StringBuilder(); + break; + } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) { + sqlString.append(StringUtils.format( + " OR {}dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", + deptAlias, role.getRoleId())); + } else if (DATA_SCOPE_DEPT.equals(dataScope)) { + sqlString.append(StringUtils.format(" OR {}dept_id = {} ", + deptAlias, user.getDeptId())); + } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) { + sqlString.append(StringUtils.format( + " OR {}dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", + deptAlias, user.getDeptId(), user.getDeptId())); + } else if (DATA_SCOPE_SELF.equals(dataScope)) { + if (isUser) { + sqlString.append(StringUtils.format(" OR {}user_id = {} ", + userAlias, user.getUserId())); + } else { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(" OR 1=0 "); + } + } + } + + if (StringUtils.isNotBlank(sqlString.toString())) { + putDataScope(joinPoint, sqlString.substring(4)); + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params)) { + putDataScope(joinPoint, ""); + } + } + + private static void putDataScope(JoinPoint joinPoint, String sql) { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params)) { + if (params instanceof BaseEntity) { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, sql); + } + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index 642076d9e..e7aa90996 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -2,12 +2,11 @@ package com.ruoyi.framework.aspectj; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.dto.OperLogDTO; -import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.service.OperLogService; import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.utils.JsonUtils; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; @@ -60,9 +59,6 @@ public class LogAspect { protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { try { - // 获取当前的用户 - LoginUser loginUser = SecurityUtils.getLoginUser(); - // *========数据库日志=========*// OperLogDTO operLog = new OperLogDTO(); operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); @@ -70,9 +66,7 @@ public class LogAspect { String ip = ServletUtils.getClientIP(); operLog.setOperIp(ip); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); - if (loginUser != null) { - operLog.setOperName(loginUser.getUsername()); - } + operLog.setOperName(LoginUtils.getUsername()); if (e != null) { operLog.setStatus(BusinessStatus.FAIL.ordinal()); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java index 48761ac29..9fa586b41 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java @@ -1,10 +1,10 @@ package com.ruoyi.framework.aspectj; +import cn.dev33.satoken.SaManager; import cn.hutool.crypto.SecureUtil; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.properties.TokenProperties; import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.redis.RedisUtils; import com.ruoyi.common.utils.ServletUtils; @@ -37,7 +37,6 @@ import java.util.concurrent.TimeUnit; @Component public class RepeatSubmitAspect { - private final TokenProperties tokenProperties; private final RepeatSubmitProperties repeatSubmitProperties; @Before("@annotation(repeatSubmit)") @@ -57,7 +56,7 @@ public class RepeatSubmitAspect { String url = request.getRequestURI(); // 唯一值(没有消息头则使用请求地址) - String submitKey = StringUtils.trimToEmpty(request.getHeader(tokenProperties.getHeader())); + String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName())); submitKey = SecureUtil.md5(submitKey + ":" + nowParams); // 唯一标识(指定key + url + 消息头) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java deleted file mode 100644 index 728773d94..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ruoyi.framework.config; - -import cn.hutool.core.util.ArrayUtil; -import com.ruoyi.common.exception.ServiceException; -import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.AsyncConfigurerSupport; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService; - -import java.util.Arrays; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; - -/** - * 异步配置 - * - * @author Lion Li - */ -@EnableAsync -@Configuration -public class AsyncConfig extends AsyncConfigurerSupport { - - @Autowired - @Qualifier("scheduledExecutorService") - private ScheduledExecutorService scheduledExecutorService; - - /** - * 异步执行需要使用权限框架自带的包装线程池 保证权限信息的传递 - */ - @Override - public Executor getAsyncExecutor() { - return new DelegatingSecurityContextExecutorService(scheduledExecutorService); - } - - /** - * 异步执行异常处理 - */ - @Override - public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { - return (throwable, method, objects) -> { - throwable.printStackTrace(); - StringBuilder sb = new StringBuilder(); - sb.append("Exception message - ").append(throwable.getMessage()) - .append(", Method name - ").append(method.getName()); - if (ArrayUtil.isNotEmpty(objects)) { - sb.append(", Parameter value - ").append(Arrays.toString(objects)); - } - throw new ServiceException(sb.toString()); - }; - } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java index 83565b6ec..f43ecab7d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -19,10 +19,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class ResourcesConfig implements WebMvcConfigurer { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - } - @Override public void addInterceptors(InterceptorRegistry registry) { // 全局链路跟踪拦截器 @@ -31,6 +27,10 @@ public class ResourcesConfig implements WebMvcConfigurer { registry.addInterceptor(new PlusWebInvokeTimeInterceptor()); } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + } + /** * 跨域配置 */ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java new file mode 100644 index 000000000..260424545 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java @@ -0,0 +1,63 @@ +package com.ruoyi.framework.config; + +import cn.dev33.satoken.interceptor.SaAnnotationInterceptor; +import cn.dev33.satoken.interceptor.SaRouteInterceptor; +import cn.dev33.satoken.jwt.StpLogicJwtForStyle; +import cn.dev33.satoken.router.SaRouter; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.stp.StpUtil; +import com.ruoyi.common.utils.LoginUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.config.properties.SecurityProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * sa-token 配置 + * + * @author Lion Li + */ +@Slf4j +@Configuration +public class SaTokenConfig implements WebMvcConfigurer { + + @Autowired + private SecurityProperties securityProperties; + + /** + * 注册sa-token的拦截器 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + // 注册路由拦截器,自定义验证规则 + registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> { + // 登录验证 -- 排除多个路径 + SaRouter + // 获取所有的 + .match("/**") + // 排除下不需要拦截的 + .notMatch(securityProperties.getExcludes()) + .check(() -> { + if (log.isDebugEnabled()) { + Long userId = LoginUtils.getUserId(); + if (StringUtils.isNotNull(userId)) { + log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout()); + log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout()); + } + } + }); + })).addPathPatterns("/**"); + registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**"); + } + + @Bean + public StpLogic getStpLogicJwt() { + // Sa-Token 整合 jwt (Style模式) + return new StpLogicJwtForStyle(); + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java deleted file mode 100644 index 450eccd45..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.ruoyi.framework.config; - -import com.ruoyi.framework.config.properties.SecurityProperties; -import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; -import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; -import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.authentication.logout.LogoutFilter; -import org.springframework.web.filter.CorsFilter; - -/** - * spring security配置 - * - * @author ruoyi - */ -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) -public class SecurityConfig extends WebSecurityConfigurerAdapter { - /** - * 自定义用户认证逻辑 - */ - @Autowired - private UserDetailsService userDetailsService; - - /** - * 认证失败处理类 - */ - @Autowired - private AuthenticationEntryPointImpl unauthorizedHandler; - - /** - * 退出处理类 - */ - @Autowired - private LogoutSuccessHandlerImpl logoutSuccessHandler; - - /** - * token认证过滤器 - */ - @Autowired - private JwtAuthenticationTokenFilter authenticationTokenFilter; - - /** - * 跨域过滤器 - */ - @Autowired - private CorsFilter corsFilter; - - @Autowired - private SecurityProperties securityProperties; - - /** - * 解决 无法直接注入 AuthenticationManager - * - * @return - * @throws Exception - */ - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - /** - * anyRequest | 匹配所有请求路径 - * access | SpringEl表达式结果为true时可以访问 - * anonymous | 匿名可以访问 - * denyAll | 用户不能访问 - * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) - * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 - * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 - * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 - * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 - * hasRole | 如果有参数,参数表示角色,则其角色可以访问 - * permitAll | 用户可以任意访问 - * rememberMe | 允许通过remember-me登录的用户访问 - * authenticated | 用户登录后可访问 - */ - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - httpSecurity - // CSRF禁用,因为不使用session - .csrf().disable() - // 认证失败处理类 - .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() - // 基于token,所以不需要session - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() - // 过滤请求 - .authorizeRequests() - .antMatchers( - HttpMethod.GET, - "/", - "/*.html", - "/**/*.html", - "/**/*.css", - "/**/*.js" - ).permitAll() - .antMatchers(securityProperties.getAnonymous()).anonymous() - .antMatchers(securityProperties.getPermitAll()).permitAll() - // 除上面外的所有请求全部需要鉴权认证 - .anyRequest().authenticated() - .and() - .headers().frameOptions().disable(); - httpSecurity.logout().logoutUrl(securityProperties.getLogoutUrl()).logoutSuccessHandler(logoutSuccessHandler); - // 添加JWT filter - httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); - // 添加CORS filter - httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); - httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); - } - - /** - * 强散列哈希加密实现 - */ - @Bean - public BCryptPasswordEncoder bCryptPasswordEncoder() { - return new BCryptPasswordEncoder(); - } - - /** - * 身份认证接口 - */ - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java index 16437f44f..167ac2ec1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -1,8 +1,8 @@ package com.ruoyi.framework.config; +import cn.dev33.satoken.config.SaTokenConfig; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; -import com.ruoyi.common.properties.TokenProperties; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.config.properties.SwaggerProperties; @@ -40,7 +40,7 @@ import java.util.List; public class SwaggerConfig { private final SwaggerProperties swaggerProperties; - private final TokenProperties tokenProperties; + private final SaTokenConfig saTokenConfig; private final OpenApiExtensionResolver openApiExtensionResolver; /** @@ -110,7 +110,7 @@ public class SwaggerConfig { */ private List securitySchemes() { List apiKeyList = new ArrayList(); - String header = tokenProperties.getHeader(); + String header = saTokenConfig.getTokenName(); apiKeyList.add(new ApiKey(header, header, In.HEADER.toValue())); return apiKeyList; } @@ -136,7 +136,7 @@ public class SwaggerConfig { AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; List securityReferences = new ArrayList<>(); - securityReferences.add(new SecurityReference(tokenProperties.getHeader(), authorizationScopes)); + securityReferences.add(new SecurityReference(saTokenConfig.getTokenName(), authorizationScopes)); return securityReferences; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java index c83ffccbe..b37418181 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java @@ -15,18 +15,9 @@ import org.springframework.stereotype.Component; public class SecurityProperties { /** - * 退出登录url + * 排除路径 */ - private String logoutUrl; + private String[] excludes; - /** - * 匿名放行路径 - */ - private String[] anonymous; - - /** - * 用户任意访问放行路径 - */ - private String[] permitAll; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/CreateAndUpdateMetaObjectHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/CreateAndUpdateMetaObjectHandler.java index 4c4f36c6b..87781eb59 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/CreateAndUpdateMetaObjectHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/CreateAndUpdateMetaObjectHandler.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; @@ -72,18 +72,18 @@ public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler { } } - /** - * 获取登录用户名 - */ - private String getLoginUsername() { - LoginUser loginUser; - try { - loginUser = SecurityUtils.getLoginUser(); - } catch (Exception e) { - log.warn("自动注入警告 => 用户未登录"); - return null; - } - return loginUser.getUsername(); - } + /** + * 获取登录用户名 + */ + private String getLoginUsername() { + LoginUser loginUser; + try { + loginUser = LoginUtils.getLoginUser(); + } catch (Exception e) { + log.warn("自动注入警告 => 用户未登录"); + return null; + } + return loginUser.getUsername(); + } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java index d5f4f5832..2318f6f4e 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/PlusDataPermissionHandler.java @@ -13,7 +13,7 @@ import com.ruoyi.common.core.service.UserService; import com.ruoyi.common.enums.DataScopeType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.helper.DataPermissionHelper; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; import lombok.extern.slf4j.Slf4j; @@ -76,7 +76,7 @@ public class PlusDataPermissionHandler { } SysUser currentUser = DataPermissionHelper.getVariable("user"); if (ObjectUtil.isNull(currentUser)) { - currentUser = SpringUtils.getBean(UserService.class).selectUserById(SecurityUtils.getUserId()); + currentUser = SpringUtils.getBean(UserService.class).selectUserById(LoginUtils.getUserId()); DataPermissionHelper.setVariable("user", currentUser); } // 如果是超级管理员,则不过滤数据 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java new file mode 100644 index 000000000..95837fe49 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java @@ -0,0 +1,121 @@ +package com.ruoyi.framework.listener; + +import cn.dev33.satoken.config.SaTokenConfig; +import cn.dev33.satoken.listener.SaTokenListener; +import cn.dev33.satoken.stp.SaLoginModel; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.dto.UserOnlineDTO; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.service.UserService; +import com.ruoyi.common.enums.UserType; +import com.ruoyi.common.utils.LoginUtils; +import com.ruoyi.common.utils.RedisUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * 用户行为 侦听器的实现 + */ +@Component +@Slf4j +public class UserActionListener implements SaTokenListener { + + @Autowired + private SaTokenConfig saTokenConfig; + + /** + * 每次登录时触发 + */ + @Override + public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) { + UserType userType = LoginUtils.getUserType(loginId); + if (userType == UserType.SYS_USER) { + UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = ServletUtils.getClientIP(); + SysUser user = SpringUtils.getBean(UserService.class).selectUserById(LoginUtils.getUserId()); + String tokenValue = StpUtil.getTokenValue(); + UserOnlineDTO userOnlineDTO = new UserOnlineDTO() + .setIpaddr(ip) + .setLoginLocation(AddressUtils.getRealAddressByIP(ip)) + .setBrowser(userAgent.getBrowser().getName()) + .setOs(userAgent.getOs().getName()) + .setLoginTime(System.currentTimeMillis()) + .setTokenId(tokenValue) + .setUserName(user.getUserName()); + if (StringUtils.isNotNull(user.getDept())) { + userOnlineDTO.setDeptName(user.getDept().getDeptName()); + } + RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, userOnlineDTO, saTokenConfig.getTimeout(), TimeUnit.SECONDS); + log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue); + } else if (userType == UserType.APP_USER) { + // app端 自行根据业务编写 + } + } + + /** + * 每次注销时触发 + */ + @Override + public void doLogout(String loginType, Object loginId, String tokenValue) { + RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue); + log.info("user doLogout, useId:{}, token:{}", loginId, tokenValue); + } + + /** + * 每次被踢下线时触发 + */ + @Override + public void doKickout(String loginType, Object loginId, String tokenValue) { + RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue); + log.info("user doLogoutByLoginId, useId:{}, token:{}", loginId, tokenValue); + } + + /** + * 每次被顶下线时触发 + */ + @Override + public void doReplaced(String loginType, Object loginId, String tokenValue) { + RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue); + log.info("user doReplaced, useId:{}, token:{}", loginId, tokenValue); + } + + /** + * 每次被封禁时触发 + */ + @Override + public void doDisable(String loginType, Object loginId, long disableTime) { + } + + /** + * 每次被解封时触发 + */ + @Override + public void doUntieDisable(String loginType, Object loginId) { + } + + /** + * 每次创建Session时触发 + */ + @Override + public void doCreateSession(String id) { + } + + /** + * 每次注销Session时触发 + */ + @Override + public void doLogoutSession(String id) { + } + + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java new file mode 100644 index 000000000..556133c15 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java @@ -0,0 +1,178 @@ +package com.ruoyi.framework.satoken.dao; + +import cn.dev33.satoken.dao.SaTokenDao; +import cn.dev33.satoken.util.SaFoxUtil; +import com.ruoyi.common.utils.RedisUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一) + * + * @author Lion Li + */ +@Component +public class PlusSaTokenDao implements SaTokenDao { + + /** + * 获取Value,如无返空 + */ + @Override + public String get(String key) { + return RedisUtils.getCacheObject(key); + } + + /** + * 写入Value,并设定存活时间 (单位: 秒) + */ + @Override + public void set(String key, String value, long timeout) { + if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + // 判断是否为永不过期 + if(timeout == SaTokenDao.NEVER_EXPIRE) { + RedisUtils.setCacheObject(key, value); + } else { + RedisUtils.setCacheObject(key, value, timeout, TimeUnit.SECONDS); + } + } + + /** + * 修修改指定key-value键值对 (过期时间不变) + */ + @Override + public void update(String key, String value) { + long expire = getTimeout(key); + // -2 = 无此键 + if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + this.set(key, value, expire); + } + + /** + * 删除Value + */ + @Override + public void delete(String key) { + RedisUtils.deleteObject(key); + } + + /** + * 获取Value的剩余存活时间 (单位: 秒) + */ + @Override + public long getTimeout(String key) { + return RedisUtils.getTimeToLive(key) / 1000; + } + + /** + * 修改Value的剩余存活时间 (单位: 秒) + */ + @Override + public void updateTimeout(String key, long timeout) { + // 判断是否想要设置为永久 + if(timeout == SaTokenDao.NEVER_EXPIRE) { + long expire = getTimeout(key); + if(expire == SaTokenDao.NEVER_EXPIRE) { + // 如果其已经被设置为永久,则不作任何处理 + } else { + // 如果尚未被设置为永久,那么再次set一次 + this.set(key, this.get(key), timeout); + } + return; + } + RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + } + + + + /** + * 获取Object,如无返空 + */ + @Override + public Object getObject(String key) { + return RedisUtils.getCacheObject(key); + } + + /** + * 写入Object,并设定存活时间 (单位: 秒) + */ + @Override + public void setObject(String key, Object object, long timeout) { + if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + // 判断是否为永不过期 + if(timeout == SaTokenDao.NEVER_EXPIRE) { + RedisUtils.setCacheObject(key, object); + } else { + RedisUtils.setCacheObject(key, object, timeout, TimeUnit.SECONDS); + } + } + + /** + * 更新Object (过期时间不变) + */ + @Override + public void updateObject(String key, Object object) { + long expire = getObjectTimeout(key); + // -2 = 无此键 + if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + this.setObject(key, object, expire); + } + + /** + * 删除Object + */ + @Override + public void deleteObject(String key) { + RedisUtils.deleteObject(key); + } + + /** + * 获取Object的剩余存活时间 (单位: 秒) + */ + @Override + public long getObjectTimeout(String key) { + return RedisUtils.getTimeToLive(key) / 1000; + } + + /** + * 修改Object的剩余存活时间 (单位: 秒) + */ + @Override + public void updateObjectTimeout(String key, long timeout) { + // 判断是否想要设置为永久 + if(timeout == SaTokenDao.NEVER_EXPIRE) { + long expire = getObjectTimeout(key); + if(expire == SaTokenDao.NEVER_EXPIRE) { + // 如果其已经被设置为永久,则不作任何处理 + } else { + // 如果尚未被设置为永久,那么再次set一次 + this.setObject(key, this.getObject(key), timeout); + } + return; + } + RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + } + + + /** + * 搜索数据 + */ + @Override + public List searchData(String prefix, String keyword, int start, int size) { + Collection keys = RedisUtils.keys(prefix + "*" + keyword + "*"); + List list = new ArrayList<>(keys); + return SaFoxUtil.searchList(list, start, size); + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/service/SaInterfaceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/service/SaInterfaceImpl.java new file mode 100644 index 000000000..e5bacd342 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/service/SaInterfaceImpl.java @@ -0,0 +1,38 @@ +package com.ruoyi.framework.satoken.service; + +import cn.dev33.satoken.stp.StpInterface; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.UserType; +import com.ruoyi.common.utils.LoginUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class SaInterfaceImpl implements StpInterface { + + @Override + public List getPermissionList(Object loginId, String loginType) { + UserType userType = LoginUtils.getUserType(loginId); + if (userType == UserType.SYS_USER) { + LoginUser loginUser = LoginUtils.getLoginUser(); + return new ArrayList<>(loginUser.getMenuPermission()); + } else if (userType == UserType.APP_USER) { + // app端权限返回 自行根据业务编写 + } + return new ArrayList<>(); + } + + @Override + public List getRoleList(Object loginId, String loginType) { + UserType userType = LoginUtils.getUserType(loginId); + if (userType == UserType.SYS_USER) { + LoginUser loginUser = LoginUtils.getLoginUser(); + return new ArrayList<>(loginUser.getRolePermission()); + } else if (userType == UserType.APP_USER) { + // app端权限返回 自行根据业务编写 + } + return new ArrayList<>(); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java deleted file mode 100644 index 4ebb4aaea..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ruoyi.framework.security.filter; - -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.service.TokenService; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * token过滤器 验证token有效性 - * - * @author ruoyi - */ -@Component -public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { - - @Autowired - private TokenService tokenService; - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - LoginUser loginUser = tokenService.getLoginUser(request); - if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) { - tokenService.verifyToken(loginUser); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); - authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authenticationToken); - } - chain.doFilter(request, response); - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java deleted file mode 100644 index 35b0f921c..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.ruoyi.framework.security.handle; - -import cn.hutool.http.HttpStatus; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.JsonUtils; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.Serializable; - -/** - * 认证失败处理类 返回未授权 - * - * @author ruoyi - */ -@Component -public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable { - private static final long serialVersionUID = -8970718410437077606L; - - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) - throws IOException { - int code = HttpStatus.HTTP_UNAUTHORIZED; - String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); - ServletUtils.renderString(response, JsonUtils.toJsonString(AjaxResult.error(code, msg))); - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java deleted file mode 100644 index 969af512c..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ruoyi.framework.security.handle; - -import cn.hutool.http.HttpStatus; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.service.LogininforService; -import com.ruoyi.common.core.service.TokenService; -import com.ruoyi.common.utils.JsonUtils; -import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 自定义退出处理类 返回成功 - * - * @author ruoyi - */ -@Configuration -public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { - - @Autowired - private TokenService tokenService; - - @Autowired - private LogininforService asyncService; - - /** - * 退出处理 - */ - @Override - public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException { - LoginUser loginUser = tokenService.getLoginUser(request); - String message = MessageUtils.message("user.logout.success"); - if (StringUtils.isNotNull(loginUser)) { - String userName = loginUser.getUsername(); - // 删除用户缓存记录 - tokenService.delLoginUser(loginUser.getToken()); - // 记录用户退出日志 - asyncService.recordLogininfor(userName, Constants.LOGOUT, message, request); - } - ServletUtils.renderString(response, JsonUtils.toJsonString(AjaxResult.error(HttpStatus.HTTP_OK, message))); - } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java index 4c642c2d7..60979dd0e 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -1,13 +1,18 @@ package com.ruoyi.framework.web.exception; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.NotPermissionException; +import cn.dev33.satoken.exception.NotRoleException; +import cn.dev33.satoken.stp.StpUtil; import cn.hutool.http.HttpStatus; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.exception.DemoModeException; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.context.support.DefaultMessageSourceResolvable; -import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.BindException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -31,13 +36,33 @@ public class GlobalExceptionHandler { /** * 权限校验异常 */ - @ExceptionHandler(AccessDeniedException.class) - public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) { + @ExceptionHandler(NotPermissionException.class) + public AjaxResult handleAccessDeniedException(NotPermissionException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); return AjaxResult.error(HttpStatus.HTTP_FORBIDDEN, "没有权限,请联系管理员授权"); } + /** + * 角色校验异常 + */ + @ExceptionHandler(NotRoleException.class) + public AjaxResult handleAccessDeniedException(NotRoleException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',角色校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.HTTP_FORBIDDEN, "没有角色,请联系管理员授权"); + } + + /** + * 认证失败 + */ + @ExceptionHandler(NotLoginException.class) + public AjaxResult handleAccessDeniedException(NotLoginException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.HTTP_UNAUTHORIZED, StringUtils.format("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI)); + } + /** * 请求方式不支持 */ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java deleted file mode 100644 index 0e97b92f0..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.ruoyi.framework.web.service; - -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.Set; - -/** - * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 - * - * @author ruoyi - */ -@Service("ss") -public class PermissionService { - /** - * 所有权限标识 - */ - private static final String ALL_PERMISSION = "*:*:*"; - - /** - * 管理员角色权限标识 - */ - private static final String SUPER_ADMIN = "admin"; - - private static final String ROLE_DELIMETER = ","; - - private static final String PERMISSION_DELIMETER = ","; - - /** - * 验证用户是否具备某权限 - * - * @param permission 权限字符串 - * @return 用户是否具备某权限 - */ - public boolean hasPermi(String permission) { - if (StringUtils.isEmpty(permission)) { - return false; - } - LoginUser loginUser = SecurityUtils.getLoginUser(); - if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getMenuPermissions())) { - return false; - } - return hasPermissions(loginUser.getMenuPermissions(), permission); - } - - /** - * 验证用户是否不具备某权限,与 hasPermi逻辑相反 - * - * @param permission 权限字符串 - * @return 用户是否不具备某权限 - */ - public boolean lacksPermi(String permission) { - return hasPermi(permission) != true; - } - - /** - * 验证用户是否具有以下任意一个权限 - * - * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表 - * @return 用户是否具有以下任意一个权限 - */ - public boolean hasAnyPermi(String permissions) { - if (StringUtils.isEmpty(permissions)) { - return false; - } - LoginUser loginUser = SecurityUtils.getLoginUser(); - if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getMenuPermissions())) { - return false; - } - Set authorities = loginUser.getMenuPermissions(); - for (String permission : permissions.split(PERMISSION_DELIMETER)) { - if (permission != null && hasPermissions(authorities, permission)) { - return true; - } - } - return false; - } - - /** - * 判断用户是否拥有某个角色 - * - * @param role 角色字符串 - * @return 用户是否具备某角色 - */ - public boolean hasRole(String role) { - if (StringUtils.isEmpty(role)) { - return false; - } - LoginUser loginUser = SecurityUtils.getLoginUser(); - if (StringUtils.isNull(loginUser)) { - return false; - } - Set rolePermissions = loginUser.getRolePermissions(); - if (CollectionUtils.isEmpty(rolePermissions)) { - return false; - } - for (String roleKey : rolePermissions) { - if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) { - return true; - } - } - return false; - } - - /** - * 验证用户是否不具备某角色,与 isRole逻辑相反。 - * - * @param role 角色名称 - * @return 用户是否不具备某角色 - */ - public boolean lacksRole(String role) { - return hasRole(role) != true; - } - - /** - * 验证用户是否具有以下任意一个角色 - * - * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 - * @return 用户是否具有以下任意一个角色 - */ - public boolean hasAnyRoles(String roles) { - if (StringUtils.isEmpty(roles)) { - return false; - } - LoginUser loginUser = SecurityUtils.getLoginUser(); - if (StringUtils.isNull(loginUser)) { - return false; - } - Set rolePermissions = loginUser.getRolePermissions(); - if (CollectionUtils.isEmpty(rolePermissions)) { - return false; - } - for (String role : roles.split(ROLE_DELIMETER)) { - for (String roleKey : rolePermissions) { - if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) { - return true; - } - } - } - return false; - } - - /** - * 判断是否包含权限 - * - * @param permissions 权限列表 - * @param permission 权限字符串 - * @return 用户是否具备某权限 - */ - private boolean hasPermissions(Set permissions, String permission) { - return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java index 685a5bbc0..f1ff61a36 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java @@ -1,5 +1,6 @@ package com.ruoyi.generator.controller; +import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IoUtil; import com.ruoyi.common.annotation.Log; @@ -16,7 +17,6 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -45,7 +45,7 @@ public class GenController extends BaseController { * 查询代码生成列表 */ @ApiOperation("查询代码生成列表") - @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @SaCheckPermission("tool:gen:list") @GetMapping("/list") public TableDataInfo genList(GenTable genTable, PageQuery pageQuery) { return genTableService.selectPageGenTableList(genTable, pageQuery); @@ -55,7 +55,7 @@ public class GenController extends BaseController { * 修改代码生成业务 */ @ApiOperation("修改代码生成业务") - @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @SaCheckPermission("tool:gen:query") @GetMapping(value = "/{talbleId}") public AjaxResult> getInfo(@PathVariable Long talbleId) { GenTable table = genTableService.selectGenTableById(talbleId); @@ -72,7 +72,7 @@ public class GenController extends BaseController { * 查询数据库列表 */ @ApiOperation("查询数据库列表") - @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @SaCheckPermission("tool:gen:list") @GetMapping("/db/list") public TableDataInfo dataList(GenTable genTable, PageQuery pageQuery) { return genTableService.selectPageDbTableList(genTable, pageQuery); @@ -82,7 +82,7 @@ public class GenController extends BaseController { * 查询数据表字段列表 */ @ApiOperation("查询数据表字段列表") - @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @SaCheckPermission("tool:gen:list") @GetMapping(value = "/column/{talbleId}") public TableDataInfo columnList(Long tableId) { TableDataInfo dataInfo = new TableDataInfo<>(); @@ -96,7 +96,7 @@ public class GenController extends BaseController { * 导入表结构(保存) */ @ApiOperation("导入表结构(保存)") - @PreAuthorize("@ss.hasPermi('tool:gen:import')") + @SaCheckPermission("tool:gen:import") @Log(title = "代码生成", businessType = BusinessType.IMPORT) @PostMapping("/importTable") public AjaxResult importTableSave(String tables) { @@ -111,7 +111,7 @@ public class GenController extends BaseController { * 修改保存代码生成业务 */ @ApiOperation("修改保存代码生成业务") - @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @SaCheckPermission("tool:gen:edit") @Log(title = "代码生成", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult editSave(@Validated @RequestBody GenTable genTable) { @@ -124,7 +124,7 @@ public class GenController extends BaseController { * 删除代码生成 */ @ApiOperation("删除代码生成") - @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @SaCheckPermission("tool:gen:remove") @Log(title = "代码生成", businessType = BusinessType.DELETE) @DeleteMapping("/{tableIds}") public AjaxResult remove(@PathVariable Long[] tableIds) { @@ -136,7 +136,7 @@ public class GenController extends BaseController { * 预览代码 */ @ApiOperation("预览代码") - @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @SaCheckPermission("tool:gen:preview") @GetMapping("/preview/{tableId}") public AjaxResult> preview(@PathVariable("tableId") Long tableId) throws IOException { Map dataMap = genTableService.previewCode(tableId); @@ -147,7 +147,7 @@ public class GenController extends BaseController { * 生成代码(下载方式) */ @ApiOperation("生成代码(下载方式)") - @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @SaCheckPermission("tool:gen:code") @Log(title = "代码生成", businessType = BusinessType.GENCODE) @GetMapping("/download/{tableName}") public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException { @@ -159,7 +159,7 @@ public class GenController extends BaseController { * 生成代码(自定义路径) */ @ApiOperation("生成代码(自定义路径)") - @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @SaCheckPermission("tool:gen:code") @Log(title = "代码生成", businessType = BusinessType.GENCODE) @GetMapping("/genCode/{tableName}") public AjaxResult genCode(@PathVariable("tableName") String tableName) { @@ -171,7 +171,7 @@ public class GenController extends BaseController { * 同步数据库 */ @ApiOperation("同步数据库") - @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @SaCheckPermission("tool:gen:edit") @Log(title = "代码生成", businessType = BusinessType.UPDATE) @GetMapping("/synchDb/{tableName}") public AjaxResult synchDb(@PathVariable("tableName") String tableName) { @@ -183,7 +183,7 @@ public class GenController extends BaseController { * 批量生成代码 */ @ApiOperation("批量生成代码") - @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @SaCheckPermission("tool:gen:code") @Log(title = "代码生成", businessType = BusinessType.GENCODE) @GetMapping("/batchGenCode") public void batchGenCode(HttpServletResponse response, String tables) throws IOException { diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java index 3ac512b8a..83824438f 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java @@ -10,9 +10,7 @@ import com.ruoyi.common.constant.GenConstants; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.JsonUtils; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.*; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.generator.domain.GenTable; import com.ruoyi.generator.domain.GenTableColumn; @@ -161,7 +159,7 @@ public class GenTableServiceImpl implements IGenTableService { @Override @Transactional(rollbackFor = Exception.class) public void importGenTable(List tableList) { - String operName = SecurityUtils.getUsername(); + String operName = LoginUtils.getUsername(); try { for (GenTable table : tableList) { String tableName = table.getTableName(); diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm index 16798f33c..cd618fb66 100644 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit; import lombok.RequiredArgsConstructor; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.*; -import org.springframework.security.access.prepost.PreAuthorize; +import cn.dev33.satoken.annotation.SaCheckPermission; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; @@ -51,7 +51,7 @@ public class ${ClassName}Controller extends BaseController { * 查询${functionName}列表 */ @ApiOperation("查询${functionName}列表") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @SaCheckPermission("${permissionPrefix}:list") @GetMapping("/list") #if($table.crud || $table.sub) public TableDataInfo<${ClassName}Vo> list(@Validated(QueryGroup.class) ${ClassName}Bo bo, PageQuery pageQuery) { @@ -68,7 +68,7 @@ public class ${ClassName}Controller extends BaseController { * 导出${functionName}列表 */ @ApiOperation("导出${functionName}列表") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @SaCheckPermission("${permissionPrefix}:export") @Log(title = "${functionName}", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(@Validated ${ClassName}Bo bo, HttpServletResponse response) { @@ -80,7 +80,7 @@ public class ${ClassName}Controller extends BaseController { * 获取${functionName}详细信息 */ @ApiOperation("获取${functionName}详细信息") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @SaCheckPermission("${permissionPrefix}:query") @GetMapping("/{${pkColumn.javaField}}") public AjaxResult<${ClassName}Vo> getInfo(@ApiParam("主键") @NotNull(message = "主键不能为空") @@ -92,7 +92,7 @@ public class ${ClassName}Controller extends BaseController { * 新增${functionName} */ @ApiOperation("新增${functionName}") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @SaCheckPermission("${permissionPrefix}:add") @Log(title = "${functionName}", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() @@ -104,7 +104,7 @@ public class ${ClassName}Controller extends BaseController { * 修改${functionName} */ @ApiOperation("修改${functionName}") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @SaCheckPermission("${permissionPrefix}:edit") @Log(title = "${functionName}", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() @@ -116,7 +116,7 @@ public class ${ClassName}Controller extends BaseController { * 删除${functionName} */ @ApiOperation("删除${functionName}") - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @SaCheckPermission("${permissionPrefix}:remove") @Log(title = "${functionName}" , businessType = BusinessType.DELETE) @DeleteMapping("/{${pkColumn.javaField}s}") public AjaxResult remove(@ApiParam("主键串") diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java index 3b700d48c..9bd21d3bb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.excel.ExcelListener; import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ValidatorUtils; @@ -44,7 +45,7 @@ public class SysUserImportListener extends AnalysisEventListener depts = SpringUtils.getAopProxy(this).selectDeptList(dept); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java index f3c4a74ca..2f7276780 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -8,7 +8,7 @@ import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.SysRoleDept; @@ -182,7 +182,7 @@ public class SysRoleServiceImpl implements ISysRoleService { */ @Override public void checkRoleDataScope(Long roleId) { - if (!SysUser.isAdmin(SecurityUtils.getUserId())) { + if (!SysUser.isAdmin(LoginUtils.getUserId())) { SysRole role = new SysRole(); role.setRoleId(roleId); List roles = SpringUtils.getAopProxy(this).selectRoleList(role); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java deleted file mode 100644 index 8ec0fe245..000000000 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.ruoyi.system.service.impl; - -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.domain.SysUserOnline; -import com.ruoyi.system.mapper.SysUserMapper; -import com.ruoyi.system.service.ISysUserOnlineService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -/** - * 在线用户 服务层处理 - * - * @author Lion Li - */ -@RequiredArgsConstructor -@Service -public class SysUserOnlineServiceImpl implements ISysUserOnlineService { - - private final SysUserMapper userMapper; - - /** - * 通过登录地址查询信息 - * - * @param ipaddr 登录地址 - * @param user 用户信息 - * @return 在线用户信息 - */ - @Override - public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) { - if (StringUtils.equals(ipaddr, user.getIpaddr())) { - return loginUserToUserOnline(user); - } - return null; - } - - /** - * 通过用户名称查询信息 - * - * @param userName 用户名称 - * @param user 用户信息 - * @return 在线用户信息 - */ - @Override - public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) { - if (StringUtils.equals(userName, user.getUsername())) { - return loginUserToUserOnline(user); - } - return null; - } - - /** - * 通过登录地址/用户名称查询信息 - * - * @param ipaddr 登录地址 - * @param userName 用户名称 - * @param user 用户信息 - * @return 在线用户信息 - */ - @Override - public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) { - if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) { - return loginUserToUserOnline(user); - } - return null; - } - - /** - * 设置在线用户信息 - * - * @param user 用户信息 - * @return 在线用户 - */ - @Override - public SysUserOnline loginUserToUserOnline(LoginUser user) { - if (StringUtils.isNull(user)) { - return null; - } - SysUser sysUser = userMapper.selectUserById(user.getUserId()); - SysUserOnline sysUserOnline = new SysUserOnline(); - sysUserOnline.setTokenId(user.getToken()); - sysUserOnline.setUserName(user.getUsername()); - sysUserOnline.setIpaddr(user.getIpaddr()); - sysUserOnline.setLoginLocation(user.getLoginLocation()); - sysUserOnline.setBrowser(user.getBrowser()); - sysUserOnline.setOs(user.getOs()); - sysUserOnline.setLoginTime(user.getLoginTime()); - if (StringUtils.isNotNull(sysUser.getDept())) { - sysUserOnline.setDeptName(sysUser.getDept().getDeptName()); - } - return sysUserOnline; - } -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index fe028bc06..9dd77a025 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -11,6 +11,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.service.UserService; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.LoginUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; @@ -208,7 +209,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public void checkUserDataScope(Long userId) { - if (!SysUser.isAdmin(SecurityUtils.getUserId())) { + if (!SysUser.isAdmin(LoginUtils.getUserId())) { SysUser user = new SysUser(); user.setUserId(userId); List users = SpringUtils.getAopProxy(this).selectUserList(user); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TokenServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TokenServiceImpl.java deleted file mode 100644 index af14f3743..000000000 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TokenServiceImpl.java +++ /dev/null @@ -1,202 +0,0 @@ -package com.ruoyi.system.service.impl; - -import cn.hutool.core.util.IdUtil; -import cn.hutool.http.useragent.UserAgent; -import cn.hutool.http.useragent.UserAgentUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.jwt.JWTUtil; -import cn.hutool.jwt.signers.JWTSigner; -import cn.hutool.jwt.signers.JWTSignerUtil; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.service.TokenService; -import com.ruoyi.common.properties.TokenProperties; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.ip.AddressUtils; -import com.ruoyi.common.utils.redis.RedisUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * token验证处理 - * - * @author Lion Li - */ -@RequiredArgsConstructor -@Service -public class TokenServiceImpl implements TokenService { - - protected static final long MILLIS_SECOND = 1000; - - protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; - - private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; - - private final TokenProperties tokenProperties; - - /** - * 获取用户身份信息 - * - * @return 用户信息 - */ - @Override - public LoginUser getLoginUser(HttpServletRequest request) { - // 获取请求携带的令牌 - String token = getToken(request); - if (StringUtils.isNotEmpty(token)) { - try { - JSONObject claims = parseToken(token); - // 解析对应的权限以及用户信息 - String uuid = claims.getStr(Constants.LOGIN_USER_KEY); - String userKey = getTokenKey(uuid); - LoginUser user = RedisUtils.getCacheObject(userKey); - return user; - } catch (Exception e) { - - } - } - return null; - } - - /** - * 设置用户身份信息 - */ - @Override - public void setLoginUser(LoginUser loginUser) { - if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) { - refreshToken(loginUser); - } - } - - /** - * 删除用户身份信息 - */ - @Override - public void delLoginUser(String token) { - if (StringUtils.isNotEmpty(token)) { - String userKey = getTokenKey(token); - RedisUtils.deleteObject(userKey); - } - } - - /** - * 创建令牌 - * - * @param loginUser 用户信息 - * @return 令牌 - */ - @Override - public String createToken(LoginUser loginUser) { - String token = IdUtil.fastUUID(); - loginUser.setToken(token); - setUserAgent(loginUser); - refreshToken(loginUser); - - Map claims = new HashMap<>(); - claims.put(Constants.LOGIN_USER_KEY, token); - return createToken(claims); - } - - /** - * 验证令牌有效期,相差不足20分钟,自动刷新缓存 - * - * @param loginUser - * @return 令牌 - */ - @Override - public void verifyToken(LoginUser loginUser) { - long expireTime = loginUser.getExpireTime(); - long currentTime = System.currentTimeMillis(); - if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { - refreshToken(loginUser); - } - } - - /** - * 刷新令牌有效期 - * - * @param loginUser 登录信息 - */ - @Override - public void refreshToken(LoginUser loginUser) { - loginUser.setLoginTime(System.currentTimeMillis()); - loginUser.setExpireTime(loginUser.getLoginTime() + tokenProperties.getExpireTime() * MILLIS_MINUTE); - // 根据uuid将loginUser缓存 - String userKey = getTokenKey(loginUser.getToken()); - RedisUtils.setCacheObject(userKey, loginUser, tokenProperties.getExpireTime(), TimeUnit.MINUTES); - } - - /** - * 设置用户代理信息 - * - * @param loginUser 登录信息 - */ - @Override - public void setUserAgent(LoginUser loginUser) { - UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); - String ip = ServletUtils.getClientIP(); - loginUser.setIpaddr(ip); - loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); - loginUser.setBrowser(userAgent.getBrowser().getName()); - loginUser.setOs(userAgent.getOs().getName()); - } - - /** - * 从数据声明生成令牌 - * - * @param claims 数据声明 - * @return 令牌 - */ - private String createToken(Map claims) { - JWTSigner signer = JWTSignerUtil.hs512(tokenProperties.getSecret().getBytes()); - String token = JWTUtil.createToken(claims, signer); - return token; - } - - /** - * 从令牌中获取数据声明 - * - * @param token 令牌 - * @return 数据声明 - */ - private JSONObject parseToken(String token) { - JWTSigner signer = JWTSignerUtil.hs512(tokenProperties.getSecret().getBytes()); - return JWTUtil.parseToken(token).setSigner(signer).getPayload().getClaimsJson(); - } - - /** - * 从令牌中获取用户名 - * - * @param token 令牌 - * @return 用户名 - */ - @Override - public String getUsernameFromToken(String token) { - JSONObject claims = parseToken(token); - return claims.getStr("sub"); - } - - /** - * 获取请求token - * - * @param request - * @return token - */ - private String getToken(HttpServletRequest request) { - String token = request.getHeader(tokenProperties.getHeader()); - if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) { - token = token.replace(Constants.TOKEN_PREFIX, ""); - } - return token; - } - - private String getTokenKey(String uuid) { - return Constants.LOGIN_TOKEN_KEY + uuid; - } -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserDetailsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserDetailsServiceImpl.java deleted file mode 100644 index c66aa59e5..000000000 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserDetailsServiceImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.system.service.impl; - -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.enums.UserStatus; -import com.ruoyi.common.exception.user.UserException; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.service.ISysUserService; -import com.ruoyi.system.service.SysPermissionService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -/** - * 用户验证处理 - * - * @author ruoyi - */ -@Slf4j -@RequiredArgsConstructor -@Service -public class UserDetailsServiceImpl implements UserDetailsService { - - private final ISysUserService userService; - private final SysPermissionService permissionService; - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - SysUser user = userService.selectUserByUserName(username); - if (StringUtils.isNull(user)) { - log.info("登录用户:{} 不存在.", username); - throw new UserException("user.not.exists", username); - } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { - log.info("登录用户:{} 已被删除.", username); - throw new UserException("user.password.delete", username); - } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { - log.info("登录用户:{} 已被停用.", username); - throw new UserException("user.blocked", username); - } - - return createLoginUser(user); - } - - public UserDetails createLoginUser(SysUser user) { - return new LoginUser() - .setUserId(user.getUserId()) - .setDeptId(user.getDeptId()) - .setUsername(user.getUserName()) - .setPassword(user.getPassword()) - .setMenuPermissions(permissionService.getMenuPermission(user)) - .setRolePermissions(permissionService.getRolePermission(user)); - } -}