From 25aad6ba5fda0fb86afbf25a8f18e83230f5427a Mon Sep 17 00:00:00 2001 From: zhuoda Date: Wed, 26 Jul 2023 21:18:39 +0800 Subject: [PATCH] Revert "!22 sa-token" This reverts commit e465fdbf0a2d6a54368e921502b17adaa56ddb4c, reversing changes made to c6d7ae9f46c7512ac582c6c4d3751e0e9bbd38af. --- smart-admin-api/pom.xml | 18 -- .../sa/admin/config/JweAspectConfig.java | 4 +- .../sa/admin/config/SaTokenConfig.java | 37 --- .../sa/admin/config/SecurityConfig.java | 40 +++ .../sa/admin/config/SecurityMethodConfig.java | 50 ++++ .../admin/interceptor/AdminInterceptor.java | 69 ----- .../goods/controller/GoodsController.java | 6 + .../business/oa/bank/BankController.java | 2 +- .../oa/enterprise/EnterpriseController.java | 13 +- .../oa/invoice/InvoiceController.java | 2 +- .../notice/controller/NoticeController.java | 12 +- .../service/DataScopeSqlConfigService.java | 4 +- .../controller/DepartmentController.java | 4 + .../controller/EmployeeController.java | 9 +- .../service/EmployeePermissionService.java | 119 +++------ .../employee/service/EmployeeService.java | 8 +- .../login/controller/LoginController.java | 43 ++-- .../login/domain/LoginEmployeeDetail.java | 91 ++++++- .../module/system/login/domain/LoginForm.java | 9 +- .../system/login/service/LoginService.java | 72 ++++-- .../system/menu/constant/MenuTypeEnum.java | 24 +- .../menu/controller/MenuController.java | 10 +- .../system/menu/service/MenuCacheService.java | 55 ---- .../system/menu/service/MenuService.java | 16 +- .../role/controller/RoleController.java | 4 + .../controller/RoleDataScopeController.java | 2 + .../controller/RoleEmployeeController.java | 4 + .../role/controller/RoleMenuController.java | 2 + .../role/service/RoleEmployeeService.java | 24 +- .../system/role/service/RoleMenuService.java | 12 +- .../system/role/service/RoleService.java | 4 - .../system/support/AdminCacheController.java | 3 + .../support/AdminChangeLogController.java | 5 + .../system/support/AdminConfigController.java | 4 + .../system/support/AdminFileController.java | 2 + .../support/AdminHelpDocController.java | 7 + .../support/AdminLoginLogController.java | 2 + .../support/AdminOperateLogController.java | 3 + .../system/support/AdminReloadController.java | 3 + .../support/AdminSerialNumberController.java | 3 + smart-admin-api/sa-common/pom.xml | 13 +- .../sa/common/common/annoation/SaAuth.java | 22 ++ .../sa/common/common/code/UserErrorCode.java | 8 +- .../common/common/constant/StringConst.java | 5 - .../sa/common/common/domain/RequestUrlVO.java | 3 + .../sa/common/common/domain/RequestUser.java | 36 ++- ...{SystemEnv.java => SystemEnvironment.java} | 6 +- ...nvEnum.java => SystemEnvironmentEnum.java} | 12 +- .../common/enumeration/UserTypeEnum.java | 26 +- .../interceptor/AbstractInterceptor.java | 178 +++++-------- .../security/AbstractSecurityConfig.java | 93 +++++++ .../SecurityAuthenticationFailHandler.java | 43 ++++ .../common/security/SecurityMethodSource.java | 66 +++++ .../SecurityPermissionCheckService.java | 74 ++++++ .../common/security/SecurityTokenFilter.java | 64 +++++ .../common/common/util/SmartRequestUtil.java | 31 ++- .../sa/common/config/DataSourceConfig.java | 2 +- .../lab1024/sa/common/config/MvcConfig.java | 31 +-- .../sa/common/config/RepeatSubmitConfig.java | 2 +- .../sa/common/config/SwaggerConfig.java | 4 +- ...nfig.java => SystemEnvironmentConfig.java} | 16 +- .../lab1024/sa/common/config/UrlConfig.java | 63 +++-- .../handler/GlobalExceptionHandler.java | 40 ++- .../support/captcha/CaptchaService.java | 5 +- .../datatracer/service/DataTracerService.java | 4 +- .../controller/FeedbackController.java | 3 +- .../file/controller/FileController.java | 10 +- .../helpdoc/controller/HelpDocController.java | 2 +- .../operatelog/core/OperateLogAspect.java | 2 +- .../module/support/redis/RedisService.java | 8 +- .../support/table/TableColumnController.java | 6 +- .../module/support/token/LoginDeviceEnum.java | 24 +- .../module/support/token/TokenService.java | 237 ++++++++++++++---- .../src/main/resources/dev/sa-common.yaml | 46 +--- 74 files changed, 1240 insertions(+), 746 deletions(-) delete mode 100644 smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SaTokenConfig.java create mode 100644 smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java create mode 100644 smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java delete mode 100644 smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java delete mode 100644 smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuCacheService.java create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java rename smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/{SystemEnv.java => SystemEnvironment.java} (76%) rename smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/{SystemEnvEnum.java => SystemEnvironmentEnum.java} (67%) create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java create mode 100644 smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java rename smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/{SystemEnvConfig.java => SystemEnvironmentConfig.java} (69%) diff --git a/smart-admin-api/pom.xml b/smart-admin-api/pom.xml index 37e2f4ae..7211de26 100644 --- a/smart-admin-api/pom.xml +++ b/smart-admin-api/pom.xml @@ -46,7 +46,6 @@ 0.9.1 0.9.0 3.1 - 1.35.0.RC @@ -110,23 +109,6 @@ ${swagger.version} - - - - cn.dev33 - sa-token-spring-boot-starter - ${sa-token-version} - - - - - cn.dev33 - sa-token-redis-jackson - ${sa-token-version} - - - - com.alibaba fastjson diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java index 3c6147c1..c4e74ff9 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java @@ -4,6 +4,8 @@ import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.util.SmartRequestUtil; import net.lab1024.sa.common.module.support.jwe.JweAspect; import net.lab1024.sa.common.module.support.jwe.JweUserKey; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogAspect; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,7 +27,7 @@ public class JweAspectConfig { @Bean public JweAspect jweConfig() { return new JweAspect((request -> { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); JweUserKey userKey = new JweUserKey(); userKey.setUserId(requestUser.getUserId()); userKey.setUserName(requestUser.getUserName()); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SaTokenConfig.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SaTokenConfig.java deleted file mode 100644 index 0df62f98..00000000 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SaTokenConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.lab1024.sa.admin.config; - -import cn.dev33.satoken.interceptor.SaInterceptor; -import cn.dev33.satoken.router.SaRouter; -import cn.dev33.satoken.stp.StpUtil; -import net.lab1024.sa.admin.module.system.menu.service.MenuCacheService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.List; - -/** - * sa-token 配置 - * - * @author Turbolisten - * @date 2023/7/13 16:57 - */ -@Configuration -public class SaTokenConfig { - - @Autowired - private MenuCacheService menuService; - - /** - * 定义 Sa-Token 拦截器,定义详细认证规则 - */ - @Bean - public SaInterceptor saInterceptor() { - // 关闭注解鉴权 只做路由拦截校验 - return new SaInterceptor(handler -> { - // 查询数据表中 需要校验权限的url - List urlList = menuService.queryNeedCheckPermissionsUrl(); - urlList.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url))); - }).isAnnotation(false); - } -} diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java new file mode 100644 index 00000000..8f12ba27 --- /dev/null +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.common.common.security.AbstractSecurityConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.servlet.http.HttpServletRequest; +import java.util.function.BiFunction; + +/** + * 权限配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class SecurityConfig extends AbstractSecurityConfig { + /** + * 获取TOKEN 解析类 + */ + @Autowired + private LoginService loginService; + + @Override + protected BiFunction userFunction() { + return (token, request) -> loginService.getLoginUserDetail(token, request); + } + + @Override + protected String[] getAuthenticatedUrlPatterns() { + return new String[]{"/**"}; + } + + +} diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java new file mode 100644 index 00000000..772b2d5d --- /dev/null +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.annoation.SaAuth; +import net.lab1024.sa.common.common.security.SecurityMethodSource; +import net.lab1024.sa.common.common.security.SecurityPermissionCheckService; +import org.springframework.context.annotation.Bean; +import org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory; +import org.springframework.security.access.method.MethodSecurityMetadataSource; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.core.Authentication; + +/** + * 1、以类名加方法名为权限字符串的校验模式
+ * 2、重写MethodSecurityMetadataSource将优化security配置,只需在方法上加上@saAuth注解,方法上就会存在权限(权限字符串为类名加方法名),而无需另外手动设置,减轻后端开发成本
+ * 3、security将不再依据权限字符串进行权限控制,
+ * 4、security将依据对应权限字符串下的接口权限进行控制
+ * 5、采用此配置原@PreAuthorize依然有效
+ * 6、如若无需此配置,需将@EnableGlobalMethodSecurity注解添加至SecurityConfig类上 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-08-31 0:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration { + + @Bean(SaAuth.saAuth) + public SecurityPermissionCheckService securityPermissionCheckService() { + return new SecurityPermissionCheckService() { + @Override + public boolean checkPermission(Authentication authentication, String permission) { + LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal(); + if (loginEmployeeDetail.getAdministratorFlag()) { + return true; + } + return super.permissionJudge(loginEmployeeDetail, permission); + } + }; + } + + @Override + public MethodSecurityMetadataSource customMethodSecurityMetadataSource() { + ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(this.getExpressionHandler()); + return new SecurityMethodSource(attributeFactory, SaAuth.saAuth); + } +} diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java deleted file mode 100644 index 6ea73889..00000000 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.lab1024.sa.admin.interceptor; - -import com.google.common.collect.Lists; -import net.lab1024.sa.common.common.domain.RequestUser; -import net.lab1024.sa.common.common.enumeration.UserTypeEnum; -import net.lab1024.sa.common.common.interceptor.AbstractInterceptor; -import org.springframework.context.annotation.Configuration; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * admin 拦截器 - * - * @author: listen - * @date: 2023/7/12 21:00 - */ -@Configuration -public class AdminInterceptor extends AbstractInterceptor { - - /** - * 此处可根据需要 - * 自行查询用户信息 - */ - @Override - public RequestUser getDevUser(Long userId) { - RequestUser requestUser = new RequestUser(); - requestUser.setUserId(userId); - requestUser.setUserName("dev"); - requestUser.setUserType(this.getUserType()); - return requestUser; - } - - @Override - public UserTypeEnum getUserType() { - return UserTypeEnum.ADMIN_EMPLOYEE; - } - - /** - * 配置拦截路径 - * - * @return - */ - @Override - public List pathPatterns() { - return Lists.newArrayList("/**"); - } - - /** - * 如果没有需要处理的业务 - * 那就没有必要重写了 可以删除这个方法 - * - * @param request - * @param response - * @param handler - * @return - * @throws Exception - */ - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - boolean isHandle = super.preHandle(request, response, handler); - if (!isHandle) { - return false; - } - // 如有业务需处理 写在此处 - return true; - } -} diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java index 7d6ba5f8..7fa863c2 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java @@ -14,6 +14,7 @@ import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.domain.ValidateList; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -37,30 +38,35 @@ public class GoodsController extends AdminBaseController { @ApiOperation("分页查询 @author 胡克") @PostMapping("/goods/query") + @PreAuthorize("@saAuth.checkPermission('goods:query')") public ResponseDTO> query(@RequestBody @Valid GoodsQueryForm queryForm) { return goodsService.query(queryForm); } @ApiOperation("添加商品 @author 胡克") @PostMapping("/goods/add") + @PreAuthorize("@saAuth.checkPermission('goods:add')") public ResponseDTO add(@RequestBody @Valid GoodsAddForm addForm) { return goodsService.add(addForm); } @ApiOperation("更新商品 @author 胡克") @PostMapping("/goods/update") + @PreAuthorize("@saAuth.checkPermission('goods:update')") public ResponseDTO update(@RequestBody @Valid GoodsUpdateForm updateForm) { return goodsService.update(updateForm); } @ApiOperation("删除 @author 卓大") @GetMapping("/goods/delete/{goodsId}") + @PreAuthorize("@saAuth.checkPermission('goods:delete')") public ResponseDTO delete(@PathVariable Long goodsId) { return goodsService.delete(goodsId); } @ApiOperation("批量 @author 卓大") @PostMapping("/goods/batchDelete") + @PreAuthorize("@saAuth.checkPermission('goods:batchDelete')") public ResponseDTO batchDelete(@RequestBody @Valid ValidateList idList) { return goodsService.batchDelete(idList); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java index bc99f346..96fbea31 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java @@ -54,7 +54,7 @@ public class BankController { @ApiOperation(value = "新建银行信息 @author 善逸") @PostMapping("/oa/bank/create") public ResponseDTO createBank(@RequestBody @Valid BankCreateForm createVO) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); createVO.setCreateUserId(requestUser.getUserId()); createVO.setCreateUserName(requestUser.getUserName()); return bankService.createBank(createVO); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java index ed8a35cd..efc0143b 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java @@ -8,6 +8,7 @@ import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*; import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.common.common.annoation.SaAuth; import net.lab1024.sa.common.common.domain.PageResult; import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.domain.ResponseDTO; @@ -39,20 +40,23 @@ public class EnterpriseController { @ApiOperation(value = "分页查询企业模块 @author 开云") @PostMapping("/oa/enterprise/page/query") + @SaAuth public ResponseDTO> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryDTO) { return enterpriseService.queryByPage(queryDTO); } @ApiOperation(value = "查询企业详情 @author 开云") @GetMapping("/oa/enterprise/get/{enterpriseId}") + @SaAuth public ResponseDTO getDetail(@PathVariable Long enterpriseId) { return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId)); } @ApiOperation(value = "新建企业 @author 开云") @PostMapping("/oa/enterprise/create") + @SaAuth public ResponseDTO createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); createVO.setCreateUserId(requestUser.getUserId()); createVO.setCreateUserName(requestUser.getUserName()); return enterpriseService.createEnterprise(createVO); @@ -60,18 +64,21 @@ public class EnterpriseController { @ApiOperation(value = "编辑企业 @author 开云") @PostMapping("/oa/enterprise/update") + @SaAuth public ResponseDTO updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) { return enterpriseService.updateEnterprise(updateVO); } @ApiOperation(value = "删除企业 @author 开云") @GetMapping("/oa/enterprise/delete/{enterpriseId}") + @SaAuth public ResponseDTO deleteEnterprise(@PathVariable Long enterpriseId) { return enterpriseService.deleteEnterprise(enterpriseId); } @ApiOperation(value = "企业列表查询 @author 开云") @GetMapping("/oa/enterprise/query/list") + @SaAuth public ResponseDTO> queryList(@RequestParam(value = "type", required = false) Integer type) { return enterpriseService.queryList(type); } @@ -79,18 +86,21 @@ public class EnterpriseController { @ApiOperation(value = "企业添加员工 @author 罗伊") @PostMapping("/oa/enterprise/employee/add") + @SaAuth public ResponseDTO addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { return enterpriseService.addEmployee(enterpriseEmployeeForm); } @ApiOperation(value = "查询企业全部员工 @author 罗伊") @PostMapping("/oa/enterprise/employee/list") + @SaAuth public ResponseDTO> employeeList(@RequestBody @Valid List enterpriseIdList) { return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList)); } @ApiOperation(value = "分页查询企业员工 @author 卓大") @PostMapping("/oa/enterprise/employee/queryPage") + @SaAuth public ResponseDTO> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) { return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm)); } @@ -98,6 +108,7 @@ public class EnterpriseController { @ApiOperation(value = "企业删除员工 @author 罗伊") @PostMapping("/oa/enterprise/employee/delete") + @SaAuth public ResponseDTO deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { return enterpriseService.deleteEmployee(enterpriseEmployeeForm); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java index fb9d1bcd..40909dc9 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java @@ -52,7 +52,7 @@ public class InvoiceController { @ApiOperation(value = "新建发票信息 @author 善逸") @PostMapping("/oa/invoice/create") public ResponseDTO createInvoice(@RequestBody @Valid InvoiceAddForm createVO) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); createVO.setCreateUserId(requestUser.getUserId()); createVO.setCreateUserName(requestUser.getUserName()); return invoiceService.createInvoice(createVO); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java index f2af3de6..8ac0f311 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java @@ -9,6 +9,7 @@ import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*; import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeEmployeeService; import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeService; import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeTypeService; +import net.lab1024.sa.common.common.annoation.SaAuth; import net.lab1024.sa.common.common.domain.PageResult; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartRequestUtil; @@ -72,6 +73,7 @@ public class NoticeController { @ApiOperation("【管理】通知公告-分页查询 @author 卓大") @PostMapping("/oa/notice/query") + @SaAuth public ResponseDTO> query(@RequestBody @Valid NoticeQueryForm queryForm) { return ResponseDTO.ok(noticeService.query(queryForm)); } @@ -79,26 +81,30 @@ public class NoticeController { @ApiOperation("【管理】通知公告-添加 @author 卓大") @PostMapping("/oa/notice/add") @RepeatSubmit + @SaAuth public ResponseDTO add(@RequestBody @Valid NoticeAddForm addForm) { - addForm.setCreateUserId(SmartRequestUtil.getUserId()); + addForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); return noticeService.add(addForm); } @ApiOperation("【管理】通知公告-更新 @author 卓大") @PostMapping("/oa/notice/update") @RepeatSubmit + @SaAuth public ResponseDTO update(@RequestBody @Valid NoticeUpdateForm updateForm) { return noticeService.update(updateForm); } @ApiOperation("【管理】通知公告-更新详情 @author 卓大") @GetMapping("/oa/notice/getUpdateVO/{noticeId}") + @SaAuth public ResponseDTO getUpdateFormVO(@PathVariable Long noticeId) { return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId)); } @ApiOperation("【管理】通知公告-删除 @author 卓大") @GetMapping("/oa/notice/delete/{noticeId}") + @SaAuth public ResponseDTO delete(@PathVariable Long noticeId) { return noticeService.delete(noticeId); } @@ -108,7 +114,7 @@ public class NoticeController { @GetMapping("/oa/notice/employee/view/{noticeId}") public ResponseDTO view(@PathVariable Long noticeId, HttpServletRequest request) { return noticeEmployeeService.view( - SmartRequestUtil.getUserId(), + SmartRequestUtil.getRequestUserId(), noticeId, ServletUtil.getClientIP(request), request.getHeader("User-Agent") @@ -118,7 +124,7 @@ public class NoticeController { @ApiOperation("【员工】通知公告-查询全部 @author 卓大") @PostMapping("/oa/notice/employee/query") public ResponseDTO> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) { - return noticeEmployeeService.queryList(SmartRequestUtil.getUserId(), noticeEmployeeQueryForm); + return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm); } @ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大") diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java index 1148d030..fc98e24b 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java @@ -1,11 +1,11 @@ package net.lab1024.sa.admin.module.system.datascope.service; import lombok.extern.slf4j.Slf4j; -import net.lab1024.sa.admin.module.system.datascope.DataScope; import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; +import net.lab1024.sa.admin.module.system.datascope.DataScope; import net.lab1024.sa.admin.module.system.datascope.strategy.DataScopePowerStrategy; import net.lab1024.sa.common.common.util.SmartRequestUtil; import org.apache.commons.collections4.CollectionUtils; @@ -108,7 +108,7 @@ public class DataScopeSqlConfigService { public String getJoinSql(Map paramMap, DataScopeSqlConfig sqlConfigDTO) { DataScopeTypeEnum dataScopeTypeEnum = sqlConfigDTO.getDataScopeType(); String joinSql = sqlConfigDTO.getJoinSql(); - Long employeeId = SmartRequestUtil.getUserId(); + Long employeeId = SmartRequestUtil.getRequestUserId(); if (employeeId == null) { return ""; } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java index 79ee73dd..62e2fe33 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java @@ -12,6 +12,7 @@ import net.lab1024.sa.admin.module.system.department.service.DepartmentService; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -42,18 +43,21 @@ public class DepartmentController extends AdminBaseController { @ApiOperation(value = "添加部门 @author 卓大") @PostMapping("/department/add") + @PreAuthorize("@saAuth.checkPermission('system:department:add')") public ResponseDTO addDepartment(@Valid @RequestBody DepartmentAddForm createDTO) { return departmentService.addDepartment(createDTO); } @ApiOperation(value = "更新部门 @author 卓大") @PostMapping("/department/update") + @PreAuthorize("@saAuth.checkPermission('system:department:update')") public ResponseDTO updateDepartment(@Valid @RequestBody DepartmentUpdateForm updateDTO) { return departmentService.updateDepartment(updateDTO); } @ApiOperation(value = "删除部门 @author 卓大") @GetMapping("/department/delete/{departmentId}") + @PreAuthorize("@saAuth.checkPermission('system:department:delete')") public ResponseDTO deleteDepartment(@PathVariable Long departmentId) { return departmentService.deleteDepartment(departmentId); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java index c8cacfb9..c5f0f325 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java @@ -12,6 +12,7 @@ import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartRequestUtil; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -42,30 +43,35 @@ public class EmployeeController extends AdminBaseController { @ApiOperation(value = "添加员工(返回添加员工的密码) @author 卓大") @PostMapping("/employee/add") + @PreAuthorize("@saAuth.checkPermission('system:employee:add')") public ResponseDTO addEmployee(@Valid @RequestBody EmployeeAddForm employeeAddForm) { return employeeService.addEmployee(employeeAddForm); } @ApiOperation(value = "更新员工 @author 卓大") @PostMapping("/employee/update") + @PreAuthorize("@saAuth.checkPermission('system:employee:update')") public ResponseDTO updateEmployee(@Valid @RequestBody EmployeeUpdateForm employeeUpdateForm) { return employeeService.updateEmployee(employeeUpdateForm); } @ApiOperation(value = "更新员工禁用/启用状态 @author 卓大") @GetMapping("/employee/update/disabled/{employeeId}") + @PreAuthorize("@saAuth.checkPermission('system:employee:disabled')") public ResponseDTO updateDisableFlag(@PathVariable Long employeeId) { return employeeService.updateDisableFlag(employeeId); } @ApiOperation(value = "批量删除员工 @author 卓大") @PostMapping("/employee/update/batch/delete") + @PreAuthorize("@saAuth.checkPermission('system:employee:delete')") public ResponseDTO batchUpdateDeleteFlag(@RequestBody List employeeIdList) { return employeeService.batchUpdateDeleteFlag(employeeIdList); } @ApiOperation(value = "批量调整员工部门 @author 卓大") @PostMapping("/employee/update/batch/department") + @PreAuthorize("@saAuth.checkPermission('system:employee:department:update')") public ResponseDTO batchUpdateDepartment(@Valid @RequestBody EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) { return employeeService.batchUpdateDepartment(batchUpdateDepartmentForm); } @@ -73,12 +79,13 @@ public class EmployeeController extends AdminBaseController { @ApiOperation(value = "修改密码 @author 卓大") @PostMapping("/employee/update/password") public ResponseDTO updatePassword(@Valid @RequestBody EmployeeUpdatePasswordForm updatePasswordForm) { - updatePasswordForm.setEmployeeId(SmartRequestUtil.getUserId()); + updatePasswordForm.setEmployeeId(SmartRequestUtil.getRequestUserId()); return employeeService.updatePassword(updatePasswordForm); } @ApiOperation(value = "重置员工密码 @author 卓大") @GetMapping("/employee/update/password/reset/{employeeId}") + @PreAuthorize("@saAuth.checkPermission('system:employee:password:reset')") public ResponseDTO resetPassword(@PathVariable Integer employeeId) { return employeeService.resetPassword(employeeId); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java index fdfb84de..3e6a0297 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java @@ -1,24 +1,18 @@ package net.lab1024.sa.admin.module.system.employee.service; -import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.session.SaSessionCustomUtil; -import cn.dev33.satoken.stp.StpInterface; -import cn.dev33.satoken.stp.StpUtil; -import com.google.common.collect.Lists; -import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; -import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum; import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; -import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; -import net.lab1024.sa.common.common.enumeration.UserTypeEnum; -import net.lab1024.sa.common.module.support.token.TokenService; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; -import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; /** @@ -31,7 +25,7 @@ import java.util.stream.Collectors; * @Copyright 1024创新实验室 ( https://1024lab.net ) */ @Service -public class EmployeePermissionService implements StpInterface { +public class EmployeePermissionService { @Autowired private RoleEmployeeService roleEmployeeService; @@ -39,23 +33,39 @@ public class EmployeePermissionService implements StpInterface { @Autowired private RoleMenuService roleMenuService; - @Autowired - private RoleMenuDao roleMenuDao; - /** - * 员工关联权限 缓存key + * 构建权限集合 + * + * @param menuAndPointsList */ - private static final String USER_ROLE_CACHE_KEY = "RoleList"; + public Set buildAuthorities(List menuAndPointsList) { + HashSet permissionList = new HashSet<>(); + for (MenuVO menu : menuAndPointsList) { + if(menu.getPermsType() == null){ + continue; + } - /** - * 角色关联功能点 缓存key - */ - private static final String ROLE_CACHE_KEY = "role:"; + String perms = null; + if(menu.getPermsType().equals(MenuPermsTypeEnum.SPRING_SECURITY.getValue())){ + perms = menu.getWebPerms(); + }else{ + perms = menu.getApiPerms(); + } - /** - * 角色关联功能点 缓存key - */ - private static final String ROLE_PERMISSION_CACHE_KEY = "PermissionList"; + if (StringUtils.isEmpty(perms)) { + continue; + } + //接口权限 + String[] split = perms.split(","); + for (String perm : split) { + permissionList.add(perm); + } + } + + Set authorities = new HashSet<>(); + authorities.addAll(permissionList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet())); + return authorities; + } /** * 查询用户拥有的前端菜单项 用于登陆返回 前端动态路由配置 @@ -68,61 +78,4 @@ public class EmployeePermissionService implements StpInterface { return roleMenuService.getMenuList(roleIdList, administratorFlag); } - @Override - public List getPermissionList(Object loginId, String loginType) { - // 权限集合 - List permissionList = new ArrayList<>(); - - // 遍历角色列表,查询拥有的权限 - List roleList = this.getRoleList(loginId, loginType); - for (String roleId : roleList) { - // 查询缓存 - SaSession roleSession = SaSessionCustomUtil.getSessionById(ROLE_CACHE_KEY + roleId); - List list = roleSession.get(ROLE_PERMISSION_CACHE_KEY, () -> { - // 从数据库查询这个角色所拥有的权限列表 - return roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(Long.parseLong(roleId)), false) - .stream() - .filter(e -> MenuTypeEnum.POINTS.equalsValue(e.getMenuType())) - .map(MenuEntity::getApiPerms).filter(Objects::nonNull).distinct() - .collect(Collectors.toList()); - }); - permissionList.addAll(list); - } - // 返回权限集合 - return permissionList; - } - - @Override - public List getRoleList(Object loginId, String loginType) { - SaSession session = StpUtil.getSessionByLoginId(loginId); - // 查询员工关联角色缓存 - Long employeeId = TokenService.getUserId((String) loginId); - return session.get(USER_ROLE_CACHE_KEY, () -> { - // 数据库中查询员工角色 - return roleEmployeeService.getRoleIdList(employeeId).stream().map(String::valueOf).collect(Collectors.toList()); - }); - } - - /** - * 清理角色关联权限 缓存 - * - * @param roleId - */ - public static void clearRoleCache(Long roleId) { - SaSessionCustomUtil.deleteSessionById(ROLE_CACHE_KEY + roleId); - } - - /** - * 清理 员工关联角色 缓存 - * - * @param employeeId - */ - public static void clearUserRoleCache(Long employeeId) { - String loginId = TokenService.generateLoginId(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); - SaSession session = StpUtil.getSessionByLoginId(loginId, false); - if (null == session) { - return; - } - session.delete(USER_ROLE_CACHE_KEY); - } } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java index 3606d781..a315397d 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java @@ -206,12 +206,12 @@ public class EmployeeService { return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); } - boolean disableFlag = !employeeEntity.getDisabledFlag(); + boolean disableFlag=!employeeEntity.getDisabledFlag(); employeeEntity.setDisabledFlag(disableFlag); employeeDao.updateDisableFlag(employeeId, disableFlag); if (employeeEntity.getDisabledFlag()) { - tokenService.removeToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); } return ResponseDTO.ok(); @@ -240,7 +240,9 @@ public class EmployeeService { }).collect(Collectors.toList()); employeeManager.updateBatchById(deleteList); - tokenService.removeToken(employeeIdList, UserTypeEnum.ADMIN_EMPLOYEE); + for (Long employeeId : employeeIdList) { + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + } return ResponseDTO.ok(); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java index 92eda233..1d28888d 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java @@ -8,15 +8,17 @@ import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; import net.lab1024.sa.admin.module.system.login.domain.LoginForm; import net.lab1024.sa.admin.module.system.login.service.LoginService; import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.constant.RequestHeaderConst; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartRequestUtil; import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; @@ -38,38 +40,51 @@ public class LoginController { private LoginService loginService; @NoNeedLogin - @ApiOperation("登录 @author 卓大") @PostMapping("/login") - public ResponseDTO login(@Valid @RequestBody LoginForm loginForm, HttpServletRequest request) { + @ApiOperation("登录 @author 卓大") + public ResponseDTO login(@Valid @RequestBody LoginForm loginForm) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String ip = ServletUtil.getClientIP(request); String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT); return loginService.login(loginForm, ip, userAgent); } - @ApiOperation("刷新用户信息(包含用户基础信息、权限信息等等) @author 卓大") @GetMapping("/login/refresh") + @ApiOperation("刷新用户信息(包含用户基础信息、权限信息等等) @author 卓大") public ResponseDTO refresh() { - loginService.removeLoginUserDetailCache(SmartRequestUtil.getUserId()); + loginService.removeLoginUserDetailCache(SmartRequestUtil.getRequestUserId()); return ResponseDTO.ok(); } - @ApiOperation("获取登录结果信息 @author 卓大") @GetMapping("/login/getLoginInfo") + @ApiOperation("获取登录结果信息 @author 卓大") public ResponseDTO getLoginInfo() { - LoginEmployeeDetail loginEmployeeDetail = loginService.getLoginUserDetailCache(SmartRequestUtil.getUserId()); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); + } + + Object principal = authentication.getPrincipal(); + if (!(principal instanceof LoginEmployeeDetail)) { + return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); + } + + LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal(); + loginEmployeeDetail.setLoginPassword(null); return ResponseDTO.ok(loginEmployeeDetail); } - @ApiOperation("退出登录 @author 卓大") + @ApiOperation("退出登陆 @author 卓大") @GetMapping("/login/logout") - public ResponseDTO logout() { - return loginService.logout(SmartRequestUtil.getUser()); + public ResponseDTO logout(@RequestHeader(value = RequestHeaderConst.TOKEN, required = false) String token) { + return loginService.logout(token, SmartRequestUtil.getRequestUser()); } - @NoNeedLogin @ApiOperation("获取验证码 @author 卓大") @GetMapping("/login/getCaptcha") + @NoNeedLogin public ResponseDTO getCaptcha() { return loginService.getCaptcha(); } + } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java index 76b4dbea..a8be6eef 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java @@ -4,12 +4,17 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.enumeration.GenderEnum; import net.lab1024.sa.common.common.enumeration.UserTypeEnum; import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; import java.time.LocalDateTime; +import java.util.Collection; import java.util.List; +import java.util.Set; /** * 员工登录 @@ -21,7 +26,7 @@ import java.util.List; * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 */ @Data -public class LoginEmployeeDetail { +public class LoginEmployeeDetail implements UserDetails, RequestUser { @ApiModelProperty("token") private String token; @@ -73,4 +78,88 @@ public class LoginEmployeeDetail { @ApiModelProperty("请求user-agent") private String userAgent; + + /** + * security 权限串 + */ + private Set authorities; + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + @JsonIgnore + public String getPassword() { + return this.loginPassword; + } + + @Override + public String getUsername() { + return this.getLoginName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @Override + public boolean isAccountNonExpired() { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @Override + public boolean isAccountNonLocked() { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @Override + public boolean isEnabled() { + return true; + } + + @Override + public Long getUserId() { + return employeeId; + } + + @Override + public String getUserName() { + return actualName; + } + + @Override + public UserTypeEnum getUserType() { + return userType; + } + + @Override + public String getIp() { + return this.ip; + } + + @Override + public String getUserAgent() { + return this.userAgent; + } } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java index 7a859946..c7e9ffb3 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java @@ -24,8 +24,8 @@ import javax.validation.constraints.Pattern; @Data public class LoginForm extends CaptchaForm { - @ApiModelProperty("登录账号") - @NotBlank(message = "登录账号不能为空") + @ApiModelProperty("登录名") + @NotBlank(message = "登录名不能为空") @Length(max = 30, message = "登录账号最多30字符") private String loginName; @@ -34,7 +34,8 @@ public class LoginForm extends CaptchaForm { @Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "请输入6-15位密码(数字|大小写字母|小数点)") private String password; - @ApiModelPropertyEnum(desc = "登录终端", value = LoginDeviceEnum.class) - @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "登录终端类型错误") + @ApiModelProperty(value = "登录终端") + @ApiModelPropertyEnum(LoginDeviceEnum.class) + @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录") private Integer loginDevice; } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java index 96489fe0..95dafbe6 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java @@ -1,5 +1,6 @@ package net.lab1024.sa.admin.module.system.login.service; +import cn.hutool.extra.servlet.ServletUtil; import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; @@ -10,6 +11,7 @@ import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; import net.lab1024.sa.admin.module.system.login.domain.LoginForm; import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; import net.lab1024.sa.common.common.constant.StringConst; import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.domain.ResponseDTO; @@ -29,6 +31,7 @@ import net.lab1024.sa.common.module.support.token.TokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletRequest; import java.time.LocalDateTime; import java.util.List; import java.util.concurrent.ConcurrentMap; @@ -52,6 +55,9 @@ public class LoginService { @Autowired private DepartmentService departmentService; + @Autowired + private TokenService tokenService; + @Autowired private CaptchaService captchaService; @@ -64,9 +70,6 @@ public class LoginService { @Autowired private LoginLogService loginLogService; - @Autowired - private TokenService tokenService; - /** * 登录信息二级缓存 */ @@ -85,15 +88,17 @@ public class LoginService { * 员工登陆 * * @param loginForm - * @param ip - * @param userAgent * @return 返回用户登录信息 */ public ResponseDTO login(LoginForm loginForm, String ip, String userAgent) { + LoginDeviceEnum loginDeviceEnum = SmartEnumUtil.getEnumByValue(loginForm.getLoginDevice(), LoginDeviceEnum.class); + if (loginDeviceEnum == null) { + return ResponseDTO.userErrorParam("登录设备暂不支持!"); + } // 校验 图形验证码 ResponseDTO checkCaptcha = captchaService.checkCaptcha(loginForm); if (!checkCaptcha.getOk()) { - return ResponseDTO.error(checkCaptcha); + return ResponseDTO.error(checkCaptcha); } /** @@ -121,9 +126,8 @@ public class LoginService { } // 生成 登录token,保存token - boolean superPasswordFlag = superPassword.equals(requestPassword); - LoginDeviceEnum loginDeviceEnum = SmartEnumUtil.getEnumByValue(loginForm.getLoginDevice(), LoginDeviceEnum.class); - String token = tokenService.generateToken(employeeEntity.getEmployeeId(), employeeEntity.getActualName(), UserTypeEnum.ADMIN_EMPLOYEE, loginDeviceEnum); + Boolean superPasswordFlag = superPassword.equals(requestPassword); + String token = tokenService.generateToken(employeeEntity.getEmployeeId(), employeeEntity.getActualName(), UserTypeEnum.ADMIN_EMPLOYEE, loginDeviceEnum, superPasswordFlag); //获取员工登录信息 LoginEmployeeDetail loginEmployeeDetail = loadLoginInfo(employeeEntity); @@ -160,6 +164,8 @@ public class LoginService { List menuAndPointsList = employeePermissionService.getEmployeeMenuAndPointsList(employeeEntity.getEmployeeId(), employeeEntity.getAdministratorFlag()); //前端菜单 loginEmployeeDetail.setMenuList(menuAndPointsList); + //后端权限 + loginEmployeeDetail.setAuthorities(employeePermissionService.buildAuthorities(menuAndPointsList)); //上次登录信息 LoginLogVO loginLogVO = loginLogService.queryLastByUserId(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); @@ -193,15 +199,6 @@ public class LoginService { loginLogService.log(loginEntity); } - /** - * 查询用户信息缓存 - * - * @param requestUserId - */ - public LoginEmployeeDetail getLoginUserDetailCache(Long requestUserId) { - return loginUserDetailCache.get(requestUserId); - } - /** * 移除用户信息缓存 @@ -212,15 +209,48 @@ public class LoginService { loginUserDetailCache.remove(requestUserId); } + /** + * 根据登陆token 获取员请求工信息 + * + * @param + * @return + */ + public LoginEmployeeDetail getLoginUserDetail(String token, HttpServletRequest request) { + Long requestUserId = tokenService.getUserIdAndValidateToken(token); + if (requestUserId == null) { + return null; + } + // 查询用户信息 + LoginEmployeeDetail loginEmployeeDetail = loginUserDetailCache.get(requestUserId); + if (loginEmployeeDetail == null) { + // 员工基本信息 + EmployeeEntity employeeEntity = employeeService.getById(requestUserId); + if (employeeEntity == null) { + return null; + } + + loginEmployeeDetail = this.loadLoginInfo(employeeEntity); + loginEmployeeDetail.setToken(token); + loginUserDetailCache.put(requestUserId, loginEmployeeDetail); + } + + //更新请求ip和user agent + loginEmployeeDetail.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT)); + loginEmployeeDetail.setIp(ServletUtil.getClientIP(request)); + + return loginEmployeeDetail; + } + + /** * 退出登陆,清除token缓存 * * @return */ - public ResponseDTO logout(RequestUser requestUser) { + public ResponseDTO logout(String token, RequestUser requestUser) { loginUserDetailCache.remove(requestUser.getUserId()); - tokenService.removeToken(); - // 保存登出日志 + tokenService.removeToken(token); + //保存登出日志 saveLogoutLog(requestUser, requestUser.getIp(), requestUser.getUserAgent()); return ResponseDTO.ok(); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java index a32d183f..06c21540 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java @@ -1,8 +1,6 @@ package net.lab1024.sa.admin.module.system.menu.constant; -import lombok.AllArgsConstructor; -import lombok.Getter; import net.lab1024.sa.common.common.enumeration.BaseEnum; /** @@ -14,8 +12,6 @@ import net.lab1024.sa.common.common.enumeration.BaseEnum; * @Email lab1024@163.com * @Copyright 1024创新实验室 ( https://1024lab.net ) */ -@Getter -@AllArgsConstructor public enum MenuTypeEnum implements BaseEnum { /** * 目录 @@ -30,7 +26,23 @@ public enum MenuTypeEnum implements BaseEnum { */ POINTS(3, "功能点"); - private final Integer value; + private Integer value; - private final String desc; + private String desc; + + + MenuTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java index ff7a73ac..d0b921e7 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java @@ -14,6 +14,7 @@ import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartRequestUtil; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -38,22 +39,25 @@ public class MenuController extends AdminBaseController { @ApiOperation(value = "添加菜单 @author 卓大") @PostMapping("/menu/add") + @PreAuthorize("@saAuth.checkPermission('system:menu:add')") public ResponseDTO addMenu(@RequestBody @Valid MenuAddForm menuAddForm) { - menuAddForm.setCreateUserId(SmartRequestUtil.getUserId()); + menuAddForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); return menuService.addMenu(menuAddForm); } @ApiOperation(value = "更新菜单 @author 卓大") @PostMapping("/menu/update") + @PreAuthorize("@saAuth.checkPermission('system:menu:update')") public ResponseDTO updateMenu(@RequestBody @Valid MenuUpdateForm menuUpdateForm) { - menuUpdateForm.setUpdateUserId(SmartRequestUtil.getUserId()); + menuUpdateForm.setUpdateUserId(SmartRequestUtil.getRequestUserId()); return menuService.updateMenu(menuUpdateForm); } @ApiOperation(value = "批量删除菜单 @author 卓大") @GetMapping("/menu/batchDelete") + @PreAuthorize("@saAuth.checkPermission('system:menu:delete,system:menu:batch:delete')") public ResponseDTO batchDeleteMenu(@RequestParam("menuIdList") List menuIdList) { - return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getUserId()); + return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getRequestUserId()); } @ApiOperation(value = "查询菜单列表 @author 卓大") diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuCacheService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuCacheService.java deleted file mode 100644 index d8d5fbc2..00000000 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuCacheService.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.lab1024.sa.admin.module.system.menu.service; - -import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; -import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; -import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * 功能菜单业务 - * - * @author Turbolisten - * @date 2023/7/20 19:04 - */ -@Service -public class MenuCacheService { - - @Autowired - private MenuDao menuDao; - - private static volatile List MENU_URL_CACHE = null; - - /** - * 查询 需要校验权限的url - * - * @return - */ - public List queryNeedCheckPermissionsUrl() { - if (null != MENU_URL_CACHE) { - return MENU_URL_CACHE; - } - synchronized (MenuCacheService.class) { - if (null != MENU_URL_CACHE) { - return MENU_URL_CACHE; - } - // TODO listen 待确定哪个字段做为url - MENU_URL_CACHE = menuDao.queryMenuByType(MenuTypeEnum.POINTS.getValue(), false, false) - .stream() - .map(MenuEntity::getApiPerms) - .filter(Objects::nonNull) - .distinct() - .collect(Collectors.toList()); - return MENU_URL_CACHE; - } - } - - public static void clearCache() { - MENU_URL_CACHE = null; - } - -} diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java index 0b8f1bd6..4b3fa693 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java @@ -65,12 +65,6 @@ public class MenuService { menuEntity.setApiPerms(perms); } menuDao.insert(menuEntity); - - // 清除权限缓存 - if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) { - MenuCacheService.clearCache(); - } - return ResponseDTO.ok(); } @@ -108,11 +102,6 @@ public class MenuService { menuEntity.setApiPerms(perms); } menuDao.updateById(menuEntity); - - // 清除权限缓存 - if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) { - MenuCacheService.clearCache(); - } return ResponseDTO.ok(); } @@ -129,11 +118,8 @@ public class MenuService { return ResponseDTO.userErrorParam("所选菜单不能为空"); } menuDao.deleteByMenuIdList(menuIdList, employeeId, Boolean.TRUE); - // 子节点也需要删除 + //孩子节点也需要删除 this.recursiveDeleteChildren(menuIdList, employeeId); - - // 清除权限缓存 - MenuCacheService.clearCache(); return ResponseDTO.ok(); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java index c68f820a..4fcdc2d2 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java @@ -11,6 +11,7 @@ import net.lab1024.sa.admin.module.system.role.service.RoleService; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -35,18 +36,21 @@ public class RoleController extends AdminBaseController { @ApiOperation("添加角色 @author 卓大") @PostMapping("/role/add") + @PreAuthorize("@saAuth.checkPermission('system:role:add')") public ResponseDTO addRole(@Valid @RequestBody RoleAddForm roleAddForm) { return roleService.addRole(roleAddForm); } @ApiOperation("删除角色 @author 卓大") @GetMapping("/role/delete/{roleId}") + @PreAuthorize("@saAuth.checkPermission('system:role:delete')") public ResponseDTO deleteRole(@PathVariable Long roleId) { return roleService.deleteRole(roleId); } @ApiOperation("更新角色 @author 卓大") @PostMapping("/role/update") + @PreAuthorize("@saAuth.checkPermission('system:role:update')") public ResponseDTO updateRole(@Valid @RequestBody RoleUpdateForm roleUpdateDTO) { return roleService.updateRole(roleUpdateDTO); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java index 6f3f503f..a2814595 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.admin.module.system.role.service.RoleDataScopeService; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -40,6 +41,7 @@ public class RoleDataScopeController extends AdminBaseController { @ApiOperation(value = "批量设置某角色数据范围 @author 卓大") @PostMapping("/role/dataScope/updateRoleDataScopeList") + @PreAuthorize("@saAuth.checkPermission('system:role:dataScope:update')") public ResponseDTO updateRoleDataScopeList(@RequestBody @Valid RoleDataScopeUpdateForm roleDataScopeUpdateForm) { return roleDataScopeService.updateRoleDataScopeList(roleDataScopeUpdateForm); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java index d7f5dcea..19ad623c 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java @@ -13,6 +13,7 @@ import net.lab1024.sa.common.common.domain.PageResult; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -49,18 +50,21 @@ public class RoleEmployeeController extends AdminBaseController { @ApiOperation(value = "从角色成员列表中移除员工 @author 卓大") @GetMapping("/role/employee/removeEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:delete')") public ResponseDTO removeEmployee(Long employeeId, Long roleId) { return roleEmployeeService.removeRoleEmployee(employeeId, roleId); } @ApiOperation(value = "从角色成员列表中批量移除员工 @author 卓大") @PostMapping("/role/employee/batchRemoveRoleEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:batch:delete')") public ResponseDTO batchRemoveEmployee(@Valid @RequestBody RoleEmployeeUpdateForm updateForm) { return roleEmployeeService.batchRemoveRoleEmployee(updateForm); } @ApiOperation(value = "角色成员列表中批量添加员工 @author 卓大") @PostMapping("/role/employee/batchAddRoleEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:add')") public ResponseDTO addEmployeeList(@Valid @RequestBody RoleEmployeeUpdateForm addForm) { return roleEmployeeService.batchAddRoleEmployee(addForm); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java index b3afd048..02e7b8c3 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -33,6 +34,7 @@ public class RoleMenuController extends AdminBaseController { @ApiOperation("更新角色权限 @author 卓大") @PostMapping("/role/menu/updateRoleMenu") + @PreAuthorize("@saAuth.checkPermission('system:role:menu:update')") public ResponseDTO updateRoleMenu(@Valid @RequestBody RoleMenuUpdateForm updateDTO) { return roleMenuService.updateRoleMenu(updateDTO); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java index e5eb1ce1..51bf64d4 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java @@ -1,23 +1,23 @@ package net.lab1024.sa.admin.module.system.role.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; -import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; -import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; -import net.lab1024.sa.admin.module.system.employee.service.EmployeePermissionService; import net.lab1024.sa.admin.module.system.role.dao.RoleDao; import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; -import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeUpdateForm; import net.lab1024.sa.admin.module.system.role.domain.vo.RoleSelectedVO; -import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager; +import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.constant.StringConst; import net.lab1024.sa.common.common.domain.PageResult; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartBeanUtil; import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -90,9 +90,6 @@ public class RoleEmployeeService { return ResponseDTO.userErrorParam(); } roleEmployeeDao.deleteByEmployeeIdRoleId(employeeId, roleId); - - // 清理员工角色缓存 - EmployeePermissionService.clearUserRoleCache(employeeId); return ResponseDTO.ok(); } @@ -103,11 +100,7 @@ public class RoleEmployeeService { * @return ResponseDTO */ public ResponseDTO batchRemoveRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) { - List employeeIdList = roleEmployeeUpdateForm.getEmployeeIdList(); - roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), employeeIdList); - - // 清理员工角色缓存 - employeeIdList.forEach(EmployeePermissionService::clearUserRoleCache); + roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), roleEmployeeUpdateForm.getEmployeeIdList()); return ResponseDTO.ok(); } @@ -129,9 +122,6 @@ public class RoleEmployeeService { } // 保存数据 roleEmployeeManager.saveRoleEmployee(roleId, roleEmployeeList); - - // 清理员工角色缓存 - employeeIdList.forEach(EmployeePermissionService::clearUserRoleCache); return ResponseDTO.ok(); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java index 952e3a64..e93d106a 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java @@ -1,7 +1,6 @@ package net.lab1024.sa.admin.module.system.role.service; import com.google.common.collect.Lists; -import net.lab1024.sa.admin.module.system.employee.service.EmployeePermissionService; import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuSimpleTreeVO; @@ -68,10 +67,7 @@ public class RoleMenuService { roleMenuEntity.setMenuId(menuId); roleMenuEntityList.add(roleMenuEntity); } - roleMenuManager.updateRoleMenu(roleId, roleMenuEntityList); - - // 清理角色缓存 - EmployeePermissionService.clearRoleCache(roleId); + roleMenuManager.updateRoleMenu(roleMenuUpdateForm.getRoleId(), roleMenuEntityList); return ResponseDTO.ok(); } @@ -81,9 +77,9 @@ public class RoleMenuService { * @param roleIdList * @return */ - public List getMenuList(List roleIdList, Boolean adminFlag) { - // 超管返回所有菜单 - if(adminFlag){ + public List getMenuList(List roleIdList, Boolean administratorFlag) { + //管理员返回所有菜单 + if(administratorFlag){ List menuEntityList = roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(), false); return SmartBeanUtil.copyList(menuEntityList, MenuVO.class); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java index 4c1d9317..031d75e0 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java @@ -1,6 +1,5 @@ package net.lab1024.sa.admin.module.system.role.service; -import net.lab1024.sa.admin.module.system.employee.service.EmployeePermissionService; import net.lab1024.sa.admin.module.system.role.dao.RoleDao; import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; @@ -69,9 +68,6 @@ public class RoleService { roleDao.deleteById(roleId); roleMenuDao.deleteByRoleId(roleId); roleEmployeeDao.deleteByRoleId(roleId); - - // 清理角色缓存 - EmployeePermissionService.clearRoleCache(roleId); return ResponseDTO.ok(); } diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java index e3522075..492a063b 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java @@ -7,6 +7,7 @@ import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.constant.SwaggerTagConst; import net.lab1024.sa.common.module.support.cache.CacheService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @@ -37,6 +38,7 @@ public class AdminCacheController extends SupportBaseController { @ApiOperation(value = "移除某个缓存 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('support:cache:delete')") @GetMapping("/cache/remove/{cacheName}") public ResponseDTO removeCache(@PathVariable String cacheName) { cacheService.removeCache(cacheName); @@ -45,6 +47,7 @@ public class AdminCacheController extends SupportBaseController { @ApiOperation(value = "获取某个缓存的所有key @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('support:cache:keys')") @GetMapping("/cache/keys/{cacheName}") public ResponseDTO> cacheKeys(@PathVariable String cacheName) { return ResponseDTO.ok(cacheService.cacheKey(cacheName)); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java index ea7229e9..7c4b1eec 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java @@ -9,6 +9,7 @@ import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogAddFo import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogUpdateForm; import net.lab1024.sa.common.module.support.changelog.service.ChangeLogService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -30,23 +31,27 @@ public class AdminChangeLogController { @ApiOperation("添加 @author 卓大") @PostMapping("/changeLog/add") + @PreAuthorize("@saAuth.checkPermission('changeLog:add')") public ResponseDTO add(@RequestBody @Valid ChangeLogAddForm addForm) { return changeLogService.add(addForm); } @ApiOperation("更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:update')") @PostMapping("/changeLog/update") public ResponseDTO update(@RequestBody @Valid ChangeLogUpdateForm updateForm) { return changeLogService.update(updateForm); } @ApiOperation("批量删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:batchDelete')") @PostMapping("/changeLog/batchDelete") public ResponseDTO batchDelete(@RequestBody ValidateList idList) { return changeLogService.batchDelete(idList); } @ApiOperation("单个删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:delete')") @GetMapping("/changeLog/delete/{changeLogId}") public ResponseDTO batchDelete(@PathVariable Long changeLogId) { return changeLogService.delete(changeLogId); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java index c16ac0bc..78ab1722 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java @@ -12,6 +12,7 @@ import net.lab1024.sa.common.module.support.config.domain.ConfigQueryForm; import net.lab1024.sa.common.module.support.config.domain.ConfigUpdateForm; import net.lab1024.sa.common.module.support.config.domain.ConfigVO; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -35,18 +36,21 @@ public class AdminConfigController extends SupportBaseController { private ConfigService configService; @ApiOperation("分页查询系统配置 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:query')") @PostMapping("/config/query") public ResponseDTO> querySystemConfigPage(@RequestBody @Valid ConfigQueryForm queryForm) { return configService.queryConfigPage(queryForm); } @ApiOperation("添加配置参数 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:add')") @PostMapping("/config/add") public ResponseDTO addSystemConfig(@RequestBody @Valid ConfigAddForm configAddForm) { return configService.add(configAddForm); } @ApiOperation("修改配置参数 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:update')") @PostMapping("/config/update") public ResponseDTO updateSystemConfig(@RequestBody @Valid ConfigUpdateForm updateForm) { return configService.updateSystemConfig(updateForm); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java index 0eea2e12..b4528715 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; import net.lab1024.sa.common.module.support.file.service.FileService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -33,6 +34,7 @@ public class AdminFileController extends SupportBaseController { private FileService fileService; @ApiOperation("分页查询 @author 1024创新实验室-主任-卓大") + @PreAuthorize("@saAuth.checkPermission('support:file:query')") @PostMapping("/file/queryPage") public ResponseDTO> queryPage(@RequestBody @Valid FileQueryForm queryForm) { return ResponseDTO.ok(fileService.queryPage(queryForm)); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java index 68ee6557..5d0949e2 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java @@ -13,6 +13,7 @@ import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocCatalogServic import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocService; import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -41,12 +42,14 @@ public class AdminHelpDocController extends SupportBaseController { @ApiOperation("帮助文档目录-添加 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDocCatalog:addCategory')") @PostMapping("/helpDoc/helpDocCatalog/add") public ResponseDTO addHelpDocCatalog(@RequestBody @Valid HelpDocCatalogAddForm helpDocCatalogAddForm) { return helpDocCatalogService.add(helpDocCatalogAddForm); } @ApiOperation("帮助文档目录-更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDocCatalog:edit')") @PostMapping("/helpDoc/helpDocCatalog/update") public ResponseDTO updateHelpDocCatalog(@RequestBody @Valid HelpDocCatalogUpdateForm helpDocCatalogUpdateForm) { return helpDocCatalogService.update(helpDocCatalogUpdateForm); @@ -61,6 +64,7 @@ public class AdminHelpDocController extends SupportBaseController { // --------------------- 帮助文档 【管理:增、删、查、改】------------------------- @ApiOperation("【管理】帮助文档-分页查询 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:query')") @PostMapping("/helpDoc/query") public ResponseDTO> query(@RequestBody @Valid HelpDocQueryForm queryForm) { return ResponseDTO.ok(helpDocService.query(queryForm)); @@ -73,6 +77,7 @@ public class AdminHelpDocController extends SupportBaseController { } @ApiOperation("【管理】帮助文档-添加 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:add')") @PostMapping("/helpDoc/add") @RepeatSubmit public ResponseDTO add(@RequestBody @Valid HelpDocAddForm addForm) { @@ -80,6 +85,7 @@ public class AdminHelpDocController extends SupportBaseController { } @ApiOperation("【管理】帮助文档-更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:update')") @PostMapping("/helpDoc/update") @RepeatSubmit public ResponseDTO update(@RequestBody @Valid HelpDocUpdateForm updateForm) { @@ -87,6 +93,7 @@ public class AdminHelpDocController extends SupportBaseController { } @ApiOperation("【管理】帮助文档-删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:delete')") @GetMapping("/helpDoc/delete/{helpDocId}") public ResponseDTO delete(@PathVariable Long helpDocId) { return helpDocService.delete(helpDocId); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java index ca2a52c1..0fd71522 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.common.module.support.loginlog.LoginLogService; import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogQueryForm; import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogVO; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -31,6 +32,7 @@ public class AdminLoginLogController extends SupportBaseController { private LoginLogService loginLogService; @ApiOperation(value = "分页查询 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('loginLog:query')") @PostMapping("/loginLog/page/query") public ResponseDTO> queryByPage(@RequestBody LoginLogQueryForm queryForm) { return loginLogService.queryByPage(queryForm); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java index c4c2b313..85161a6f 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.common.module.support.operatelog.OperateLogService; import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogQueryForm; import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogVO; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; /** @@ -29,12 +30,14 @@ public class AdminOperateLogController extends SupportBaseController { private OperateLogService operateLogService; @ApiOperation(value = "分页查询 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('operateLog:query')") @PostMapping("/operateLog/page/query") public ResponseDTO> queryByPage(@RequestBody OperateLogQueryForm queryForm) { return operateLogService.queryByPage(queryForm); } @ApiOperation(value = "详情 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('operateLog:detail')") @GetMapping("/operateLog/detail/{operateLogId}") public ResponseDTO detail(@PathVariable Long operateLogId) { return operateLogService.detail(operateLogId); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java index c0eb99ac..24637f6e 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java @@ -10,6 +10,7 @@ import net.lab1024.sa.common.module.support.reload.domain.ReloadForm; import net.lab1024.sa.common.module.support.reload.domain.ReloadItemVO; import net.lab1024.sa.common.module.support.reload.domain.ReloadResultVO; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -38,12 +39,14 @@ public class AdminReloadController extends SupportBaseController { } @ApiOperation(value = "获取reload result @author 开云") + @PreAuthorize("@saAuth.checkPermission('support:reload:result')") @GetMapping("/reload/result/{tag}") public ResponseDTO> queryReloadResult(@PathVariable("tag") String tag) { return reloadService.queryReloadItemResult(tag); } @ApiOperation(value = "通过tag更新标识 @author 开云") + @PreAuthorize("@saAuth.checkPermission('support:reload:execute')") @PostMapping("/reload/update") public ResponseDTO updateByTag(@RequestBody @Valid ReloadForm reloadForm) { return reloadService.updateByTag(reloadForm); diff --git a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java index d6e39c2a..329a2aaf 100644 --- a/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java +++ b/smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java @@ -16,6 +16,7 @@ import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberReco import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberRecordService; import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -47,6 +48,7 @@ public class AdminSerialNumberController extends SupportBaseController { private SerialNumberRecordService serialNumberRecordService; @ApiOperation("生成单号 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:serial:number:generate')") @PostMapping("/serialNumber/generate") public ResponseDTO> generate(@RequestBody @Valid SerialNumberGenerateForm generateForm) { SerialNumberIdEnum serialNumberIdEnum = SmartEnumUtil.getEnumByValue(generateForm.getSerialNumberId(), SerialNumberIdEnum.class); @@ -63,6 +65,7 @@ public class AdminSerialNumberController extends SupportBaseController { } @ApiOperation("获取生成记录 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:serial:number:record')") @PostMapping("/serialNumber/queryRecord") public ResponseDTO> queryRecord(@RequestBody @Valid SerialNumberRecordQueryForm queryForm) { return ResponseDTO.ok(serialNumberRecordService.query(queryForm)); diff --git a/smart-admin-api/sa-common/pom.xml b/smart-admin-api/sa-common/pom.xml index 84b1161e..6a5d2b38 100644 --- a/smart-admin-api/sa-common/pom.xml +++ b/smart-admin-api/sa-common/pom.xml @@ -49,19 +49,12 @@
- + - cn.dev33 - sa-token-spring-boot-starter + org.springframework.boot + spring-boot-starter-security - - cn.dev33 - sa-token-redis-jackson - - - - org.springframework.boot spring-boot-starter-log4j2 diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java new file mode 100644 index 00000000..4d44a2f7 --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.common.common.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 校验权限注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface SaAuth { + + String saAuth = "saAuth"; +} diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java index 7c71de96..6178661a 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java @@ -24,7 +24,7 @@ public enum UserErrorCode implements ErrorCode { REPEAT_SUBMIT(30004, "亲~您操作的太快了,请稍等下再操作~"), - NO_PERMISSION(30005, "对不起,您无法访问此内容哦~"), + NO_PERMISSION(30005, "对不起,您无法访问此资源哦~"), DEVELOPING(30006, "系統正在紧急开发中,敬请期待~"), @@ -32,11 +32,7 @@ public enum UserErrorCode implements ErrorCode { USER_STATUS_ERROR(30008, "用户状态异常"), - FORM_REPEAT_SUBMIT(30009, "请勿重复提交"), - - LOGIN_FROM_OTHER(30010, "您的账号已在其他地方登录"), - - ; + FORM_REPEAT_SUBMIT(30009, "请勿重复提交"); private final int code; diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java index 0dcaf849..2a40152d 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java @@ -26,11 +26,6 @@ public class StringConst { */ public static final String HORIZONTAL = "-"; - /** - * 全局通用 冒号 - */ - public static final String COLON = ":"; - /** * 全局通用分隔符 */ diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java index 3bdca030..3b8e0be3 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java @@ -18,6 +18,9 @@ public class RequestUrlVO { @ApiModelProperty("注释说明") private String comment; + @ApiModelProperty("controller.method") + private String name; + @ApiModelProperty("url") private String url; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java index 3d295eca..afce6da7 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java @@ -1,11 +1,9 @@ package net.lab1024.sa.common.common.domain; -import lombok.Data; import net.lab1024.sa.common.common.enumeration.UserTypeEnum; /** * 请求用户 - * 多系统用户 可以继承此类 * * @Author 1024创新实验室-主任: 卓大 * @Date 2021-12-21 19:55:07 @@ -13,25 +11,39 @@ import net.lab1024.sa.common.common.enumeration.UserTypeEnum; * @Email lab1024@163.com * @Copyright 1024创新实验室 ( https://1024lab.net ) */ -@Data -public class RequestUser { +public interface RequestUser { /** - * 当前请求用户id + * 请求用户id + * + * @return */ - private Long userId; + Long getUserId(); /** - * 当前请求用户名称 + * 请求用户名称 + * + * @return */ - private String userName; + String getUserName(); /** - * 当前请求用户类型 + * 获取用户类型 */ - private UserTypeEnum userType; + UserTypeEnum getUserType(); - private String ip; + /** + * 获取请求的IP + * + * @return + */ + String getIp(); + + /** + * 获取请求 user-agent + * + * @return + */ + String getUserAgent(); - private String userAgent; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnv.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java similarity index 76% rename from smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnv.java rename to smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java index 4a709a25..8cf4b845 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnv.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java @@ -3,7 +3,7 @@ package net.lab1024.sa.common.common.domain; import lombok.AllArgsConstructor; import lombok.Getter; -import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; /** * 系统环境 @@ -16,7 +16,7 @@ import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; */ @AllArgsConstructor @Getter -public class SystemEnv { +public class SystemEnvironment { /** * 是否位生产环境 @@ -31,5 +31,5 @@ public class SystemEnv { /** * 当前环境 */ - private SystemEnvEnum currentEnv; + private SystemEnvironmentEnum currentEnvironment; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvEnum.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java similarity index 67% rename from smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvEnum.java rename to smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java index 6889107d..bccaecbd 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvEnum.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java @@ -15,32 +15,32 @@ import lombok.Getter; */ @AllArgsConstructor @Getter -public enum SystemEnvEnum implements BaseEnum { +public enum SystemEnvironmentEnum implements BaseEnum { /** * dev */ - DEV(EnvConst.DEV, "开发环境"), + DEV(SystemEnvironmentNameConst.DEV, "开发环境"), /** * test */ - TEST(EnvConst.TEST, "测试环境"), + TEST(SystemEnvironmentNameConst.TEST, "测试环境"), /** * pre */ - PRE(EnvConst.PRE, "预发布环境"), + PRE(SystemEnvironmentNameConst.PRE, "预发布环境"), /** * prod */ - PROD(EnvConst.PROD, "生产环境"); + PROD(SystemEnvironmentNameConst.PROD, "生产环境"); private final String value; private final String desc; - public static final class EnvConst { + public static final class SystemEnvironmentNameConst { public static final String DEV = "dev"; public static final String TEST = "test"; public static final String PRE = "pre"; diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java index ff95a981..c34670b9 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java @@ -1,8 +1,5 @@ package net.lab1024.sa.common.common.enumeration; -import lombok.AllArgsConstructor; -import lombok.Getter; - /** * 用户类型 * @@ -12,16 +9,29 @@ import lombok.Getter; * @Email lab1024@163.com * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 */ -@Getter -@AllArgsConstructor public enum UserTypeEnum implements BaseEnum { /** * 管理端 员工用户 */ - ADMIN_EMPLOYEE(1, "管理端-员工"); + ADMIN_EMPLOYEE(1, "员工"); - private final Integer value; + private Integer type; - private final String desc; + private String desc; + + UserTypeEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + @Override + public Integer getValue() { + return type; + } + + @Override + public String getDesc() { + return desc; + } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java index 9abc3465..62f2042d 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java @@ -1,27 +1,17 @@ package net.lab1024.sa.common.common.interceptor; -import cn.dev33.satoken.exception.NotLoginException; -import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.stp.StpUtil; -import cn.hutool.extra.servlet.ServletUtil; import com.alibaba.fastjson.JSONObject; -import com.google.common.collect.Lists; import net.lab1024.sa.common.common.annoation.NoNeedLogin; import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.constant.RequestHeaderConst; import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.domain.ResponseDTO; -import net.lab1024.sa.common.common.domain.SystemEnv; -import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; -import net.lab1024.sa.common.common.enumeration.UserTypeEnum; import net.lab1024.sa.common.common.util.SmartRequestUtil; -import net.lab1024.sa.common.module.support.token.TokenService; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; +import org.springframework.util.CollectionUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; @@ -29,56 +19,48 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; +import java.util.function.Function; /** * 抽象拦截器 - * 只校验了登录处理 - * 自定义的拦截器 可以继承此类 * - * @author huke - * @date 2023-07-12 21:56:14 + * @Author 1024创新实验室: 罗伊 + * @Date 2021-10-09 20:56:14 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) */ public abstract class AbstractInterceptor implements HandlerInterceptor { @Autowired - private SystemEnv systemEnv; + private List ignoreUrlList; + /** - * 校验 token + * Token获取用户信息 * - * @param userId + * @return */ - public abstract RequestUser getDevUser(Long userId); - - /** - * 校验 当前服务用户类型 - */ - public abstract UserTypeEnum getUserType(); + protected abstract Function userFunction(); /** * 拦截路径 * * @return */ - public abstract List pathPatterns(); + public abstract String[] pathPatterns(); /** * 忽略的url集合 * * @return */ - public List getIgnoreUrlList() { - List ignoreUrlList = Lists.newArrayList(); - ignoreUrlList.add("/swagger-ui.html"); - ignoreUrlList.add("/swagger-resources/**"); - ignoreUrlList.add("/webjars/**"); - ignoreUrlList.add("/druid/**"); - ignoreUrlList.add("/*/api-docs"); + protected List getIgnoreUrlList() { return ignoreUrlList; } /** - * 拦截处理登录 token + * 拦截服务器端响应处理ajax请求返回结果 * * @param request * @param response @@ -89,81 +71,60 @@ public abstract class AbstractInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // OPTIONS请求直接return - if (StringUtils.equalsIgnoreCase(HttpMethod.OPTIONS.name(), request.getMethod())) { + if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { response.setStatus(HttpStatus.NO_CONTENT.value()); return false; } + boolean isHandler = handler instanceof HandlerMethod; if (!isHandler) { return true; } - // 校验 token - ResponseDTO res = this.checkTokenAndGetUser(request); - if (res.getOk()) { - SmartRequestUtil.setUser(res.getData()); + //放行的Uri前缀 + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + String target = uri.replaceFirst(contextPath, ""); + if (this.contain(this.getIgnoreUrlList(), target)) { return true; } - // 不需要登录 + //不需要登录 NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class); + // 检查是否包含 token + String xRequestToken = request.getParameter(RequestHeaderConst.TOKEN); + String xHeaderToken = request.getHeader(RequestHeaderConst.TOKEN); + String xAccessToken = StringUtils.isNotBlank(xRequestToken) ? xRequestToken : xHeaderToken; + // 包含token 则获取用户信息 并保存 + if (StringUtils.isNotBlank(xAccessToken)) { + RequestUser requestUser = userFunction().apply(xAccessToken); + if (requestUser != null) { + SmartRequestUtil.setRequestUser(requestUser); + } + // 有token 无需登录 + if (null != noNeedLogin) { + return true; + } + } + // 无token 无需登录 if (null != noNeedLogin) { return true; } - this.outputResult(response, res); - return false; + if (StringUtils.isBlank(xAccessToken)) { + this.outputResult(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID)); + return false; + } + return true; } - /** - * 判断 sa-token 未登录场景值 - * 自己根据业务在下面 switch 添加分支判断 - * NotLoginException.NOT_TOKEN 无token - * NotLoginException.INVALID_TOKEN token无效 - * NotLoginException.TOKEN_TIMEOUT token过期 - * NotLoginException.NO_PREFIX token缺少前缀 - * NotLoginException.KICK_OUT 已被踢下线 - * NotLoginException.TOKEN_FREEZE 已被冻结 - *

- * ps :之所以没有在全局异常里处理 是因为后续还有操作 - */ - public ResponseDTO checkTokenAndGetUser(HttpServletRequest request) { - /** - * 处理【非生产环境】的测试 token ,便于开发调试 - * 如不需要 可以删除此段判断代码 - */ - if (SystemEnvEnum.PROD != systemEnv.getCurrentEnv()) { - String tokenValue = StpUtil.getTokenValue(); - if (NumberUtils.isDigits(tokenValue)) { - RequestUser user = this.getDevUser(NumberUtils.createLong(tokenValue)); - this.handleRequestIpAndAgent(user, request); - // sa token 登录身份临时切换 - StpUtil.switchTo(TokenService.generateLoginId(user.getUserId(), user.getUserType())); - return ResponseDTO.ok(user); + public Boolean contain(List ignores, String uri) { + if (CollectionUtils.isEmpty(ignores)) { + return false; + } + for (String ignoreUrl : ignores) { + if (uri.startsWith(ignoreUrl)) { + return true; } } - - try { - /** - * sa-token 会从当前请求 header or body 中获取token - * 检验当前会话是否已经登录, 如果未登录,则抛出异常:`NotLoginException` - */ - StpUtil.checkLogin(); - } catch (NotLoginException e) { - switch (e.getType()) { - case NotLoginException.BE_REPLACED: - // token 已被顶下线 - return ResponseDTO.error(UserErrorCode.LOGIN_FROM_OTHER); - // case NotLoginException.TOKEN_FREEZE: - // case NotLoginException.KICK_OUT: - default: - return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); - } - } - // 校验token的用户类型 - UserTypeEnum systemUserTypeEnum = this.getUserType(); - RequestUser user = this.buildCurrentUser(request); - if (null == user || systemUserTypeEnum != user.getUserType()) { - return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); - } - return ResponseDTO.ok(user); + return false; } /** @@ -175,40 +136,13 @@ public abstract class AbstractInterceptor implements HandlerInterceptor { */ private void outputResult(HttpServletResponse response, ResponseDTO responseDTO) throws IOException { String msg = JSONObject.toJSONString(responseDTO); - response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(msg); response.flushBuffer(); } - /** - * build 当前请求用户 - * - * @param request - * @return - */ - public RequestUser buildCurrentUser(HttpServletRequest request) { - // 获取额外数据 - SaSession session = StpUtil.getSession(); - UserTypeEnum userTypeEnum = (UserTypeEnum) session.get(TokenService.EXTRA_KEY_USER_TYPE); - String userName = session.getString(TokenService.EXTRA_KEY_USER_NAME); - - // 当前请求对象 - RequestUser user = new RequestUser(); - user.setUserId(TokenService.getUserId((String) StpUtil.getLoginId())); - user.setUserName(userName); - user.setUserType(userTypeEnum); - this.handleRequestIpAndAgent(user, request); - return user; - } - - /** - * 设置 当前请求ip agent - * - * @param requestUser - * @param request - */ - private void handleRequestIpAndAgent(RequestUser requestUser, HttpServletRequest request) { - requestUser.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT)); - requestUser.setIp(ServletUtil.getClientIP(request)); + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + SmartRequestUtil.remove(); } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java new file mode 100644 index 00000000..30fc239b --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java @@ -0,0 +1,93 @@ +package net.lab1024.sa.common.common.security; + +import org.springframework.beans.factory.annotation.Autowired; +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.UserDetails; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.filter.CorsFilter; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Spring Security + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/3 17:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class AbstractSecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private CorsFilter corsFilter; + + @Autowired + private List noNeedLoginUrlList; + + @Autowired + private List ignoreUrlList; + + /** + * Token获取用户信息 + * + * @return + */ + protected abstract BiFunction userFunction(); + + /** + * 需要认证的url集合 + * + * @return + */ + protected abstract String[] getAuthenticatedUrlPatterns(); + + /** + * 不需要登录的url集合 + * + * @return + */ + protected String[] getNoNeedLoginUrl() { + return noNeedLoginUrlList.toArray(new String[noNeedLoginUrlList.size()]); + } + + /** + * 忽略的url集合 + * + * @return + */ + protected String[] getIgnoreUrlList() { + return ignoreUrlList.toArray(new String[ignoreUrlList.size()]); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity + // CSRF禁用,因为不使用session + .csrf().disable() + // 认证失败处理类 + .exceptionHandling().authenticationEntryPoint(new SecurityAuthenticationFailHandler()).and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + // 过滤请求 + .authorizeRequests() + //忽略的url + .antMatchers(this.getIgnoreUrlList()).permitAll() + // 不需要登陆的url + .antMatchers(this.getNoNeedLoginUrl()).permitAll() + //需要校验权限的url + .antMatchers(getAuthenticatedUrlPatterns()).authenticated(); + + // token filter 进行校验 + httpSecurity.addFilterBefore(new SecurityTokenFilter(this.userFunction()), UsernamePasswordAuthenticationFilter.class); + httpSecurity.addFilterBefore(corsFilter, SecurityTokenFilter.class); + // 禁用spring security 使用 X-Frame-Options防止网页被Frame + httpSecurity.headers().frameOptions().disable(); + + } + + +} diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java new file mode 100644 index 00000000..3e146f18 --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.common.common.security; + +import com.alibaba.fastjson.JSONObject; +import net.lab1024.sa.common.common.code.ErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 登录认证失败处理 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-08-26 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SecurityAuthenticationFailHandler implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException { + this.outputResult(response, UserErrorCode.LOGIN_STATE_INVALID); + } + + /** + * 输出 + * + * @param response + * @param errorCode + * @throws IOException + */ + private void outputResult(HttpServletResponse response, ErrorCode errorCode) throws IOException { + String msg = JSONObject.toJSONString(ResponseDTO.error(errorCode)); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write(msg); + response.flushBuffer(); + } +} diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java new file mode 100644 index 00000000..290b3d9c --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.common.common.security; + +import net.lab1024.sa.common.common.annoation.SaAuth; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.prepost.PreInvocationAttribute; +import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource; +import org.springframework.security.access.prepost.PrePostInvocationAttributeFactory; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; + +/** + * 此类用于默认给所有接口添加权限 @saAuth.checkPermission('%s') + * %s 为类名.方法名 + * 和使用@PreAuthorize("@saAuth.checkPermission('%s')") 效果一致 + * 避免所有接口都添加一遍 减轻工作量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-08-30 23:08 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SecurityMethodSource extends PrePostAnnotationSecurityMetadataSource { + + + private static String EXPRESSION_FORMAT = "@%s.checkPermission('%s')"; + + private final PrePostInvocationAttributeFactory attributeFactory; + + private String beanName; + + + public SecurityMethodSource(PrePostInvocationAttributeFactory attributeFactory, String beanName) { + super(attributeFactory); + this.attributeFactory = attributeFactory; + this.beanName = beanName; + } + + + @Override + public Collection getAttributes(Method method, Class targetClass) { + //如果不存在SaAuth采用security认证模式 + SaAuth saAuth = method.getAnnotation(SaAuth.class); + if (saAuth == null) { + return super.getAttributes(method, targetClass); + } + + //存在添加以URL为权限字符串的校验模式 + ArrayList configAttributes = new ArrayList(1); + String classFullName = targetClass.getName(); + String methodName = method.getName(); + String[] classNameArray = StringUtils.split(classFullName, "\\."); + String controllerName = classNameArray[classNameArray.length - 1]; + String privilegeName = controllerName + "." + methodName; + String preAuthorizeAttribute = String.format(EXPRESSION_FORMAT, beanName, privilegeName); + PreInvocationAttribute pre = this.attributeFactory.createPreInvocationAttribute(null, null, preAuthorizeAttribute); + if (pre != null) { + configAttributes.add(pre); + } + return configAttributes; + } + +} diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java new file mode 100644 index 00000000..29e46559 --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.common.common.security; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 校验权限 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/12 21:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class SecurityPermissionCheckService { + + + /** + * 校验是否有权限 + * + * @param permission + * @return + */ + public boolean checkPermission(String permission) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return false; + } + return checkPermission(authentication, permission); + } + + /** + * 校验是否有权限 + * + * @param authentication + * @param permission + * @return + */ + public abstract boolean checkPermission(Authentication authentication, String permission); + + /** + * 判断 + * + * @param userDetails + * @param permissionStr + * @return + */ + protected boolean permissionJudge(UserDetails userDetails, String permissionStr) { + if (CollectionUtils.isEmpty(userDetails.getAuthorities())) { + return false; + } + + if (StringUtils.isBlank(permissionStr)) { + return false; + } + + String[] permissionArray = permissionStr.split(","); + for (String permission : permissionArray) { + if(userDetails.getAuthorities().contains(new SimpleGrantedAuthority(permission))){ + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java new file mode 100644 index 00000000..1a2ef97e --- /dev/null +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java @@ -0,0 +1,64 @@ +package net.lab1024.sa.common.common.security; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +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; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * 注意此处不能 加入@Component,否则对应ignoreUrl的相关请求 将会进入此Filter,并会覆盖CorsFilter + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/12 21:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SecurityTokenFilter extends OncePerRequestFilter { + + private BiFunction userFunction; + + public SecurityTokenFilter(BiFunction userFunction) { + this.userFunction = userFunction; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + //需要做token校验, 消息头的token优先于请求query参数的token + String xHeaderToken = request.getHeader(RequestHeaderConst.TOKEN); + String xRequestToken = request.getParameter(RequestHeaderConst.TOKEN); + String xAccessToken = null != xHeaderToken ? xHeaderToken : xRequestToken; + if (StringUtils.isBlank(xAccessToken)) { + chain.doFilter(request, response); + return; + } + //清理spring security + SecurityContextHolder.clearContext(); + + UserDetails loginUserDetail = userFunction.apply(xAccessToken,request); + if (null != loginUserDetail) { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUserDetail, null, loginUserDetail.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + SmartRequestUtil.setRequestUser((RequestUser) loginUserDetail); + } + // 若未给予spring security上下文用户授权 则会授权失败 进入AuthenticationEntryPointImpl + chain.doFilter(request, response); + } +} diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java index 5e139e25..40210ba2 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java @@ -1,7 +1,6 @@ package net.lab1024.sa.common.common.util; -import cn.dev33.satoken.context.SaHolder; -import cn.dev33.satoken.context.model.SaStorage; +import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.common.common.domain.RequestUser; /** @@ -13,28 +12,26 @@ import net.lab1024.sa.common.common.domain.RequestUser; * @Email lab1024@163.com * @Copyright 1024创新实验室 ( https://1024lab.net ) */ +@Slf4j public class SmartRequestUtil { - private static final String STORAGE_KEY = "user"; + private static final ThreadLocal requestThreadLocal = new ThreadLocal<>(); - public static void setUser(RequestUser user) { - SaStorage storage = SaHolder.getStorage(); - storage.set(STORAGE_KEY, user); + public static void setRequestUser(RequestUser requestUser) { + requestThreadLocal.set(requestUser); } - /** - * 获取 当前 token 请求用户 - * - * @return - */ - public static RequestUser getUser() { - SaStorage storage = SaHolder.getStorage(); - return storage.getModel(STORAGE_KEY, RequestUser.class); + public static RequestUser getRequestUser() { + return requestThreadLocal.get(); } - public static Long getUserId() { - RequestUser user = getUser(); - return null != user ? user.getUserId() : null; + public static Long getRequestUserId() { + RequestUser requestUser = getRequestUser(); + return null == requestUser ? null : requestUser.getUserId(); + } + + public static void remove() { + requestThreadLocal.remove(); } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java index 3d4b0bd6..cb937a0b 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java @@ -153,7 +153,7 @@ public class DataSourceConfig { * * @return */ - @Conditional(SystemEnvConfig.class) + @Conditional(SystemEnvironmentConfig.class) @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean<>(); diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java index 494e6f8d..c08339c9 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java @@ -1,19 +1,16 @@ package net.lab1024.sa.common.config; -import cn.dev33.satoken.interceptor.SaInterceptor; -import com.google.common.collect.Sets; import net.lab1024.sa.common.common.interceptor.AbstractInterceptor; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.util.ArrayList; import java.util.List; -import java.util.Set; /** * web相关配置 @@ -28,28 +25,16 @@ import java.util.Set; public class MvcConfig implements WebMvcConfigurer { @Autowired(required = false) - private List interceptorList; - - @Autowired(required = false) - private List saInterceptorList; + private List interceptorList; @Override - public void addInterceptors(InterceptorRegistry registry) { - // 先注册 登录拦截器 - Set ignoreUrlSet = Sets.newHashSet(); - if (CollectionUtils.isNotEmpty(interceptorList)) { - interceptorList.forEach(e -> { - ignoreUrlSet.addAll(e.getIgnoreUrlList()); - registry.addInterceptor(e).addPathPatterns(e.pathPatterns()).excludePathPatterns(e.getIgnoreUrlList()); - }); - } - - // 后注册 sa-token 权限拦截器 不需要可以删除 - if (CollectionUtils.isNotEmpty(saInterceptorList)) { - saInterceptorList.forEach(i -> { - registry.addInterceptor(i).addPathPatterns("/**").excludePathPatterns(new ArrayList<>(ignoreUrlSet)); - }); + public void addInterceptors (InterceptorRegistry registry) { + if (CollectionUtils.isEmpty(interceptorList)) { + return; } + interceptorList.forEach(e->{ + registry.addInterceptor(e).addPathPatterns("/**"); + }); } @Override diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java index 9f4083c3..fcfdd5ee 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java @@ -31,7 +31,7 @@ public class RepeatSubmitConfig { * @return */ private String ticket(String servletPath) { - Long userId = SmartRequestUtil.getUserId(); + Long userId = SmartRequestUtil.getRequestUserId(); if (null == userId) { return StringConst.EMPTY; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java index 60cff6a0..901b9246 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java @@ -57,7 +57,7 @@ import java.util.Map; @Slf4j @EnableSwagger2 @Configuration -@Conditional(SystemEnvConfig.class) +@Conditional(SystemEnvironmentConfig.class) public class SwaggerConfig implements EnvironmentAware, BeanDefinitionRegistryPostProcessor { /** @@ -198,7 +198,7 @@ public class SwaggerConfig implements EnvironmentAware, BeanDefinitionRegistryPo Parameter token = new ParameterBuilder().name(RequestHeaderConst.TOKEN) .description("token") .modelRef(new ModelRef("string")) - .parameterType("header").defaultValue("0") + .parameterType("header").defaultValue("1") .required(false) .build(); return Lists.newArrayList(token); diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java similarity index 69% rename from smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvConfig.java rename to smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java index bc6b747e..1af9577a 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java @@ -1,7 +1,7 @@ package net.lab1024.sa.common.config; -import net.lab1024.sa.common.common.domain.SystemEnv; -import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; import net.lab1024.sa.common.common.util.SmartEnumUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; @@ -21,7 +21,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata; * @Copyright 1024创新实验室 ( https://1024lab.net ) */ @Configuration -public class SystemEnvConfig implements Condition { +public class SystemEnvironmentConfig implements Condition { @Value("${spring.profiles.active}") private String systemEnvironment; @@ -32,18 +32,18 @@ public class SystemEnvConfig implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { String property = conditionContext.getEnvironment().getProperty("spring.profiles.active"); - return StringUtils.isNotBlank(property) && !SystemEnvEnum.PROD.equalsValue(property); + return StringUtils.isNotBlank(property) && !SystemEnvironmentEnum.PROD.equalsValue(property); } @Bean - public SystemEnv initEnvironment() { - SystemEnvEnum currentEnv = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvEnum.class); - if (currentEnv == null) { + public SystemEnvironment initEnvironment() { + SystemEnvironmentEnum currentEnvironment = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvironmentEnum.class); + if (currentEnvironment == null) { throw new ExceptionInInitializerError("无法获取当前环境!请在 application.yaml 配置参数:spring.profiles.active"); } if (StringUtils.isBlank(projectName)) { throw new ExceptionInInitializerError("无法获取当前项目名称!请在 application.yaml 配置参数:project.name"); } - return new SystemEnv(currentEnv == SystemEnvEnum.PROD, projectName, currentEnv); + return new SystemEnvironment(currentEnvironment == SystemEnvironmentEnum.PROD, projectName, currentEnvironment); } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java index deea8494..6e8ae116 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java @@ -1,11 +1,12 @@ package net.lab1024.sa.common.config; -import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.annoation.SaAuth; import net.lab1024.sa.common.common.domain.RequestUrlVO; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -22,18 +23,21 @@ import java.util.Set; import java.util.stream.Collectors; /** - * description + * url配置 * - * @author Turbolisten - * @date 2023/7/13 17:42 + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) */ -@Slf4j @Configuration +@Slf4j public class UrlConfig { - @Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping; + /** * 获取每个方法的请求路径 * @@ -42,10 +46,11 @@ public class UrlConfig { @Bean public Map> methodUrlMap() { Map> methodUrlMap = Maps.newHashMap(); - // 获取url与类和方法的对应信息 + //获取url与类和方法的对应信息 Map map = requestMappingHandlerMapping.getHandlerMethods(); for (Map.Entry entry : map.entrySet()) { RequestMappingInfo requestMappingInfo = entry.getKey(); + Set urls = requestMappingInfo.getPatternsCondition().getPatterns(); if (CollectionUtils.isEmpty(urls)) { continue; @@ -67,20 +72,14 @@ public class UrlConfig { List authUrlList = Lists.newArrayList(); for (Map.Entry> entry : methodUrlMap.entrySet()) { Method method = entry.getKey(); - // 忽略权限 - SaIgnore ignore = method.getAnnotation(SaIgnore.class); - if (null != ignore) { + SaAuth saAuth = method.getAnnotation(SaAuth.class); + if (null == saAuth) { continue; } - NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class); - if (null != noNeedLogin) { - continue; - } - Set urlSet = entry.getValue(); - List requestUrlList = this.buildRequestUrl(method, urlSet); + List requestUrlList = this.buildRequestUrl(method, entry.getValue()); authUrlList.addAll(requestUrlList); } - log.info("需要权限校验的URL:{}", authUrlList.stream().map(RequestUrlVO::getUrl).collect(Collectors.toList())); + log.info("需要权限校验的URL:{}", authUrlList.stream().map(e -> e.getUrl()).collect(Collectors.toList())); return authUrlList; } @@ -89,22 +88,29 @@ public class UrlConfig { if (CollectionUtils.isEmpty(urlSet)) { return requestUrlList; } - // swagger api 说明 + //url对应的方法名称 + String className = method.getDeclaringClass().getName(); + String methodName = method.getName(); + List list = StrUtil.split(className, "."); + String controllerName = list.get(list.size() - 1); + String name = controllerName + "." + methodName; + //swagger 说明信息 String methodComment = null; ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); if (apiOperation != null) { methodComment = apiOperation.value(); } - for (String url : urlSet) { RequestUrlVO requestUrlVO = new RequestUrlVO(); requestUrlVO.setUrl(url); + requestUrlVO.setName(name); requestUrlVO.setComment(methodComment); requestUrlList.add(requestUrlVO); } return requestUrlList; } + /** * 获取无需登录可以匿名访问的url信息 * @@ -124,4 +130,21 @@ public class UrlConfig { log.info("不需要登录的URL:{}", noNeedLoginUrlList); return noNeedLoginUrlList; } -} + + /** + * 获取忽略的url信息 + * + * @return + */ + @Bean + public List ignoreUrlList() { + List ignoreUrlList = Lists.newArrayList(); + ignoreUrlList.add("/swagger-ui.html"); + ignoreUrlList.add("/swagger-resources/**"); + ignoreUrlList.add("/webjars/**"); + ignoreUrlList.add("/druid/**"); + ignoreUrlList.add("/*/api-docs"); + return ignoreUrlList; + } + +} \ No newline at end of file diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java index 3f60effe..66da1df0 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java @@ -1,16 +1,15 @@ package net.lab1024.sa.common.handler; -import cn.dev33.satoken.exception.NotPermissionException; import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.common.common.code.SystemErrorCode; import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.domain.ResponseDTO; -import net.lab1024.sa.common.common.domain.SystemEnv; -import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; +import net.lab1024.sa.common.common.domain.SystemEnvironment; import net.lab1024.sa.common.common.exception.BusinessException; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -38,7 +37,7 @@ import java.util.stream.Collectors; public class GlobalExceptionHandler { @Autowired - private SystemEnv systemEnv; + private SystemEnvironment systemEnvironment; /** * json 格式错误 缺少请求体 @@ -46,7 +45,7 @@ public class GlobalExceptionHandler { @ResponseBody @ExceptionHandler({HttpMessageNotReadableException.class}) public ResponseDTO jsonFormatExceptionHandler(Exception e) { - if (!systemEnv.isProd()) { + if (!systemEnvironment.isProd()) { log.error("全局JSON格式错误异常,URL:{}", getCurrentRequestUrl(), e); } return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "参数JSON格式错误"); @@ -58,7 +57,7 @@ public class GlobalExceptionHandler { @ResponseBody @ExceptionHandler({TypeMismatchException.class, BindException.class}) public ResponseDTO paramExceptionHandler(Exception e) { - if (!systemEnv.isProd()) { + if (!systemEnvironment.isProd()) { log.error("全局参数异常,URL:{}", getCurrentRequestUrl(), e); } @@ -78,34 +77,27 @@ public class GlobalExceptionHandler { return ResponseDTO.error(UserErrorCode.PARAM_ERROR); } + /** + * 权限异常 + */ + @ResponseBody + @ExceptionHandler({AccessDeniedException.class}) + public ResponseDTO permissionExceptionHandler(AccessDeniedException e) { + return ResponseDTO.error(UserErrorCode.NO_PERMISSION); + } + /** * 业务异常 */ @ResponseBody @ExceptionHandler(BusinessException.class) public ResponseDTO businessExceptionHandler(BusinessException e) { - if (!systemEnv.isProd()) { + if (!systemEnvironment.isProd()) { log.error("全局业务异常,URL:{}", getCurrentRequestUrl(), e); } return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, e.getMessage()); } - /** - * sa-token 权限异常处理 - * - * @param e - * @return - */ - @ResponseBody - @ExceptionHandler(NotPermissionException.class) - public ResponseDTO permissionException(NotPermissionException e) { - // 开发环境 方便调试 - if (SystemEnvEnum.PROD != systemEnv.getCurrentEnv()) { - return ResponseDTO.error(UserErrorCode.NO_PERMISSION, e.getMessage()); - } - return ResponseDTO.error(UserErrorCode.NO_PERMISSION); - } - /** * 其他全部异常 * @@ -116,7 +108,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(Throwable.class) public ResponseDTO errorHandler(Throwable e) { log.error("捕获全局异常,URL:{}", getCurrentRequestUrl(), e); - return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnv.isProd() ? null : e.toString()); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnvironment.isProd() ? null : e.toString()); } /** diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java index 8911c7c7..36042c67 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java @@ -2,9 +2,10 @@ package net.lab1024.sa.common.module.support.captcha; import com.google.code.kaptcha.impl.DefaultKaptcha; import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.UserErrorCode; import net.lab1024.sa.common.common.constant.StringConst; import net.lab1024.sa.common.common.domain.ResponseDTO; -import net.lab1024.sa.common.common.domain.SystemEnv; +import net.lab1024.sa.common.common.domain.SystemEnvironment; import net.lab1024.sa.common.common.exception.BusinessException; import net.lab1024.sa.common.constant.RedisKeyConst; import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; @@ -42,7 +43,7 @@ public class CaptchaService { @Autowired private DefaultKaptcha defaultKaptcha; @Autowired - private SystemEnv systemEnvironment; + private SystemEnvironment systemEnvironment; @Autowired private RedisService redisService; diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java index aa05bbc9..2968ed5a 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java @@ -157,7 +157,7 @@ public class DataTracerService { * 保存数据变动记录 */ public void addTrace(DataTracerForm tracerForm) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); this.addTrace(tracerForm, requestUser); } @@ -182,7 +182,7 @@ public class DataTracerService { * 批量保存数据变动记录 */ public void addTraceList(List tracerFormList) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); this.addTraceList(tracerFormList, requestUser); } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java index a3242326..b9a1cd09 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java @@ -13,6 +13,7 @@ import net.lab1024.sa.common.module.support.feedback.domain.FeedbackAddForm; import net.lab1024.sa.common.module.support.feedback.domain.FeedbackQueryForm; import net.lab1024.sa.common.module.support.feedback.domain.FeedbackVO; import net.lab1024.sa.common.module.support.feedback.service.FeedbackService; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -46,7 +47,7 @@ public class FeedbackController extends SupportBaseController { @ApiOperation("意见反馈-新增 @author 开云") @PostMapping("/feedback/add") public ResponseDTO add(@RequestBody @Valid FeedbackAddForm addForm) { - RequestUser employee = SmartRequestUtil.getUser(); + RequestUser employee = SmartRequestUtil.getRequestUser(); return feedbackService.add(addForm, employee); } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java index 4734bfa4..04dc3f10 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java @@ -5,13 +5,17 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import net.lab1024.sa.common.common.constant.RequestHeaderConst; import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; import net.lab1024.sa.common.common.domain.RequestUser; import net.lab1024.sa.common.common.domain.ResponseDTO; import net.lab1024.sa.common.common.util.SmartRequestUtil; import net.lab1024.sa.common.constant.SwaggerTagConst; -import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; +import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; import net.lab1024.sa.common.module.support.file.domain.form.FileUrlUploadForm; import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; import net.lab1024.sa.common.module.support.file.service.FileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -42,14 +46,14 @@ public class FileController extends SupportBaseController { @PostMapping("/file/upload") public ResponseDTO upload(@RequestParam MultipartFile file, @RequestParam Integer folder) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); return fileService.fileUpload(file, folder, requestUser); } @ApiOperation(value = "文件上传,通过url上传 @author 胡克", notes = FileFolderTypeEnum.INFO) @PostMapping("/file/upload/url") public ResponseDTO uploadByUrl(@RequestBody @Valid FileUrlUploadForm uploadForm) { - RequestUser requestUser = SmartRequestUtil.getUser(); + RequestUser requestUser = SmartRequestUtil.getRequestUser(); return fileService.fileUpload(uploadForm,requestUser); } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java index 005320e2..cd3eb398 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java @@ -56,7 +56,7 @@ public class HelpDocController extends SupportBaseController { @RepeatSubmit public ResponseDTO view(@PathVariable Long helpDocId, HttpServletRequest request) { return helpDocUserService.view( - SmartRequestUtil.getUser(), + SmartRequestUtil.getRequestUser(), helpDocId); } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java index 75ef250d..3d9da663 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java @@ -179,7 +179,7 @@ public abstract class OperateLogAspect { return; } //设置用户信息 - RequestUser user = SmartRequestUtil.getUser(); + RequestUser user = SmartRequestUtil.getRequestUser(); if (user == null) { return; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java index 3c309499..f99f29ef 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java @@ -1,8 +1,8 @@ package net.lab1024.sa.common.module.support.redis; import com.alibaba.fastjson.JSON; -import net.lab1024.sa.common.common.domain.SystemEnv; -import net.lab1024.sa.common.common.enumeration.SystemEnvEnum; +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; import net.lab1024.sa.common.common.util.SmartStringUtil; import net.lab1024.sa.common.constant.RedisKeyConst; import org.slf4j.Logger; @@ -52,7 +52,7 @@ public class RedisService { private SetOperations redisSetOperations; @Autowired - private SystemEnv systemEnvironment; + private SystemEnvironment systemEnvironment; /** @@ -62,7 +62,7 @@ public class RedisService { * @return */ public String generateRedisKey(String prefix, String key) { - SystemEnvEnum currentEnvironment = systemEnvironment.getCurrentEnv(); + SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment(); return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key; } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java index 0c5ca017..fd657e09 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java @@ -33,19 +33,19 @@ public class TableColumnController extends SupportBaseController { @PostMapping("/tableColumn/update") @RepeatSubmit public ResponseDTO updateTableColumn(@RequestBody @Valid TableColumnUpdateForm updateForm) { - return tableColumnService.updateTableColumns(SmartRequestUtil.getUser(), updateForm); + return tableColumnService.updateTableColumns(SmartRequestUtil.getRequestUser(), updateForm); } @ApiOperation("恢复默认(删除) @author 卓大") @GetMapping("/tableColumn/delete/{tableId}") @RepeatSubmit public ResponseDTO deleteTableColumn(@PathVariable Integer tableId) { - return tableColumnService.deleteTableColumn(SmartRequestUtil.getUser(), tableId); + return tableColumnService.deleteTableColumn(SmartRequestUtil.getRequestUser(), tableId); } @ApiOperation("查询表格列 @author 卓大") @GetMapping("/tableColumn/getColumns/{tableId}") public ResponseDTO getColumns(@PathVariable Integer tableId) { - return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getUser(), tableId)); + return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getRequestUser(), tableId)); } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java index 5baa2afa..3fa94198 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java @@ -1,7 +1,5 @@ package net.lab1024.sa.common.module.support.token; -import lombok.AllArgsConstructor; -import lombok.Getter; import net.lab1024.sa.common.common.enumeration.BaseEnum; /** @@ -13,8 +11,6 @@ import net.lab1024.sa.common.common.enumeration.BaseEnum; * @Email lab1024@163.com * @Copyright 1024创新实验室 ( https://1024lab.net ) */ -@Getter -@AllArgsConstructor public enum LoginDeviceEnum implements BaseEnum { PC(1, "电脑端"), @@ -25,9 +21,23 @@ public enum LoginDeviceEnum implements BaseEnum { H5(4, "H5"), - WX_MP(5, "微信小程序"); + WEIXIN_MP(5, "微信小程序"); - private final Integer value; + LoginDeviceEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } - private final String desc; + private Integer value; + private String desc; + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } } diff --git a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java index 07b3acea..e3af8649 100644 --- a/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java +++ b/smart-admin-api/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java @@ -1,85 +1,220 @@ package net.lab1024.sa.common.module.support.token; -import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.stp.SaLoginModel; -import cn.dev33.satoken.stp.StpUtil; -import net.lab1024.sa.common.common.constant.StringConst; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.constant.RedisKeyConst; +import net.lab1024.sa.common.module.support.redis.RedisService; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import java.util.List; +import java.util.Date; +import java.util.Map; /** - * 用户token 相关服务 + * 与用户token的相关的服务 * - * @author listen - * @date 2023-07-12 22:48:35 + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-11-29 19:48:35 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) */ @Component +@Slf4j public class TokenService { + private static final long HOUR_TIME_MILLI = 60 * 60 * 1000; - public static final String EXTRA_KEY_USER_NAME = "userName"; + @Value("${token.key}") + private String tokenKey; - public static final String EXTRA_KEY_USER_TYPE = "userType"; + @Value("${token.expire-day}") + private Integer tokenExpire; + + @Autowired + private RedisService redisService; /** - * 生成Token + * 生成Token,并存入redis * * @param userId * @param userName * @param userTypeEnum * @param loginDeviceEnum + * @param superPasswordFlag 特殊万能密码标识 * @return */ - public String generateToken(Long userId, - String userName, - UserTypeEnum userTypeEnum, - LoginDeviceEnum loginDeviceEnum) { + public String generateToken(Long userId, String userName, UserTypeEnum userTypeEnum, LoginDeviceEnum loginDeviceEnum, Boolean superPasswordFlag) { + long nowTimeMilli = System.currentTimeMillis(); + Claims jwtClaims = Jwts.claims(); + jwtClaims.put(JwtConst.CLAIM_ID_KEY, userId); + jwtClaims.put(JwtConst.CLAIM_NAME_KEY, userName); + jwtClaims.put(JwtConst.CLAIM_USER_TYPE_KEY, userTypeEnum.getValue()); + jwtClaims.put(JwtConst.CLAIM_DEVICE_KEY, loginDeviceEnum.getValue()); + jwtClaims.put(JwtConst.CLAIM_SUPER_PASSWORD_FLAG, superPasswordFlag); + JwtBuilder jwtBuilder = Jwts.builder() + .setClaims(jwtClaims) + .setIssuedAt(new Date(nowTimeMilli)) + .signWith(SignatureAlgorithm.HS512, tokenKey); - /** - * 设置登录模式参数 - * 具体参数 {@link SaLoginModel } 属性 - * 已经写的挺清楚的了 - */ - SaLoginModel loginModel = new SaLoginModel(); - // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型 - loginModel.setDevice(String.valueOf(loginDeviceEnum.getDesc())); + // 如果是万能密码,则不需要记录到redis中;万能密码最多半个小时有效期 + if (superPasswordFlag) { + jwtBuilder.setExpiration(new Date(nowTimeMilli + (HOUR_TIME_MILLI / 2))); + return jwtBuilder.compact(); + } - // 登录 - String loginId = generateLoginId(userId, userTypeEnum); - StpUtil.login(loginId, loginModel); - - // 扩展参数 放入会话中 redis session - SaSession session = StpUtil.getSession(); - session.set(EXTRA_KEY_USER_NAME, userName); - session.set(EXTRA_KEY_USER_TYPE, userTypeEnum); - return StpUtil.getTokenValue(); - } - - public static String generateLoginId(Long userId, UserTypeEnum userType) { - return userType.getValue() + StringConst.COLON + userId; - } - - public static Long getUserId(String loginId) { - return Long.valueOf(loginId.substring(loginId.indexOf(StringConst.COLON) + 1)); - } - - public static Integer getUserType(String loginId) { - return Integer.valueOf(loginId.substring(0, loginId.indexOf(StringConst.COLON))); + jwtBuilder.setExpiration(new Date(nowTimeMilli + tokenExpire * 24 * HOUR_TIME_MILLI)); + String token = jwtBuilder.compact(); + String redisKey = this.generateTokenRedisKey(userId, userTypeEnum.getValue(), loginDeviceEnum.getValue()); + redisService.set(redisKey, token, tokenExpire * 24 * 3600); + return token; } /** - * 退出登录 注销 + * 生成登录信息: 含设备信息 + * + * @param userId + * @param device + * @return */ - public void removeToken() { - StpUtil.logout(); + private String generateTokenRedisKey(Long userId, Integer userType, Integer device) { + String userKey = userType + "_" + userId + "_" + device; + return redisService.generateRedisKey(RedisKeyConst.Support.TOKEN, userKey); } - public void removeToken(Long userId, UserTypeEnum userType) { - StpUtil.logout(generateLoginId(userId, userType)); + + /** + * 强制移除 此用户各端的登录信息 + * + * @param token + */ + public void removeToken(String token) { + Map tokenData = this.decryptTokenData(token); + if (MapUtils.isEmpty(tokenData)) { + return; + } + + //特殊账号 + if (tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { + try { + Boolean superPasswordFlag = Boolean.valueOf(tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); + if (superPasswordFlag) { + return; + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return; + } + } + + boolean isValid = this.checkRedisToken(tokenData, token); + if (!isValid) { + return; + } + + Long userId = Long.valueOf(tokenData.get(JwtConst.CLAIM_ID_KEY).toString()); + Integer userType = Integer.valueOf(tokenData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString()); + Integer device = Integer.valueOf(tokenData.get(JwtConst.CLAIM_DEVICE_KEY).toString()); + + String redisKey = this.generateTokenRedisKey(userId, userType, device); + redisService.delete(redisKey); } - public void removeToken(List userIdList, UserTypeEnum userType) { - userIdList.forEach(id -> StpUtil.logout(generateLoginId(id, userType))); + /** + * 解析并校验token信息 获取 userId + * + * @param token + * @return + */ + public Long getUserIdAndValidateToken(String token) { + Map parseJwtData = this.decryptTokenData(token); + boolean isValid = this.checkRedisToken(parseJwtData, token); + if (!isValid) { + return null; + } + Long userId = Long.valueOf(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString()); + return userId; + } + + /** + * 解密和解析token + * + * @param token + * @return + */ + private Map decryptTokenData(String token) { + try { + return Jwts.parser() + .setSigningKey(tokenKey) + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + } + return null; + } + + /** + * 校验token是否有效 + * + * @param token + * @return + */ + private boolean checkRedisToken(Map parseJwtData, String token) { + if (MapUtils.isEmpty(parseJwtData)) { + return false; + } + //特殊账号 + if (parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { + try { + Boolean superPasswordFlag = Boolean.valueOf(parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); + if (superPasswordFlag) { + return true; + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + Long userId = null; + Integer userType = null, device = null; + + if (null != parseJwtData.get(JwtConst.CLAIM_ID_KEY)) { + userId = NumberUtils.toLong(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString(), -1); + userId = userId == -1 ? null : userId; + } + + if (null != parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY)) { + userType = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString(), -1); + userType = userType == -1 ? null : userType; + } + + if (null != parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY)) { + device = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY).toString(), -1); + device = device == -1 ? null : device; + } + + if (userId == null || userType == null || device == null) { + return false; + } + + String redisKey = this.generateTokenRedisKey(userId, userType, device); + String redisToken = redisService.get(redisKey); + return token.equals(redisToken); + } + + /** + * 批量移除用户所有设备的token + */ + public void batchRemoveRedisToken(Long userId, UserTypeEnum userTypeEnum) { + for (LoginDeviceEnum device : LoginDeviceEnum.values()) { + redisService.delete(this.generateTokenRedisKey(userId, userTypeEnum.getValue(), device.getValue())); + } } } \ No newline at end of file diff --git a/smart-admin-api/sa-common/src/main/resources/dev/sa-common.yaml b/smart-admin-api/sa-common/src/main/resources/dev/sa-common.yaml index 62e609ef..b6b25c9d 100644 --- a/smart-admin-api/sa-common/src/main/resources/dev/sa-common.yaml +++ b/smart-admin-api/sa-common/src/main/resources/dev/sa-common.yaml @@ -3,7 +3,7 @@ spring: datasource: url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v2?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai username: root - password: 123456 + password: Zhuoda1024lab initial-size: 2 min-idle: 2 max-active: 10 @@ -27,17 +27,17 @@ spring: # redis 连接池配置信息 redis: - database: 12 + database: 1 host: 127.0.0.1 lettuce: pool: - max-active: 50 + max-active: 5 min-idle: 1 max-idle: 3 max-wait: 30000ms port: 6379 - timeout: 10s - password: 123456 + timeout: 10000ms + password: # 上传文件大小配置 servlet: @@ -109,6 +109,11 @@ http: write-timeout: 50000 keep-alive: 300000 +# token相关配置 +token: + key: sa-jwt-key + expire-day: 7 + # 跨域配置 access-control-allow-origin: '*' @@ -118,33 +123,4 @@ heart-beat: # 热加载配置 reload: - interval-seconds: 300 - -############## Sa-Token 配置 (文档: https://sa-token.cc) ############## -sa-token: - # token 名称(同时也是 cookie 名称) - token-name: x-access-token - # token 前缀 例如:Bear - token-prefix: - # jwt秘钥 - # jwt-secret-key: smart-admin - # token 有效期(单位:秒) 默认30天,-1 代表永久有效 - timeout: 432000 - # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - active-timeout: -1 - # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) - is-concurrent: false - # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) - is-share: false - # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) - token-style: simple-uuid - # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) - auto-renew: true - # 是否输出操作日志 - is-log: true - # 日志等级(trace、debug、info、warn、error、fatal) - log-level: debug - # 启动时的字符画打印 - is-print: false - # 是否从cookie读取token - is-read-cookie: false \ No newline at end of file + interval-seconds: 300 \ No newline at end of file