mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-09-17 19:06:39 +08:00
commit
e465fdbf0a
@ -46,6 +46,7 @@
|
||||
<jjwt.version>0.9.1</jjwt.version>
|
||||
<jwks-rsa.version>0.9.0</jwks-rsa.version>
|
||||
<velocity-tools.version>3.1</velocity-tools.version>
|
||||
<sa-token-version>1.35.0.RC</sa-token-version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -109,6 +110,23 @@
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||
<!-- 依赖下载失败 请看:https://sa-token.cc/doc.html#/start/maven-pull -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token end -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
|
@ -4,8 +4,6 @@ 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;
|
||||
|
||||
@ -27,7 +25,7 @@ public class JweAspectConfig {
|
||||
@Bean
|
||||
public JweAspect jweConfig() {
|
||||
return new JweAspect((request -> {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
JweUserKey userKey = new JweUserKey();
|
||||
userKey.setUserId(requestUser.getUserId());
|
||||
userKey.setUserName(requestUser.getUserName());
|
||||
|
@ -0,0 +1,37 @@
|
||||
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<String> urlList = menuService.queryNeedCheckPermissionsUrl();
|
||||
urlList.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url)));
|
||||
}).isAnnotation(false);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
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<String, HttpServletRequest, UserDetails> userFunction() {
|
||||
return (token, request) -> loginService.getLoginUserDetail(token, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getAuthenticatedUrlPatterns() {
|
||||
return new String[]{"/**"};
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
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、以类名加方法名为权限字符串的校验模式 <br>
|
||||
* 2、重写MethodSecurityMetadataSource将优化security配置,只需在方法上加上@saAuth注解,方法上就会存在权限(权限字符串为类名加方法名),而无需另外手动设置,减轻后端开发成本<br>
|
||||
* 3、security将不再依据权限字符串进行权限控制,<br>
|
||||
* 4、security将依据对应权限字符串下的接口权限进行控制 <br>
|
||||
* 5、采用此配置原@PreAuthorize依然有效 <br>
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
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<String> 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;
|
||||
}
|
||||
}
|
@ -14,7 +14,6 @@ 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;
|
||||
@ -38,35 +37,30 @@ public class GoodsController extends AdminBaseController {
|
||||
|
||||
@ApiOperation("分页查询 @author 胡克")
|
||||
@PostMapping("/goods/query")
|
||||
@PreAuthorize("@saAuth.checkPermission('goods:query')")
|
||||
public ResponseDTO<PageResult<GoodsVO>> query(@RequestBody @Valid GoodsQueryForm queryForm) {
|
||||
return goodsService.query(queryForm);
|
||||
}
|
||||
|
||||
@ApiOperation("添加商品 @author 胡克")
|
||||
@PostMapping("/goods/add")
|
||||
@PreAuthorize("@saAuth.checkPermission('goods:add')")
|
||||
public ResponseDTO<String> add(@RequestBody @Valid GoodsAddForm addForm) {
|
||||
return goodsService.add(addForm);
|
||||
}
|
||||
|
||||
@ApiOperation("更新商品 @author 胡克")
|
||||
@PostMapping("/goods/update")
|
||||
@PreAuthorize("@saAuth.checkPermission('goods:update')")
|
||||
public ResponseDTO<String> update(@RequestBody @Valid GoodsUpdateForm updateForm) {
|
||||
return goodsService.update(updateForm);
|
||||
}
|
||||
|
||||
@ApiOperation("删除 @author 卓大")
|
||||
@GetMapping("/goods/delete/{goodsId}")
|
||||
@PreAuthorize("@saAuth.checkPermission('goods:delete')")
|
||||
public ResponseDTO<String> delete(@PathVariable Long goodsId) {
|
||||
return goodsService.delete(goodsId);
|
||||
}
|
||||
|
||||
@ApiOperation("批量 @author 卓大")
|
||||
@PostMapping("/goods/batchDelete")
|
||||
@PreAuthorize("@saAuth.checkPermission('goods:batchDelete')")
|
||||
public ResponseDTO<String> batchDelete(@RequestBody @Valid ValidateList<Long> idList) {
|
||||
return goodsService.batchDelete(idList);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class BankController {
|
||||
@ApiOperation(value = "新建银行信息 @author 善逸")
|
||||
@PostMapping("/oa/bank/create")
|
||||
public ResponseDTO<String> createBank(@RequestBody @Valid BankCreateForm createVO) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
createVO.setCreateUserId(requestUser.getUserId());
|
||||
createVO.setCreateUserName(requestUser.getUserName());
|
||||
return bankService.createBank(createVO);
|
||||
|
@ -8,7 +8,6 @@ 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;
|
||||
@ -40,23 +39,20 @@ public class EnterpriseController {
|
||||
|
||||
@ApiOperation(value = "分页查询企业模块 @author 开云")
|
||||
@PostMapping("/oa/enterprise/page/query")
|
||||
@SaAuth
|
||||
public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryDTO) {
|
||||
return enterpriseService.queryByPage(queryDTO);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询企业详情 @author 开云")
|
||||
@GetMapping("/oa/enterprise/get/{enterpriseId}")
|
||||
@SaAuth
|
||||
public ResponseDTO<EnterpriseVO> getDetail(@PathVariable Long enterpriseId) {
|
||||
return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "新建企业 @author 开云")
|
||||
@PostMapping("/oa/enterprise/create")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
createVO.setCreateUserId(requestUser.getUserId());
|
||||
createVO.setCreateUserName(requestUser.getUserName());
|
||||
return enterpriseService.createEnterprise(createVO);
|
||||
@ -64,21 +60,18 @@ public class EnterpriseController {
|
||||
|
||||
@ApiOperation(value = "编辑企业 @author 开云")
|
||||
@PostMapping("/oa/enterprise/update")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) {
|
||||
return enterpriseService.updateEnterprise(updateVO);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除企业 @author 开云")
|
||||
@GetMapping("/oa/enterprise/delete/{enterpriseId}")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> deleteEnterprise(@PathVariable Long enterpriseId) {
|
||||
return enterpriseService.deleteEnterprise(enterpriseId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "企业列表查询 @author 开云")
|
||||
@GetMapping("/oa/enterprise/query/list")
|
||||
@SaAuth
|
||||
public ResponseDTO<List<EnterpriseListVO>> queryList(@RequestParam(value = "type", required = false) Integer type) {
|
||||
return enterpriseService.queryList(type);
|
||||
}
|
||||
@ -86,21 +79,18 @@ public class EnterpriseController {
|
||||
|
||||
@ApiOperation(value = "企业添加员工 @author 罗伊")
|
||||
@PostMapping("/oa/enterprise/employee/add")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
|
||||
return enterpriseService.addEmployee(enterpriseEmployeeForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询企业全部员工 @author 罗伊")
|
||||
@PostMapping("/oa/enterprise/employee/list")
|
||||
@SaAuth
|
||||
public ResponseDTO<List<EnterpriseEmployeeVO>> employeeList(@RequestBody @Valid List<Long> enterpriseIdList) {
|
||||
return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "分页查询企业员工 @author 卓大")
|
||||
@PostMapping("/oa/enterprise/employee/queryPage")
|
||||
@SaAuth
|
||||
public ResponseDTO<PageResult<EnterpriseEmployeeVO>> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) {
|
||||
return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm));
|
||||
}
|
||||
@ -108,7 +98,6 @@ public class EnterpriseController {
|
||||
|
||||
@ApiOperation(value = "企业删除员工 @author 罗伊")
|
||||
@PostMapping("/oa/enterprise/employee/delete")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
|
||||
return enterpriseService.deleteEmployee(enterpriseEmployeeForm);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class InvoiceController {
|
||||
@ApiOperation(value = "新建发票信息 @author 善逸")
|
||||
@PostMapping("/oa/invoice/create")
|
||||
public ResponseDTO<String> createInvoice(@RequestBody @Valid InvoiceAddForm createVO) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
createVO.setCreateUserId(requestUser.getUserId());
|
||||
createVO.setCreateUserName(requestUser.getUserName());
|
||||
return invoiceService.createInvoice(createVO);
|
||||
|
@ -9,7 +9,6 @@ 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;
|
||||
@ -73,7 +72,6 @@ public class NoticeController {
|
||||
|
||||
@ApiOperation("【管理】通知公告-分页查询 @author 卓大")
|
||||
@PostMapping("/oa/notice/query")
|
||||
@SaAuth
|
||||
public ResponseDTO<PageResult<NoticeVO>> query(@RequestBody @Valid NoticeQueryForm queryForm) {
|
||||
return ResponseDTO.ok(noticeService.query(queryForm));
|
||||
}
|
||||
@ -81,30 +79,26 @@ public class NoticeController {
|
||||
@ApiOperation("【管理】通知公告-添加 @author 卓大")
|
||||
@PostMapping("/oa/notice/add")
|
||||
@RepeatSubmit
|
||||
@SaAuth
|
||||
public ResponseDTO<String> add(@RequestBody @Valid NoticeAddForm addForm) {
|
||||
addForm.setCreateUserId(SmartRequestUtil.getRequestUserId());
|
||||
addForm.setCreateUserId(SmartRequestUtil.getUserId());
|
||||
return noticeService.add(addForm);
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】通知公告-更新 @author 卓大")
|
||||
@PostMapping("/oa/notice/update")
|
||||
@RepeatSubmit
|
||||
@SaAuth
|
||||
public ResponseDTO<String> update(@RequestBody @Valid NoticeUpdateForm updateForm) {
|
||||
return noticeService.update(updateForm);
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】通知公告-更新详情 @author 卓大")
|
||||
@GetMapping("/oa/notice/getUpdateVO/{noticeId}")
|
||||
@SaAuth
|
||||
public ResponseDTO<NoticeUpdateFormVO> getUpdateFormVO(@PathVariable Long noticeId) {
|
||||
return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId));
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】通知公告-删除 @author 卓大")
|
||||
@GetMapping("/oa/notice/delete/{noticeId}")
|
||||
@SaAuth
|
||||
public ResponseDTO<String> delete(@PathVariable Long noticeId) {
|
||||
return noticeService.delete(noticeId);
|
||||
}
|
||||
@ -114,7 +108,7 @@ public class NoticeController {
|
||||
@GetMapping("/oa/notice/employee/view/{noticeId}")
|
||||
public ResponseDTO<NoticeDetailVO> view(@PathVariable Long noticeId, HttpServletRequest request) {
|
||||
return noticeEmployeeService.view(
|
||||
SmartRequestUtil.getRequestUserId(),
|
||||
SmartRequestUtil.getUserId(),
|
||||
noticeId,
|
||||
ServletUtil.getClientIP(request),
|
||||
request.getHeader("User-Agent")
|
||||
@ -124,7 +118,7 @@ public class NoticeController {
|
||||
@ApiOperation("【员工】通知公告-查询全部 @author 卓大")
|
||||
@PostMapping("/oa/notice/employee/query")
|
||||
public ResponseDTO<PageResult<NoticeEmployeeVO>> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
|
||||
return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm);
|
||||
return noticeEmployeeService.queryList(SmartRequestUtil.getUserId(), noticeEmployeeQueryForm);
|
||||
}
|
||||
|
||||
@ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大")
|
||||
|
@ -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<String, Object> paramMap, DataScopeSqlConfig sqlConfigDTO) {
|
||||
DataScopeTypeEnum dataScopeTypeEnum = sqlConfigDTO.getDataScopeType();
|
||||
String joinSql = sqlConfigDTO.getJoinSql();
|
||||
Long employeeId = SmartRequestUtil.getRequestUserId();
|
||||
Long employeeId = SmartRequestUtil.getUserId();
|
||||
if (employeeId == null) {
|
||||
return "";
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ 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;
|
||||
@ -43,21 +42,18 @@ public class DepartmentController extends AdminBaseController {
|
||||
|
||||
@ApiOperation(value = "添加部门 @author 卓大")
|
||||
@PostMapping("/department/add")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:department:add')")
|
||||
public ResponseDTO<String> addDepartment(@Valid @RequestBody DepartmentAddForm createDTO) {
|
||||
return departmentService.addDepartment(createDTO);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "更新部门 @author 卓大")
|
||||
@PostMapping("/department/update")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:department:update')")
|
||||
public ResponseDTO<String> updateDepartment(@Valid @RequestBody DepartmentUpdateForm updateDTO) {
|
||||
return departmentService.updateDepartment(updateDTO);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除部门 @author 卓大")
|
||||
@GetMapping("/department/delete/{departmentId}")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:department:delete')")
|
||||
public ResponseDTO<String> deleteDepartment(@PathVariable Long departmentId) {
|
||||
return departmentService.deleteDepartment(departmentId);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ 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;
|
||||
@ -43,35 +42,30 @@ public class EmployeeController extends AdminBaseController {
|
||||
|
||||
@ApiOperation(value = "添加员工(返回添加员工的密码) @author 卓大")
|
||||
@PostMapping("/employee/add")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:employee:add')")
|
||||
public ResponseDTO<String> addEmployee(@Valid @RequestBody EmployeeAddForm employeeAddForm) {
|
||||
return employeeService.addEmployee(employeeAddForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "更新员工 @author 卓大")
|
||||
@PostMapping("/employee/update")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:employee:update')")
|
||||
public ResponseDTO<String> 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<String> updateDisableFlag(@PathVariable Long employeeId) {
|
||||
return employeeService.updateDisableFlag(employeeId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "批量删除员工 @author 卓大")
|
||||
@PostMapping("/employee/update/batch/delete")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:employee:delete')")
|
||||
public ResponseDTO<String> batchUpdateDeleteFlag(@RequestBody List<Long> employeeIdList) {
|
||||
return employeeService.batchUpdateDeleteFlag(employeeIdList);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "批量调整员工部门 @author 卓大")
|
||||
@PostMapping("/employee/update/batch/department")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:employee:department:update')")
|
||||
public ResponseDTO<String> batchUpdateDepartment(@Valid @RequestBody EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) {
|
||||
return employeeService.batchUpdateDepartment(batchUpdateDepartmentForm);
|
||||
}
|
||||
@ -79,13 +73,12 @@ public class EmployeeController extends AdminBaseController {
|
||||
@ApiOperation(value = "修改密码 @author 卓大")
|
||||
@PostMapping("/employee/update/password")
|
||||
public ResponseDTO<String> updatePassword(@Valid @RequestBody EmployeeUpdatePasswordForm updatePasswordForm) {
|
||||
updatePasswordForm.setEmployeeId(SmartRequestUtil.getRequestUserId());
|
||||
updatePasswordForm.setEmployeeId(SmartRequestUtil.getUserId());
|
||||
return employeeService.updatePassword(updatePasswordForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "重置员工密码 @author 卓大")
|
||||
@GetMapping("/employee/update/password/reset/{employeeId}")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:employee:password:reset')")
|
||||
public ResponseDTO<String> resetPassword(@PathVariable Integer employeeId) {
|
||||
return employeeService.resetPassword(employeeId);
|
||||
}
|
||||
|
@ -1,18 +1,24 @@
|
||||
package net.lab1024.sa.admin.module.system.employee.service;
|
||||
|
||||
import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum;
|
||||
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.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 org.apache.commons.lang3.StringUtils;
|
||||
import net.lab1024.sa.common.common.enumeration.UserTypeEnum;
|
||||
import net.lab1024.sa.common.module.support.token.TokenService;
|
||||
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.HashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -25,7 +31,7 @@ import java.util.stream.Collectors;
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
*/
|
||||
@Service
|
||||
public class EmployeePermissionService {
|
||||
public class EmployeePermissionService implements StpInterface {
|
||||
|
||||
@Autowired
|
||||
private RoleEmployeeService roleEmployeeService;
|
||||
@ -33,39 +39,23 @@ public class EmployeePermissionService {
|
||||
@Autowired
|
||||
private RoleMenuService roleMenuService;
|
||||
|
||||
@Autowired
|
||||
private RoleMenuDao roleMenuDao;
|
||||
|
||||
/**
|
||||
* 构建权限集合
|
||||
*
|
||||
* @param menuAndPointsList
|
||||
* 员工关联权限 缓存key
|
||||
*/
|
||||
public Set<? extends GrantedAuthority> buildAuthorities(List<MenuVO> menuAndPointsList) {
|
||||
HashSet<String> permissionList = new HashSet<>();
|
||||
for (MenuVO menu : menuAndPointsList) {
|
||||
if(menu.getPermsType() == null){
|
||||
continue;
|
||||
}
|
||||
private static final String USER_ROLE_CACHE_KEY = "RoleList";
|
||||
|
||||
String perms = null;
|
||||
if(menu.getPermsType().equals(MenuPermsTypeEnum.SPRING_SECURITY.getValue())){
|
||||
perms = menu.getWebPerms();
|
||||
}else{
|
||||
perms = menu.getApiPerms();
|
||||
}
|
||||
/**
|
||||
* 角色关联功能点 缓存key
|
||||
*/
|
||||
private static final String ROLE_CACHE_KEY = "role:";
|
||||
|
||||
if (StringUtils.isEmpty(perms)) {
|
||||
continue;
|
||||
}
|
||||
//接口权限
|
||||
String[] split = perms.split(",");
|
||||
for (String perm : split) {
|
||||
permissionList.add(perm);
|
||||
}
|
||||
}
|
||||
|
||||
Set<GrantedAuthority> authorities = new HashSet<>();
|
||||
authorities.addAll(permissionList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
|
||||
return authorities;
|
||||
}
|
||||
/**
|
||||
* 角色关联功能点 缓存key
|
||||
*/
|
||||
private static final String ROLE_PERMISSION_CACHE_KEY = "PermissionList";
|
||||
|
||||
/**
|
||||
* 查询用户拥有的前端菜单项 用于登陆返回 前端动态路由配置
|
||||
@ -78,4 +68,61 @@ public class EmployeePermissionService {
|
||||
return roleMenuService.getMenuList(roleIdList, administratorFlag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
// 权限集合
|
||||
List<String> permissionList = new ArrayList<>();
|
||||
|
||||
// 遍历角色列表,查询拥有的权限
|
||||
List<String> roleList = this.getRoleList(loginId, loginType);
|
||||
for (String roleId : roleList) {
|
||||
// 查询缓存
|
||||
SaSession roleSession = SaSessionCustomUtil.getSessionById(ROLE_CACHE_KEY + roleId);
|
||||
List<String> 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<String> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
tokenService.removeToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
}
|
||||
|
||||
return ResponseDTO.ok();
|
||||
@ -240,9 +240,7 @@ public class EmployeeService {
|
||||
}).collect(Collectors.toList());
|
||||
employeeManager.updateBatchById(deleteList);
|
||||
|
||||
for (Long employeeId : employeeIdList) {
|
||||
tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
}
|
||||
tokenService.removeToken(employeeIdList, UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
@ -8,17 +8,15 @@ 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.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 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 javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
@ -40,51 +38,38 @@ public class LoginController {
|
||||
private LoginService loginService;
|
||||
|
||||
@NoNeedLogin
|
||||
@PostMapping("/login")
|
||||
@ApiOperation("登录 @author 卓大")
|
||||
public ResponseDTO<LoginEmployeeDetail> login(@Valid @RequestBody LoginForm loginForm) {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
@PostMapping("/login")
|
||||
public ResponseDTO<LoginEmployeeDetail> login(@Valid @RequestBody LoginForm loginForm, HttpServletRequest request) {
|
||||
String ip = ServletUtil.getClientIP(request);
|
||||
String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT);
|
||||
return loginService.login(loginForm, ip, userAgent);
|
||||
}
|
||||
|
||||
@GetMapping("/login/refresh")
|
||||
@ApiOperation("刷新用户信息(包含用户基础信息、权限信息等等) @author 卓大")
|
||||
@GetMapping("/login/refresh")
|
||||
public ResponseDTO<String> refresh() {
|
||||
loginService.removeLoginUserDetailCache(SmartRequestUtil.getRequestUserId());
|
||||
loginService.removeLoginUserDetailCache(SmartRequestUtil.getUserId());
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/login/getLoginInfo")
|
||||
@ApiOperation("获取登录结果信息 @author 卓大")
|
||||
@GetMapping("/login/getLoginInfo")
|
||||
public ResponseDTO<LoginEmployeeDetail> getLoginInfo() {
|
||||
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);
|
||||
LoginEmployeeDetail loginEmployeeDetail = loginService.getLoginUserDetailCache(SmartRequestUtil.getUserId());
|
||||
return ResponseDTO.ok(loginEmployeeDetail);
|
||||
}
|
||||
|
||||
@ApiOperation("退出登陆 @author 卓大")
|
||||
@ApiOperation("退出登录 @author 卓大")
|
||||
@GetMapping("/login/logout")
|
||||
public ResponseDTO<String> logout(@RequestHeader(value = RequestHeaderConst.TOKEN, required = false) String token) {
|
||||
return loginService.logout(token, SmartRequestUtil.getRequestUser());
|
||||
public ResponseDTO<String> logout() {
|
||||
return loginService.logout(SmartRequestUtil.getUser());
|
||||
}
|
||||
|
||||
@NoNeedLogin
|
||||
@ApiOperation("获取验证码 @author 卓大")
|
||||
@GetMapping("/login/getCaptcha")
|
||||
@NoNeedLogin
|
||||
public ResponseDTO<CaptchaVO> getCaptcha() {
|
||||
return loginService.getCaptcha();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,17 +4,12 @@ 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;
|
||||
|
||||
/**
|
||||
* 员工登录
|
||||
@ -26,7 +21,7 @@ import java.util.Set;
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
|
||||
*/
|
||||
@Data
|
||||
public class LoginEmployeeDetail implements UserDetails, RequestUser {
|
||||
public class LoginEmployeeDetail {
|
||||
|
||||
@ApiModelProperty("token")
|
||||
private String token;
|
||||
@ -78,88 +73,4 @@ public class LoginEmployeeDetail implements UserDetails, RequestUser {
|
||||
|
||||
@ApiModelProperty("请求user-agent")
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* security 权限串
|
||||
*/
|
||||
private Set<? extends GrantedAuthority> authorities;
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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,8 +34,7 @@ public class LoginForm extends CaptchaForm {
|
||||
@Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "请输入6-15位密码(数字|大小写字母|小数点)")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "登录终端")
|
||||
@ApiModelPropertyEnum(LoginDeviceEnum.class)
|
||||
@CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录")
|
||||
@ApiModelPropertyEnum(desc = "登录终端", value = LoginDeviceEnum.class)
|
||||
@CheckEnum(value = LoginDeviceEnum.class, required = true, message = "登录终端类型错误")
|
||||
private Integer loginDevice;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
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;
|
||||
@ -11,7 +10,6 @@ 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;
|
||||
@ -31,7 +29,6 @@ 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;
|
||||
@ -55,9 +52,6 @@ public class LoginService {
|
||||
@Autowired
|
||||
private DepartmentService departmentService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private CaptchaService captchaService;
|
||||
|
||||
@ -70,6 +64,9 @@ public class LoginService {
|
||||
@Autowired
|
||||
private LoginLogService loginLogService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
/**
|
||||
* 登录信息二级缓存
|
||||
*/
|
||||
@ -88,17 +85,15 @@ public class LoginService {
|
||||
* 员工登陆
|
||||
*
|
||||
* @param loginForm
|
||||
* @param ip
|
||||
* @param userAgent
|
||||
* @return 返回用户登录信息
|
||||
*/
|
||||
public ResponseDTO<LoginEmployeeDetail> login(LoginForm loginForm, String ip, String userAgent) {
|
||||
LoginDeviceEnum loginDeviceEnum = SmartEnumUtil.getEnumByValue(loginForm.getLoginDevice(), LoginDeviceEnum.class);
|
||||
if (loginDeviceEnum == null) {
|
||||
return ResponseDTO.userErrorParam("登录设备暂不支持!");
|
||||
}
|
||||
// 校验 图形验证码
|
||||
ResponseDTO<String> checkCaptcha = captchaService.checkCaptcha(loginForm);
|
||||
if (!checkCaptcha.getOk()) {
|
||||
return ResponseDTO.error(checkCaptcha);
|
||||
return ResponseDTO.error(checkCaptcha);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,8 +121,9 @@ public class LoginService {
|
||||
}
|
||||
|
||||
// 生成 登录token,保存token
|
||||
Boolean superPasswordFlag = superPassword.equals(requestPassword);
|
||||
String token = tokenService.generateToken(employeeEntity.getEmployeeId(), employeeEntity.getActualName(), UserTypeEnum.ADMIN_EMPLOYEE, loginDeviceEnum, superPasswordFlag);
|
||||
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);
|
||||
|
||||
//获取员工登录信息
|
||||
LoginEmployeeDetail loginEmployeeDetail = loadLoginInfo(employeeEntity);
|
||||
@ -164,8 +160,6 @@ public class LoginService {
|
||||
List<MenuVO> menuAndPointsList = employeePermissionService.getEmployeeMenuAndPointsList(employeeEntity.getEmployeeId(), employeeEntity.getAdministratorFlag());
|
||||
//前端菜单
|
||||
loginEmployeeDetail.setMenuList(menuAndPointsList);
|
||||
//后端权限
|
||||
loginEmployeeDetail.setAuthorities(employeePermissionService.buildAuthorities(menuAndPointsList));
|
||||
|
||||
//上次登录信息
|
||||
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
@ -199,6 +193,15 @@ public class LoginService {
|
||||
loginLogService.log(loginEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户信息缓存
|
||||
*
|
||||
* @param requestUserId
|
||||
*/
|
||||
public LoginEmployeeDetail getLoginUserDetailCache(Long requestUserId) {
|
||||
return loginUserDetailCache.get(requestUserId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除用户信息缓存
|
||||
@ -209,48 +212,15 @@ 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<String> logout(String token, RequestUser requestUser) {
|
||||
public ResponseDTO<String> logout(RequestUser requestUser) {
|
||||
loginUserDetailCache.remove(requestUser.getUserId());
|
||||
tokenService.removeToken(token);
|
||||
//保存登出日志
|
||||
tokenService.removeToken();
|
||||
// 保存登出日志
|
||||
saveLogoutLog(requestUser, requestUser.getIp(), requestUser.getUserAgent());
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.lab1024.sa.admin.module.system.menu.constant;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.lab1024.sa.common.common.enumeration.BaseEnum;
|
||||
|
||||
/**
|
||||
@ -12,6 +14,8 @@ import net.lab1024.sa.common.common.enumeration.BaseEnum;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuTypeEnum implements BaseEnum {
|
||||
/**
|
||||
* 目录
|
||||
@ -26,23 +30,7 @@ public enum MenuTypeEnum implements BaseEnum {
|
||||
*/
|
||||
POINTS(3, "功能点");
|
||||
|
||||
private Integer value;
|
||||
private final Integer value;
|
||||
|
||||
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;
|
||||
}
|
||||
private final String desc;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ 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;
|
||||
@ -39,25 +38,22 @@ public class MenuController extends AdminBaseController {
|
||||
|
||||
@ApiOperation(value = "添加菜单 @author 卓大")
|
||||
@PostMapping("/menu/add")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:menu:add')")
|
||||
public ResponseDTO<String> addMenu(@RequestBody @Valid MenuAddForm menuAddForm) {
|
||||
menuAddForm.setCreateUserId(SmartRequestUtil.getRequestUserId());
|
||||
menuAddForm.setCreateUserId(SmartRequestUtil.getUserId());
|
||||
return menuService.addMenu(menuAddForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "更新菜单 @author 卓大")
|
||||
@PostMapping("/menu/update")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:menu:update')")
|
||||
public ResponseDTO<String> updateMenu(@RequestBody @Valid MenuUpdateForm menuUpdateForm) {
|
||||
menuUpdateForm.setUpdateUserId(SmartRequestUtil.getRequestUserId());
|
||||
menuUpdateForm.setUpdateUserId(SmartRequestUtil.getUserId());
|
||||
return menuService.updateMenu(menuUpdateForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "批量删除菜单 @author 卓大")
|
||||
@GetMapping("/menu/batchDelete")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:menu:delete,system:menu:batch:delete')")
|
||||
public ResponseDTO<String> batchDeleteMenu(@RequestParam("menuIdList") List<Long> menuIdList) {
|
||||
return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getRequestUserId());
|
||||
return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getUserId());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询菜单列表 @author 卓大")
|
||||
|
@ -0,0 +1,55 @@
|
||||
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<String> MENU_URL_CACHE = null;
|
||||
|
||||
/**
|
||||
* 查询 需要校验权限的url
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> 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;
|
||||
}
|
||||
|
||||
}
|
@ -65,6 +65,12 @@ public class MenuService {
|
||||
menuEntity.setApiPerms(perms);
|
||||
}
|
||||
menuDao.insert(menuEntity);
|
||||
|
||||
// 清除权限缓存
|
||||
if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) {
|
||||
MenuCacheService.clearCache();
|
||||
}
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@ -102,6 +108,11 @@ public class MenuService {
|
||||
menuEntity.setApiPerms(perms);
|
||||
}
|
||||
menuDao.updateById(menuEntity);
|
||||
|
||||
// 清除权限缓存
|
||||
if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) {
|
||||
MenuCacheService.clearCache();
|
||||
}
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@ -118,8 +129,11 @@ public class MenuService {
|
||||
return ResponseDTO.userErrorParam("所选菜单不能为空");
|
||||
}
|
||||
menuDao.deleteByMenuIdList(menuIdList, employeeId, Boolean.TRUE);
|
||||
//孩子节点也需要删除
|
||||
// 子节点也需要删除
|
||||
this.recursiveDeleteChildren(menuIdList, employeeId);
|
||||
|
||||
// 清除权限缓存
|
||||
MenuCacheService.clearCache();
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ 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;
|
||||
@ -36,21 +35,18 @@ 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<String> deleteRole(@PathVariable Long roleId) {
|
||||
return roleService.deleteRole(roleId);
|
||||
}
|
||||
|
||||
@ApiOperation("更新角色 @author 卓大")
|
||||
@PostMapping("/role/update")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:role:update')")
|
||||
public ResponseDTO<String> updateRole(@Valid @RequestBody RoleUpdateForm roleUpdateDTO) {
|
||||
return roleService.updateRole(roleUpdateDTO);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -41,7 +40,6 @@ public class RoleDataScopeController extends AdminBaseController {
|
||||
|
||||
@ApiOperation(value = "批量设置某角色数据范围 @author 卓大")
|
||||
@PostMapping("/role/dataScope/updateRoleDataScopeList")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:role:dataScope:update')")
|
||||
public ResponseDTO<String> updateRoleDataScopeList(@RequestBody @Valid RoleDataScopeUpdateForm roleDataScopeUpdateForm) {
|
||||
return roleDataScopeService.updateRoleDataScopeList(roleDataScopeUpdateForm);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ 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;
|
||||
@ -50,21 +49,18 @@ public class RoleEmployeeController extends AdminBaseController {
|
||||
|
||||
@ApiOperation(value = "从角色成员列表中移除员工 @author 卓大")
|
||||
@GetMapping("/role/employee/removeEmployee")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:role:employee:delete')")
|
||||
public ResponseDTO<String> 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<String> 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<String> addEmployeeList(@Valid @RequestBody RoleEmployeeUpdateForm addForm) {
|
||||
return roleEmployeeService.batchAddRoleEmployee(addForm);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -34,7 +33,6 @@ public class RoleMenuController extends AdminBaseController {
|
||||
|
||||
@ApiOperation("更新角色权限 @author 卓大")
|
||||
@PostMapping("/role/menu/updateRoleMenu")
|
||||
@PreAuthorize("@saAuth.checkPermission('system:role:menu:update')")
|
||||
public ResponseDTO<String> updateRoleMenu(@Valid @RequestBody RoleMenuUpdateForm updateDTO) {
|
||||
return roleMenuService.updateRoleMenu(updateDTO);
|
||||
}
|
||||
|
@ -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.common.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager;
|
||||
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,6 +90,9 @@ public class RoleEmployeeService {
|
||||
return ResponseDTO.userErrorParam();
|
||||
}
|
||||
roleEmployeeDao.deleteByEmployeeIdRoleId(employeeId, roleId);
|
||||
|
||||
// 清理员工角色缓存
|
||||
EmployeePermissionService.clearUserRoleCache(employeeId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@ -100,7 +103,11 @@ public class RoleEmployeeService {
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
public ResponseDTO<String> batchRemoveRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) {
|
||||
roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), roleEmployeeUpdateForm.getEmployeeIdList());
|
||||
List<Long> employeeIdList = roleEmployeeUpdateForm.getEmployeeIdList();
|
||||
roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), employeeIdList);
|
||||
|
||||
// 清理员工角色缓存
|
||||
employeeIdList.forEach(EmployeePermissionService::clearUserRoleCache);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@ -122,6 +129,9 @@ public class RoleEmployeeService {
|
||||
}
|
||||
// 保存数据
|
||||
roleEmployeeManager.saveRoleEmployee(roleId, roleEmployeeList);
|
||||
|
||||
// 清理员工角色缓存
|
||||
employeeIdList.forEach(EmployeePermissionService::clearUserRoleCache);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
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;
|
||||
@ -67,7 +68,10 @@ public class RoleMenuService {
|
||||
roleMenuEntity.setMenuId(menuId);
|
||||
roleMenuEntityList.add(roleMenuEntity);
|
||||
}
|
||||
roleMenuManager.updateRoleMenu(roleMenuUpdateForm.getRoleId(), roleMenuEntityList);
|
||||
roleMenuManager.updateRoleMenu(roleId, roleMenuEntityList);
|
||||
|
||||
// 清理角色缓存
|
||||
EmployeePermissionService.clearRoleCache(roleId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@ -77,9 +81,9 @@ public class RoleMenuService {
|
||||
* @param roleIdList
|
||||
* @return
|
||||
*/
|
||||
public List<MenuVO> getMenuList(List<Long> roleIdList, Boolean administratorFlag) {
|
||||
//管理员返回所有菜单
|
||||
if(administratorFlag){
|
||||
public List<MenuVO> getMenuList(List<Long> roleIdList, Boolean adminFlag) {
|
||||
// 超管返回所有菜单
|
||||
if(adminFlag){
|
||||
List<MenuEntity> menuEntityList = roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(), false);
|
||||
return SmartBeanUtil.copyList(menuEntityList, MenuVO.class);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
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;
|
||||
@ -68,6 +69,9 @@ public class RoleService {
|
||||
roleDao.deleteById(roleId);
|
||||
roleMenuDao.deleteByRoleId(roleId);
|
||||
roleEmployeeDao.deleteByRoleId(roleId);
|
||||
|
||||
// 清理角色缓存
|
||||
EmployeePermissionService.clearRoleCache(roleId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ 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;
|
||||
@ -38,7 +37,6 @@ public class AdminCacheController extends SupportBaseController {
|
||||
|
||||
|
||||
@ApiOperation(value = "移除某个缓存 @author 罗伊")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:cache:delete')")
|
||||
@GetMapping("/cache/remove/{cacheName}")
|
||||
public ResponseDTO<String> removeCache(@PathVariable String cacheName) {
|
||||
cacheService.removeCache(cacheName);
|
||||
@ -47,7 +45,6 @@ public class AdminCacheController extends SupportBaseController {
|
||||
|
||||
|
||||
@ApiOperation(value = "获取某个缓存的所有key @author 罗伊")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:cache:keys')")
|
||||
@GetMapping("/cache/keys/{cacheName}")
|
||||
public ResponseDTO<List<String>> cacheKeys(@PathVariable String cacheName) {
|
||||
return ResponseDTO.ok(cacheService.cacheKey(cacheName));
|
||||
|
@ -9,7 +9,6 @@ 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;
|
||||
@ -31,27 +30,23 @@ public class AdminChangeLogController {
|
||||
|
||||
@ApiOperation("添加 @author 卓大")
|
||||
@PostMapping("/changeLog/add")
|
||||
@PreAuthorize("@saAuth.checkPermission('changeLog:add')")
|
||||
public ResponseDTO<String> add(@RequestBody @Valid ChangeLogAddForm addForm) {
|
||||
return changeLogService.add(addForm);
|
||||
}
|
||||
|
||||
@ApiOperation("更新 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('changeLog:update')")
|
||||
@PostMapping("/changeLog/update")
|
||||
public ResponseDTO<String> update(@RequestBody @Valid ChangeLogUpdateForm updateForm) {
|
||||
return changeLogService.update(updateForm);
|
||||
}
|
||||
|
||||
@ApiOperation("批量删除 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('changeLog:batchDelete')")
|
||||
@PostMapping("/changeLog/batchDelete")
|
||||
public ResponseDTO<String> batchDelete(@RequestBody ValidateList<Long> idList) {
|
||||
return changeLogService.batchDelete(idList);
|
||||
}
|
||||
|
||||
@ApiOperation("单个删除 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('changeLog:delete')")
|
||||
@GetMapping("/changeLog/delete/{changeLogId}")
|
||||
public ResponseDTO<String> batchDelete(@PathVariable Long changeLogId) {
|
||||
return changeLogService.delete(changeLogId);
|
||||
|
@ -12,7 +12,6 @@ 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;
|
||||
@ -36,21 +35,18 @@ public class AdminConfigController extends SupportBaseController {
|
||||
private ConfigService configService;
|
||||
|
||||
@ApiOperation("分页查询系统配置 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:config:query')")
|
||||
@PostMapping("/config/query")
|
||||
public ResponseDTO<PageResult<ConfigVO>> querySystemConfigPage(@RequestBody @Valid ConfigQueryForm queryForm) {
|
||||
return configService.queryConfigPage(queryForm);
|
||||
}
|
||||
|
||||
@ApiOperation("添加配置参数 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:config:add')")
|
||||
@PostMapping("/config/add")
|
||||
public ResponseDTO<String> addSystemConfig(@RequestBody @Valid ConfigAddForm configAddForm) {
|
||||
return configService.add(configAddForm);
|
||||
}
|
||||
|
||||
@ApiOperation("修改配置参数 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:config:update')")
|
||||
@PostMapping("/config/update")
|
||||
public ResponseDTO<String> updateSystemConfig(@RequestBody @Valid ConfigUpdateForm updateForm) {
|
||||
return configService.updateSystemConfig(updateForm);
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -34,7 +33,6 @@ public class AdminFileController extends SupportBaseController {
|
||||
private FileService fileService;
|
||||
|
||||
@ApiOperation("分页查询 @author 1024创新实验室-主任-卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:file:query')")
|
||||
@PostMapping("/file/queryPage")
|
||||
public ResponseDTO<PageResult<FileVO>> queryPage(@RequestBody @Valid FileQueryForm queryForm) {
|
||||
return ResponseDTO.ok(fileService.queryPage(queryForm));
|
||||
|
@ -13,7 +13,6 @@ 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;
|
||||
@ -42,14 +41,12 @@ public class AdminHelpDocController extends SupportBaseController {
|
||||
|
||||
|
||||
@ApiOperation("帮助文档目录-添加 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDocCatalog:addCategory')")
|
||||
@PostMapping("/helpDoc/helpDocCatalog/add")
|
||||
public ResponseDTO<String> addHelpDocCatalog(@RequestBody @Valid HelpDocCatalogAddForm helpDocCatalogAddForm) {
|
||||
return helpDocCatalogService.add(helpDocCatalogAddForm);
|
||||
}
|
||||
|
||||
@ApiOperation("帮助文档目录-更新 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDocCatalog:edit')")
|
||||
@PostMapping("/helpDoc/helpDocCatalog/update")
|
||||
public ResponseDTO<String> updateHelpDocCatalog(@RequestBody @Valid HelpDocCatalogUpdateForm helpDocCatalogUpdateForm) {
|
||||
return helpDocCatalogService.update(helpDocCatalogUpdateForm);
|
||||
@ -64,7 +61,6 @@ public class AdminHelpDocController extends SupportBaseController {
|
||||
// --------------------- 帮助文档 【管理:增、删、查、改】-------------------------
|
||||
|
||||
@ApiOperation("【管理】帮助文档-分页查询 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDoc:query')")
|
||||
@PostMapping("/helpDoc/query")
|
||||
public ResponseDTO<PageResult<HelpDocVO>> query(@RequestBody @Valid HelpDocQueryForm queryForm) {
|
||||
return ResponseDTO.ok(helpDocService.query(queryForm));
|
||||
@ -77,7 +73,6 @@ public class AdminHelpDocController extends SupportBaseController {
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】帮助文档-添加 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDoc:add')")
|
||||
@PostMapping("/helpDoc/add")
|
||||
@RepeatSubmit
|
||||
public ResponseDTO<String> add(@RequestBody @Valid HelpDocAddForm addForm) {
|
||||
@ -85,7 +80,6 @@ public class AdminHelpDocController extends SupportBaseController {
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】帮助文档-更新 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDoc:update')")
|
||||
@PostMapping("/helpDoc/update")
|
||||
@RepeatSubmit
|
||||
public ResponseDTO<String> update(@RequestBody @Valid HelpDocUpdateForm updateForm) {
|
||||
@ -93,7 +87,6 @@ public class AdminHelpDocController extends SupportBaseController {
|
||||
}
|
||||
|
||||
@ApiOperation("【管理】帮助文档-删除 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('helpDoc:delete')")
|
||||
@GetMapping("/helpDoc/delete/{helpDocId}")
|
||||
public ResponseDTO<String> delete(@PathVariable Long helpDocId) {
|
||||
return helpDocService.delete(helpDocId);
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -32,7 +31,6 @@ public class AdminLoginLogController extends SupportBaseController {
|
||||
private LoginLogService loginLogService;
|
||||
|
||||
@ApiOperation(value = "分页查询 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('loginLog:query')")
|
||||
@PostMapping("/loginLog/page/query")
|
||||
public ResponseDTO<PageResult<LoginLogVO>> queryByPage(@RequestBody LoginLogQueryForm queryForm) {
|
||||
return loginLogService.queryByPage(queryForm);
|
||||
|
@ -10,7 +10,6 @@ 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.*;
|
||||
|
||||
/**
|
||||
@ -30,14 +29,12 @@ public class AdminOperateLogController extends SupportBaseController {
|
||||
private OperateLogService operateLogService;
|
||||
|
||||
@ApiOperation(value = "分页查询 @author 罗伊")
|
||||
@PreAuthorize("@saAuth.checkPermission('operateLog:query')")
|
||||
@PostMapping("/operateLog/page/query")
|
||||
public ResponseDTO<PageResult<OperateLogVO>> queryByPage(@RequestBody OperateLogQueryForm queryForm) {
|
||||
return operateLogService.queryByPage(queryForm);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "详情 @author 罗伊")
|
||||
@PreAuthorize("@saAuth.checkPermission('operateLog:detail')")
|
||||
@GetMapping("/operateLog/detail/{operateLogId}")
|
||||
public ResponseDTO<OperateLogVO> detail(@PathVariable Long operateLogId) {
|
||||
return operateLogService.detail(operateLogId);
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -39,14 +38,12 @@ public class AdminReloadController extends SupportBaseController {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取reload result @author 开云")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:reload:result')")
|
||||
@GetMapping("/reload/result/{tag}")
|
||||
public ResponseDTO<List<ReloadResultVO>> queryReloadResult(@PathVariable("tag") String tag) {
|
||||
return reloadService.queryReloadItemResult(tag);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "通过tag更新标识 @author 开云")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:reload:execute')")
|
||||
@PostMapping("/reload/update")
|
||||
public ResponseDTO<String> updateByTag(@RequestBody @Valid ReloadForm reloadForm) {
|
||||
return reloadService.updateByTag(reloadForm);
|
||||
|
@ -16,7 +16,6 @@ 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;
|
||||
@ -48,7 +47,6 @@ public class AdminSerialNumberController extends SupportBaseController {
|
||||
private SerialNumberRecordService serialNumberRecordService;
|
||||
|
||||
@ApiOperation("生成单号 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:serial:number:generate')")
|
||||
@PostMapping("/serialNumber/generate")
|
||||
public ResponseDTO<List<String>> generate(@RequestBody @Valid SerialNumberGenerateForm generateForm) {
|
||||
SerialNumberIdEnum serialNumberIdEnum = SmartEnumUtil.getEnumByValue(generateForm.getSerialNumberId(), SerialNumberIdEnum.class);
|
||||
@ -65,7 +63,6 @@ public class AdminSerialNumberController extends SupportBaseController {
|
||||
}
|
||||
|
||||
@ApiOperation("获取生成记录 @author 卓大")
|
||||
@PreAuthorize("@saAuth.checkPermission('support:serial:number:record')")
|
||||
@PostMapping("/serialNumber/queryRecord")
|
||||
public ResponseDTO<PageResult<SerialNumberRecordEntity>> queryRecord(@RequestBody @Valid SerialNumberRecordQueryForm queryForm) {
|
||||
return ResponseDTO.ok(serialNumberRecordService.query(queryForm));
|
||||
|
@ -49,12 +49,19 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- spring security -->
|
||||
<!-- sa-token start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token end -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
|
@ -1,22 +0,0 @@
|
||||
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";
|
||||
}
|
@ -24,7 +24,7 @@ public enum UserErrorCode implements ErrorCode {
|
||||
|
||||
REPEAT_SUBMIT(30004, "亲~您操作的太快了,请稍等下再操作~"),
|
||||
|
||||
NO_PERMISSION(30005, "对不起,您无法访问此资源哦~"),
|
||||
NO_PERMISSION(30005, "对不起,您无法访问此内容哦~"),
|
||||
|
||||
DEVELOPING(30006, "系統正在紧急开发中,敬请期待~"),
|
||||
|
||||
@ -32,7 +32,11 @@ public enum UserErrorCode implements ErrorCode {
|
||||
|
||||
USER_STATUS_ERROR(30008, "用户状态异常"),
|
||||
|
||||
FORM_REPEAT_SUBMIT(30009, "请勿重复提交");
|
||||
FORM_REPEAT_SUBMIT(30009, "请勿重复提交"),
|
||||
|
||||
LOGIN_FROM_OTHER(30010, "您的账号已在其他地方登录"),
|
||||
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
||||
|
@ -26,6 +26,11 @@ public class StringConst {
|
||||
*/
|
||||
public static final String HORIZONTAL = "-";
|
||||
|
||||
/**
|
||||
* 全局通用 冒号
|
||||
*/
|
||||
public static final String COLON = ":";
|
||||
|
||||
/**
|
||||
* 全局通用分隔符
|
||||
*/
|
||||
|
@ -18,9 +18,6 @@ public class RequestUrlVO {
|
||||
@ApiModelProperty("注释说明")
|
||||
private String comment;
|
||||
|
||||
@ApiModelProperty("controller.method")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("url")
|
||||
private String url;
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
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
|
||||
@ -11,39 +13,25 @@ import net.lab1024.sa.common.common.enumeration.UserTypeEnum;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
*/
|
||||
public interface RequestUser {
|
||||
@Data
|
||||
public class RequestUser {
|
||||
|
||||
/**
|
||||
* 请求用户id
|
||||
*
|
||||
* @return
|
||||
* 当前请求用户id
|
||||
*/
|
||||
Long getUserId();
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 请求用户名称
|
||||
*
|
||||
* @return
|
||||
* 当前请求用户名称
|
||||
*/
|
||||
String getUserName();
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 获取用户类型
|
||||
* 当前请求用户类型
|
||||
*/
|
||||
UserTypeEnum getUserType();
|
||||
private UserTypeEnum userType;
|
||||
|
||||
/**
|
||||
* 获取请求的IP
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getIp();
|
||||
|
||||
/**
|
||||
* 获取请求 user-agent
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getUserAgent();
|
||||
private String ip;
|
||||
|
||||
private String userAgent;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.lab1024.sa.common.common.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvEnum;
|
||||
|
||||
/**
|
||||
* 系统环境
|
||||
@ -16,7 +16,7 @@ import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum;
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class SystemEnvironment {
|
||||
public class SystemEnv {
|
||||
|
||||
/**
|
||||
* 是否位生产环境
|
||||
@ -31,5 +31,5 @@ public class SystemEnvironment {
|
||||
/**
|
||||
* 当前环境
|
||||
*/
|
||||
private SystemEnvironmentEnum currentEnvironment;
|
||||
private SystemEnvEnum currentEnv;
|
||||
}
|
@ -15,32 +15,32 @@ import lombok.Getter;
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum SystemEnvironmentEnum implements BaseEnum {
|
||||
public enum SystemEnvEnum implements BaseEnum {
|
||||
/**
|
||||
* dev
|
||||
*/
|
||||
DEV(SystemEnvironmentNameConst.DEV, "开发环境"),
|
||||
DEV(EnvConst.DEV, "开发环境"),
|
||||
|
||||
/**
|
||||
* test
|
||||
*/
|
||||
TEST(SystemEnvironmentNameConst.TEST, "测试环境"),
|
||||
TEST(EnvConst.TEST, "测试环境"),
|
||||
|
||||
/**
|
||||
* pre
|
||||
*/
|
||||
PRE(SystemEnvironmentNameConst.PRE, "预发布环境"),
|
||||
PRE(EnvConst.PRE, "预发布环境"),
|
||||
|
||||
/**
|
||||
* prod
|
||||
*/
|
||||
PROD(SystemEnvironmentNameConst.PROD, "生产环境");
|
||||
PROD(EnvConst.PROD, "生产环境");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String desc;
|
||||
|
||||
public static final class SystemEnvironmentNameConst {
|
||||
public static final class EnvConst {
|
||||
public static final String DEV = "dev";
|
||||
public static final String TEST = "test";
|
||||
public static final String PRE = "pre";
|
@ -1,5 +1,8 @@
|
||||
package net.lab1024.sa.common.common.enumeration;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户类型
|
||||
*
|
||||
@ -9,29 +12,16 @@ package net.lab1024.sa.common.common.enumeration;
|
||||
* @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 Integer type;
|
||||
private final Integer value;
|
||||
|
||||
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;
|
||||
}
|
||||
private final String desc;
|
||||
}
|
||||
|
@ -1,17 +1,27 @@
|
||||
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.util.CollectionUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
@ -19,48 +29,56 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 抽象拦截器
|
||||
* 只校验了登录处理
|
||||
* 自定义的拦截器 可以继承此类
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2021-10-09 20:56:14
|
||||
* @Wechat zhuoda1024
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
* @author huke
|
||||
* @date 2023-07-12 21:56:14
|
||||
*/
|
||||
public abstract class AbstractInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
private List<String> ignoreUrlList;
|
||||
|
||||
private SystemEnv systemEnv;
|
||||
|
||||
/**
|
||||
* Token获取用户信息
|
||||
* 校验 token
|
||||
*
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
protected abstract Function<String, RequestUser> userFunction();
|
||||
public abstract RequestUser getDevUser(Long userId);
|
||||
|
||||
/**
|
||||
* 校验 当前服务用户类型
|
||||
*/
|
||||
public abstract UserTypeEnum getUserType();
|
||||
|
||||
/**
|
||||
* 拦截路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String[] pathPatterns();
|
||||
public abstract List<String> pathPatterns();
|
||||
|
||||
/**
|
||||
* 忽略的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected List<String> getIgnoreUrlList() {
|
||||
public List<String> getIgnoreUrlList() {
|
||||
List<String> ignoreUrlList = Lists.newArrayList();
|
||||
ignoreUrlList.add("/swagger-ui.html");
|
||||
ignoreUrlList.add("/swagger-resources/**");
|
||||
ignoreUrlList.add("/webjars/**");
|
||||
ignoreUrlList.add("/druid/**");
|
||||
ignoreUrlList.add("/*/api-docs");
|
||||
return ignoreUrlList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截服务器端响应处理ajax请求返回结果
|
||||
* 拦截处理登录 token
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
@ -71,60 +89,81 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
// OPTIONS请求直接return
|
||||
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
|
||||
if (StringUtils.equalsIgnoreCase(HttpMethod.OPTIONS.name(), request.getMethod())) {
|
||||
response.setStatus(HttpStatus.NO_CONTENT.value());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isHandler = handler instanceof HandlerMethod;
|
||||
if (!isHandler) {
|
||||
return true;
|
||||
}
|
||||
//放行的Uri前缀
|
||||
String uri = request.getRequestURI();
|
||||
String contextPath = request.getContextPath();
|
||||
String target = uri.replaceFirst(contextPath, "");
|
||||
if (this.contain(this.getIgnoreUrlList(), target)) {
|
||||
// 校验 token
|
||||
ResponseDTO<RequestUser> res = this.checkTokenAndGetUser(request);
|
||||
if (res.getOk()) {
|
||||
SmartRequestUtil.setUser(res.getData());
|
||||
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;
|
||||
}
|
||||
if (StringUtils.isBlank(xAccessToken)) {
|
||||
this.outputResult(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
this.outputResult(response, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean contain(List<String> ignores, String uri) {
|
||||
if (CollectionUtils.isEmpty(ignores)) {
|
||||
return false;
|
||||
}
|
||||
for (String ignoreUrl : ignores) {
|
||||
if (uri.startsWith(ignoreUrl)) {
|
||||
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 已被冻结
|
||||
* <p>
|
||||
* ps :之所以没有在全局异常里处理 是因为后续还有操作
|
||||
*/
|
||||
public ResponseDTO<RequestUser> 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);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,13 +175,40 @@ public abstract class AbstractInterceptor implements HandlerInterceptor {
|
||||
*/
|
||||
private void outputResult(HttpServletResponse response, ResponseDTO responseDTO) throws IOException {
|
||||
String msg = JSONObject.toJSONString(responseDTO);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
response.getWriter().write(msg);
|
||||
response.flushBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
SmartRequestUtil.remove();
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +0,0 @@
|
||||
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<String> noNeedLoginUrlList;
|
||||
|
||||
@Autowired
|
||||
private List<String> ignoreUrlList;
|
||||
|
||||
/**
|
||||
* Token获取用户信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract BiFunction<String, HttpServletRequest, UserDetails> 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
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<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
|
||||
//如果不存在SaAuth采用security认证模式
|
||||
SaAuth saAuth = method.getAnnotation(SaAuth.class);
|
||||
if (saAuth == null) {
|
||||
return super.getAttributes(method, targetClass);
|
||||
}
|
||||
|
||||
//存在添加以URL为权限字符串的校验模式
|
||||
ArrayList<ConfigAttribute> 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;
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
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<String,HttpServletRequest, UserDetails> userFunction;
|
||||
|
||||
public SecurityTokenFilter(BiFunction<String,HttpServletRequest, UserDetails> 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);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package net.lab1024.sa.common.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import net.lab1024.sa.common.common.domain.RequestUser;
|
||||
|
||||
/**
|
||||
@ -12,26 +13,28 @@ import net.lab1024.sa.common.common.domain.RequestUser;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
*/
|
||||
@Slf4j
|
||||
public class SmartRequestUtil {
|
||||
|
||||
private static final ThreadLocal<RequestUser> requestThreadLocal = new ThreadLocal<>();
|
||||
private static final String STORAGE_KEY = "user";
|
||||
|
||||
public static void setRequestUser(RequestUser requestUser) {
|
||||
requestThreadLocal.set(requestUser);
|
||||
public static void setUser(RequestUser user) {
|
||||
SaStorage storage = SaHolder.getStorage();
|
||||
storage.set(STORAGE_KEY, user);
|
||||
}
|
||||
|
||||
public static RequestUser getRequestUser() {
|
||||
return requestThreadLocal.get();
|
||||
/**
|
||||
* 获取 当前 token 请求用户
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static RequestUser getUser() {
|
||||
SaStorage storage = SaHolder.getStorage();
|
||||
return storage.getModel(STORAGE_KEY, RequestUser.class);
|
||||
}
|
||||
|
||||
public static Long getRequestUserId() {
|
||||
RequestUser requestUser = getRequestUser();
|
||||
return null == requestUser ? null : requestUser.getUserId();
|
||||
}
|
||||
|
||||
public static void remove() {
|
||||
requestThreadLocal.remove();
|
||||
public static Long getUserId() {
|
||||
RequestUser user = getUser();
|
||||
return null != user ? user.getUserId() : null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,7 +153,7 @@ public class DataSourceConfig {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Conditional(SystemEnvironmentConfig.class)
|
||||
@Conditional(SystemEnvConfig.class)
|
||||
@Bean
|
||||
public ServletRegistrationBean<StatViewServlet> druidServlet() {
|
||||
ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>();
|
||||
|
@ -1,16 +1,19 @@
|
||||
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相关配置
|
||||
@ -25,16 +28,28 @@ import java.util.List;
|
||||
public class MvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<HandlerInterceptor> interceptorList;
|
||||
private List<AbstractInterceptor> interceptorList;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<SaInterceptor> saInterceptorList;
|
||||
|
||||
@Override
|
||||
public void addInterceptors (InterceptorRegistry registry) {
|
||||
if (CollectionUtils.isEmpty(interceptorList)) {
|
||||
return;
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 先注册 登录拦截器
|
||||
Set<String> 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));
|
||||
});
|
||||
}
|
||||
interceptorList.forEach(e->{
|
||||
registry.addInterceptor(e).addPathPatterns("/**");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,7 +31,7 @@ public class RepeatSubmitConfig {
|
||||
* @return
|
||||
*/
|
||||
private String ticket(String servletPath) {
|
||||
Long userId = SmartRequestUtil.getRequestUserId();
|
||||
Long userId = SmartRequestUtil.getUserId();
|
||||
if (null == userId) {
|
||||
return StringConst.EMPTY;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ import java.util.Map;
|
||||
@Slf4j
|
||||
@EnableSwagger2
|
||||
@Configuration
|
||||
@Conditional(SystemEnvironmentConfig.class)
|
||||
@Conditional(SystemEnvConfig.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("1")
|
||||
.parameterType("header").defaultValue("0")
|
||||
.required(false)
|
||||
.build();
|
||||
return Lists.newArrayList(token);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.lab1024.sa.common.config;
|
||||
|
||||
import net.lab1024.sa.common.common.domain.SystemEnvironment;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum;
|
||||
import net.lab1024.sa.common.common.domain.SystemEnv;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvEnum;
|
||||
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 SystemEnvironmentConfig implements Condition {
|
||||
public class SystemEnvConfig implements Condition {
|
||||
|
||||
@Value("${spring.profiles.active}")
|
||||
private String systemEnvironment;
|
||||
@ -32,18 +32,18 @@ public class SystemEnvironmentConfig implements Condition {
|
||||
@Override
|
||||
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
|
||||
String property = conditionContext.getEnvironment().getProperty("spring.profiles.active");
|
||||
return StringUtils.isNotBlank(property) && !SystemEnvironmentEnum.PROD.equalsValue(property);
|
||||
return StringUtils.isNotBlank(property) && !SystemEnvEnum.PROD.equalsValue(property);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SystemEnvironment initEnvironment() {
|
||||
SystemEnvironmentEnum currentEnvironment = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvironmentEnum.class);
|
||||
if (currentEnvironment == null) {
|
||||
public SystemEnv initEnvironment() {
|
||||
SystemEnvEnum currentEnv = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvEnum.class);
|
||||
if (currentEnv == null) {
|
||||
throw new ExceptionInInitializerError("无法获取当前环境!请在 application.yaml 配置参数:spring.profiles.active");
|
||||
}
|
||||
if (StringUtils.isBlank(projectName)) {
|
||||
throw new ExceptionInInitializerError("无法获取当前项目名称!请在 application.yaml 配置参数:project.name");
|
||||
}
|
||||
return new SystemEnvironment(currentEnvironment == SystemEnvironmentEnum.PROD, projectName, currentEnvironment);
|
||||
return new SystemEnv(currentEnv == SystemEnvEnum.PROD, projectName, currentEnv);
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
package net.lab1024.sa.common.config;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
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;
|
||||
@ -23,21 +22,18 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* url配置
|
||||
* description
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2022-05-30 21:22:12
|
||||
* @Wechat zhuoda1024
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
* @author Turbolisten
|
||||
* @date 2023/7/13 17:42
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class UrlConfig {
|
||||
|
||||
@Autowired
|
||||
private RequestMappingHandlerMapping requestMappingHandlerMapping;
|
||||
|
||||
|
||||
/**
|
||||
* 获取每个方法的请求路径
|
||||
*
|
||||
@ -46,11 +42,10 @@ public class UrlConfig {
|
||||
@Bean
|
||||
public Map<Method, Set<String>> methodUrlMap() {
|
||||
Map<Method, Set<String>> methodUrlMap = Maps.newHashMap();
|
||||
//获取url与类和方法的对应信息
|
||||
// 获取url与类和方法的对应信息
|
||||
Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
|
||||
RequestMappingInfo requestMappingInfo = entry.getKey();
|
||||
|
||||
Set<String> urls = requestMappingInfo.getPatternsCondition().getPatterns();
|
||||
if (CollectionUtils.isEmpty(urls)) {
|
||||
continue;
|
||||
@ -72,14 +67,20 @@ public class UrlConfig {
|
||||
List<RequestUrlVO> authUrlList = Lists.newArrayList();
|
||||
for (Map.Entry<Method, Set<String>> entry : methodUrlMap.entrySet()) {
|
||||
Method method = entry.getKey();
|
||||
SaAuth saAuth = method.getAnnotation(SaAuth.class);
|
||||
if (null == saAuth) {
|
||||
// 忽略权限
|
||||
SaIgnore ignore = method.getAnnotation(SaIgnore.class);
|
||||
if (null != ignore) {
|
||||
continue;
|
||||
}
|
||||
List<RequestUrlVO> requestUrlList = this.buildRequestUrl(method, entry.getValue());
|
||||
NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class);
|
||||
if (null != noNeedLogin) {
|
||||
continue;
|
||||
}
|
||||
Set<String> urlSet = entry.getValue();
|
||||
List<RequestUrlVO> requestUrlList = this.buildRequestUrl(method, urlSet);
|
||||
authUrlList.addAll(requestUrlList);
|
||||
}
|
||||
log.info("需要权限校验的URL:{}", authUrlList.stream().map(e -> e.getUrl()).collect(Collectors.toList()));
|
||||
log.info("需要权限校验的URL:{}", authUrlList.stream().map(RequestUrlVO::getUrl).collect(Collectors.toList()));
|
||||
return authUrlList;
|
||||
}
|
||||
|
||||
@ -88,29 +89,22 @@ public class UrlConfig {
|
||||
if (CollectionUtils.isEmpty(urlSet)) {
|
||||
return requestUrlList;
|
||||
}
|
||||
//url对应的方法名称
|
||||
String className = method.getDeclaringClass().getName();
|
||||
String methodName = method.getName();
|
||||
List<String> list = StrUtil.split(className, ".");
|
||||
String controllerName = list.get(list.size() - 1);
|
||||
String name = controllerName + "." + methodName;
|
||||
//swagger 说明信息
|
||||
// swagger api 说明
|
||||
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信息
|
||||
*
|
||||
@ -130,21 +124,4 @@ public class UrlConfig {
|
||||
log.info("不需要登录的URL:{}", noNeedLoginUrlList);
|
||||
return noNeedLoginUrlList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取忽略的url信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public List<String> ignoreUrlList() {
|
||||
List<String> ignoreUrlList = Lists.newArrayList();
|
||||
ignoreUrlList.add("/swagger-ui.html");
|
||||
ignoreUrlList.add("/swagger-resources/**");
|
||||
ignoreUrlList.add("/webjars/**");
|
||||
ignoreUrlList.add("/druid/**");
|
||||
ignoreUrlList.add("/*/api-docs");
|
||||
return ignoreUrlList;
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
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.SystemEnvironment;
|
||||
import net.lab1024.sa.common.common.domain.SystemEnv;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvEnum;
|
||||
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;
|
||||
@ -37,7 +38,7 @@ import java.util.stream.Collectors;
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@Autowired
|
||||
private SystemEnvironment systemEnvironment;
|
||||
private SystemEnv systemEnv;
|
||||
|
||||
/**
|
||||
* json 格式错误 缺少请求体
|
||||
@ -45,7 +46,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseBody
|
||||
@ExceptionHandler({HttpMessageNotReadableException.class})
|
||||
public ResponseDTO<?> jsonFormatExceptionHandler(Exception e) {
|
||||
if (!systemEnvironment.isProd()) {
|
||||
if (!systemEnv.isProd()) {
|
||||
log.error("全局JSON格式错误异常,URL:{}", getCurrentRequestUrl(), e);
|
||||
}
|
||||
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "参数JSON格式错误");
|
||||
@ -57,7 +58,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseBody
|
||||
@ExceptionHandler({TypeMismatchException.class, BindException.class})
|
||||
public ResponseDTO<?> paramExceptionHandler(Exception e) {
|
||||
if (!systemEnvironment.isProd()) {
|
||||
if (!systemEnv.isProd()) {
|
||||
log.error("全局参数异常,URL:{}", getCurrentRequestUrl(), e);
|
||||
}
|
||||
|
||||
@ -77,27 +78,34 @@ 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 (!systemEnvironment.isProd()) {
|
||||
if (!systemEnv.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<String> permissionException(NotPermissionException e) {
|
||||
// 开发环境 方便调试
|
||||
if (SystemEnvEnum.PROD != systemEnv.getCurrentEnv()) {
|
||||
return ResponseDTO.error(UserErrorCode.NO_PERMISSION, e.getMessage());
|
||||
}
|
||||
return ResponseDTO.error(UserErrorCode.NO_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他全部异常
|
||||
*
|
||||
@ -108,7 +116,7 @@ public class GlobalExceptionHandler {
|
||||
@ExceptionHandler(Throwable.class)
|
||||
public ResponseDTO<?> errorHandler(Throwable e) {
|
||||
log.error("捕获全局异常,URL:{}", getCurrentRequestUrl(), e);
|
||||
return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnvironment.isProd() ? null : e.toString());
|
||||
return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnv.isProd() ? null : e.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,10 +2,9 @@ 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.SystemEnvironment;
|
||||
import net.lab1024.sa.common.common.domain.SystemEnv;
|
||||
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;
|
||||
@ -43,7 +42,7 @@ public class CaptchaService {
|
||||
@Autowired
|
||||
private DefaultKaptcha defaultKaptcha;
|
||||
@Autowired
|
||||
private SystemEnvironment systemEnvironment;
|
||||
private SystemEnv systemEnvironment;
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
|
@ -157,7 +157,7 @@ public class DataTracerService {
|
||||
* 保存数据变动记录
|
||||
*/
|
||||
public void addTrace(DataTracerForm tracerForm) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
this.addTrace(tracerForm, requestUser);
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ public class DataTracerService {
|
||||
* 批量保存数据变动记录
|
||||
*/
|
||||
public void addTraceList(List<DataTracerForm> tracerFormList) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
this.addTraceList(tracerFormList, requestUser);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ 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;
|
||||
@ -47,7 +46,7 @@ public class FeedbackController extends SupportBaseController {
|
||||
@ApiOperation("意见反馈-新增 @author 开云")
|
||||
@PostMapping("/feedback/add")
|
||||
public ResponseDTO<String> add(@RequestBody @Valid FeedbackAddForm addForm) {
|
||||
RequestUser employee = SmartRequestUtil.getRequestUser();
|
||||
RequestUser employee = SmartRequestUtil.getUser();
|
||||
return feedbackService.add(addForm, employee);
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,13 @@ 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.domain.form.FileQueryForm;
|
||||
import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum;
|
||||
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;
|
||||
@ -46,14 +42,14 @@ public class FileController extends SupportBaseController {
|
||||
@PostMapping("/file/upload")
|
||||
public ResponseDTO<FileUploadVO> upload(@RequestParam MultipartFile file,
|
||||
@RequestParam Integer folder) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
return fileService.fileUpload(file, folder, requestUser);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "文件上传,通过url上传 @author 胡克", notes = FileFolderTypeEnum.INFO)
|
||||
@PostMapping("/file/upload/url")
|
||||
public ResponseDTO<FileUploadVO> uploadByUrl(@RequestBody @Valid FileUrlUploadForm uploadForm) {
|
||||
RequestUser requestUser = SmartRequestUtil.getRequestUser();
|
||||
RequestUser requestUser = SmartRequestUtil.getUser();
|
||||
return fileService.fileUpload(uploadForm,requestUser);
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class HelpDocController extends SupportBaseController {
|
||||
@RepeatSubmit
|
||||
public ResponseDTO<HelpDocDetailVO> view(@PathVariable Long helpDocId, HttpServletRequest request) {
|
||||
return helpDocUserService.view(
|
||||
SmartRequestUtil.getRequestUser(),
|
||||
SmartRequestUtil.getUser(),
|
||||
helpDocId);
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ public abstract class OperateLogAspect {
|
||||
return;
|
||||
}
|
||||
//设置用户信息
|
||||
RequestUser user = SmartRequestUtil.getRequestUser();
|
||||
RequestUser user = SmartRequestUtil.getUser();
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.lab1024.sa.common.module.support.redis;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import net.lab1024.sa.common.common.domain.SystemEnvironment;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum;
|
||||
import net.lab1024.sa.common.common.domain.SystemEnv;
|
||||
import net.lab1024.sa.common.common.enumeration.SystemEnvEnum;
|
||||
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<String, Object> redisSetOperations;
|
||||
|
||||
@Autowired
|
||||
private SystemEnvironment systemEnvironment;
|
||||
private SystemEnv systemEnvironment;
|
||||
|
||||
|
||||
/**
|
||||
@ -62,7 +62,7 @@ public class RedisService {
|
||||
* @return
|
||||
*/
|
||||
public String generateRedisKey(String prefix, String key) {
|
||||
SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment();
|
||||
SystemEnvEnum currentEnvironment = systemEnvironment.getCurrentEnv();
|
||||
return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key;
|
||||
}
|
||||
|
||||
|
@ -33,19 +33,19 @@ public class TableColumnController extends SupportBaseController {
|
||||
@PostMapping("/tableColumn/update")
|
||||
@RepeatSubmit
|
||||
public ResponseDTO<String> updateTableColumn(@RequestBody @Valid TableColumnUpdateForm updateForm) {
|
||||
return tableColumnService.updateTableColumns(SmartRequestUtil.getRequestUser(), updateForm);
|
||||
return tableColumnService.updateTableColumns(SmartRequestUtil.getUser(), updateForm);
|
||||
}
|
||||
|
||||
@ApiOperation("恢复默认(删除) @author 卓大")
|
||||
@GetMapping("/tableColumn/delete/{tableId}")
|
||||
@RepeatSubmit
|
||||
public ResponseDTO<String> deleteTableColumn(@PathVariable Integer tableId) {
|
||||
return tableColumnService.deleteTableColumn(SmartRequestUtil.getRequestUser(), tableId);
|
||||
return tableColumnService.deleteTableColumn(SmartRequestUtil.getUser(), tableId);
|
||||
}
|
||||
|
||||
@ApiOperation("查询表格列 @author 卓大")
|
||||
@GetMapping("/tableColumn/getColumns/{tableId}")
|
||||
public ResponseDTO<String> getColumns(@PathVariable Integer tableId) {
|
||||
return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getRequestUser(), tableId));
|
||||
return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getUser(), tableId));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.lab1024.sa.common.module.support.token;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.lab1024.sa.common.common.enumeration.BaseEnum;
|
||||
|
||||
/**
|
||||
@ -11,6 +13,8 @@ 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, "电脑端"),
|
||||
@ -21,23 +25,9 @@ public enum LoginDeviceEnum implements BaseEnum {
|
||||
|
||||
H5(4, "H5"),
|
||||
|
||||
WEIXIN_MP(5, "微信小程序");
|
||||
WX_MP(5, "微信小程序");
|
||||
|
||||
LoginDeviceEnum(Integer value, String desc) {
|
||||
this.value = value;
|
||||
this.desc = desc;
|
||||
}
|
||||
private final Integer value;
|
||||
|
||||
private Integer value;
|
||||
private String desc;
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
private final String desc;
|
||||
}
|
||||
|
@ -1,220 +1,85 @@
|
||||
package net.lab1024.sa.common.module.support.token;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 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.Date;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 与用户token的相关的服务
|
||||
* 用户token 相关服务
|
||||
*
|
||||
* @Author 1024创新实验室-主任: 卓大
|
||||
* @Date 2021-11-29 19:48:35
|
||||
* @Wechat zhuoda1024
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
* @author listen
|
||||
* @date 2023-07-12 22:48:35
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class TokenService {
|
||||
private static final long HOUR_TIME_MILLI = 60 * 60 * 1000;
|
||||
|
||||
@Value("${token.key}")
|
||||
private String tokenKey;
|
||||
public static final String EXTRA_KEY_USER_NAME = "userName";
|
||||
|
||||
@Value("${token.expire-day}")
|
||||
private Integer tokenExpire;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
public static final String EXTRA_KEY_USER_TYPE = "userType";
|
||||
|
||||
/**
|
||||
* 生成Token,并存入redis
|
||||
* 生成Token
|
||||
*
|
||||
* @param userId
|
||||
* @param userName
|
||||
* @param userTypeEnum
|
||||
* @param loginDeviceEnum
|
||||
* @param superPasswordFlag 特殊万能密码标识
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
public String generateToken(Long userId,
|
||||
String userName,
|
||||
UserTypeEnum userTypeEnum,
|
||||
LoginDeviceEnum loginDeviceEnum) {
|
||||
|
||||
// 如果是万能密码,则不需要记录到redis中;万能密码最多半个小时有效期
|
||||
if (superPasswordFlag) {
|
||||
jwtBuilder.setExpiration(new Date(nowTimeMilli + (HOUR_TIME_MILLI / 2)));
|
||||
return jwtBuilder.compact();
|
||||
}
|
||||
/**
|
||||
* 设置登录模式参数
|
||||
* 具体参数 {@link SaLoginModel } 属性
|
||||
* 已经写的挺清楚的了
|
||||
*/
|
||||
SaLoginModel loginModel = new SaLoginModel();
|
||||
// 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
|
||||
loginModel.setDevice(String.valueOf(loginDeviceEnum.getDesc()));
|
||||
|
||||
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;
|
||||
// 登录
|
||||
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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成登录信息: 含设备信息
|
||||
*
|
||||
* @param userId
|
||||
* @param device
|
||||
* @return
|
||||
* 退出登录 注销
|
||||
*/
|
||||
private String generateTokenRedisKey(Long userId, Integer userType, Integer device) {
|
||||
String userKey = userType + "_" + userId + "_" + device;
|
||||
return redisService.generateRedisKey(RedisKeyConst.Support.TOKEN, userKey);
|
||||
public void removeToken() {
|
||||
StpUtil.logout();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 强制移除 此用户各端的登录信息
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public void removeToken(String token) {
|
||||
Map<String, Object> 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(Long userId, UserTypeEnum userType) {
|
||||
StpUtil.logout(generateLoginId(userId, userType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析并校验token信息 获取 userId
|
||||
*
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public Long getUserIdAndValidateToken(String token) {
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> 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()));
|
||||
}
|
||||
public void removeToken(List<Long> userIdList, UserTypeEnum userType) {
|
||||
userIdList.forEach(id -> StpUtil.logout(generateLoginId(id, userType)));
|
||||
}
|
||||
}
|
@ -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: Zhuoda1024lab
|
||||
password: 123456
|
||||
initial-size: 2
|
||||
min-idle: 2
|
||||
max-active: 10
|
||||
@ -27,17 +27,17 @@ spring:
|
||||
|
||||
# redis 连接池配置信息
|
||||
redis:
|
||||
database: 1
|
||||
database: 12
|
||||
host: 127.0.0.1
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 5
|
||||
max-active: 50
|
||||
min-idle: 1
|
||||
max-idle: 3
|
||||
max-wait: 30000ms
|
||||
port: 6379
|
||||
timeout: 10000ms
|
||||
password:
|
||||
timeout: 10s
|
||||
password: 123456
|
||||
|
||||
# 上传文件大小配置
|
||||
servlet:
|
||||
@ -109,11 +109,6 @@ http:
|
||||
write-timeout: 50000
|
||||
keep-alive: 300000
|
||||
|
||||
# token相关配置
|
||||
token:
|
||||
key: sa-jwt-key
|
||||
expire-day: 7
|
||||
|
||||
# 跨域配置
|
||||
access-control-allow-origin: '*'
|
||||
|
||||
@ -124,3 +119,32 @@ 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
|
Loading…
Reference in New Issue
Block a user