From 21a54cf05a74adea1ab337683ffd8b48000aa2d2 Mon Sep 17 00:00:00 2001 From: psh Date: Fri, 8 Dec 2023 13:29:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E6=8C=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/config/application.yml | 2 +- .../java/org/nl/config/ConfigurerAdapter.java | 63 ++++++++++ .../org/nl/config/saconfig/CorsFilter.java | 112 +++++++++--------- .../secutiry/AuthorizationController.java | 6 +- .../MobileAuthorizationController.java | 92 ++++++++++++++ .../system/service/dept/ISysDeptService.java | 2 + .../dept/dao/mapper/SysDeptMapper.java | 2 + .../service/dept/dao/mapper/SysDeptMapper.xml | 19 ++- .../service/dept/impl/SysDeptServiceImpl.java | 5 + .../secutiry/impl/OnlineUserService.java | 66 +++++++---- .../wms/sch/task_manage/task/TaskFactory.java | 2 + 11 files changed, 285 insertions(+), 86 deletions(-) create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/ConfigurerAdapter.java create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/MobileAuthorizationController.java diff --git a/acs/nladmin-system/nlsso-server/src/main/resources/config/application.yml b/acs/nladmin-system/nlsso-server/src/main/resources/config/application.yml index ac11b14..2d1a89c 100644 --- a/acs/nladmin-system/nlsso-server/src/main/resources/config/application.yml +++ b/acs/nladmin-system/nlsso-server/src/main/resources/config/application.yml @@ -2,7 +2,7 @@ spring: freemarker: check-template-location: false profiles: - active: dev + active: prod jackson: time-zone: GMT+8 data: diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/ConfigurerAdapter.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/ConfigurerAdapter.java new file mode 100644 index 0000000..7bb4cb3 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/ConfigurerAdapter.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.nl.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * WebMvcConfigurer + * + * @author Zheng Jie + * @date 2018-11-30 + */ +@Configuration +@EnableWebMvc +public class ConfigurerAdapter implements WebMvcConfigurer { + /** 文件配置 */ + private final FileProperties properties; + + public ConfigurerAdapter(FileProperties properties) { + this.properties = properties; + } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + FileProperties.ElPath path = properties.getPath(); + String avatarUtl = "file:" + path.getAvatar().replace("\\","/"); + String pathUtl = "file:" + path.getPath().replace("\\","/"); + registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0); + registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0); + registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0); + } +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/saconfig/CorsFilter.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/saconfig/CorsFilter.java index cc2e734..9a67267 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/saconfig/CorsFilter.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/saconfig/CorsFilter.java @@ -1,56 +1,56 @@ -package org.nl.config.saconfig; - -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.web.cors.CorsConfiguration; - -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 跨域过滤器 - * @author kong - */ -@Component -@Order(-200) -public class CorsFilter implements Filter { - - static final String OPTIONS = "OPTIONS"; - - @Override - public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) - throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - // 允许指定域访问跨域资源 - response.setHeader("Access-Control-Allow-Origin", "*"); - // 允许所有请求方式 - response.setHeader("Access-Control-Allow-Methods", "*"); - // 有效时间 - response.setHeader("Access-Control-Max-Age", "3600"); - // 允许的header参数 - response.setHeader("Access-Control-Allow-Headers", "*"); - response.setHeader("Access-Control-Allow-Credentials", "true"); - - // 如果是预检请求,直接返回 - if (OPTIONS.equals(request.getMethod())) { - System.out.println("=======================浏览器发来了OPTIONS预检请求=========="); - response.getWriter().print(""); - return; - } - - // System.out.println("*********************************过滤器被使用**************************"); - chain.doFilter(req, res); - } - - @Override - public void init(FilterConfig filterConfig) { - } - - @Override - public void destroy() { - } - -} +//package org.nl.config.saconfig; +// +//import org.springframework.core.annotation.Order; +//import org.springframework.stereotype.Component; +//import org.springframework.web.cors.CorsConfiguration; +// +//import javax.servlet.*; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.io.IOException; +// +///** +// * 跨域过滤器 +// * @author kong +// */ +//@Component +//@Order(-200) +//public class CorsFilter implements Filter { +// +// static final String OPTIONS = "OPTIONS"; +// +// @Override +// public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) +// throws IOException, ServletException { +// HttpServletRequest request = (HttpServletRequest) req; +// HttpServletResponse response = (HttpServletResponse) res; +// // 允许指定域访问跨域资源 +// response.setHeader("Access-Control-Allow-Origin", "*"); +// // 允许所有请求方式 +// response.setHeader("Access-Control-Allow-Methods", "*"); +// // 有效时间 +// response.setHeader("Access-Control-Max-Age", "3600"); +// // 允许的header参数 +// response.setHeader("Access-Control-Allow-Headers", "*"); +// response.setHeader("Access-Control-Allow-Credentials", "true"); +// +// // 如果是预检请求,直接返回 +// if (OPTIONS.equals(request.getMethod())) { +// System.out.println("=======================浏览器发来了OPTIONS预检请求=========="); +// response.getWriter().print(""); +// return; +// } +// +// // System.out.println("*********************************过滤器被使用**************************"); +// chain.doFilter(req, res); +// } +// +// @Override +// public void init(FilterConfig filterConfig) { +// } +// +// @Override +// public void destroy() { +// } +// +//} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/AuthorizationController.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/AuthorizationController.java index 321bfa3..5314d97 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/AuthorizationController.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/AuthorizationController.java @@ -49,11 +49,11 @@ public class AuthorizationController { @ApiOperation("登录授权") @PostMapping(value = "/login") - public ResponseEntity login(@RequestBody Map authMap) throws Exception { + public ResponseEntity login(@RequestBody Map authMap, HttpServletRequest request) throws Exception { if (ObjectUtil.isEmpty(authMap)){ - return ResponseEntity.noContent().build(); + return ResponseEntity.noContent().build(); } - return ResponseEntity.ok(onlineUserService.login(authMap)); + return ResponseEntity.ok(onlineUserService.login(authMap, request)); } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/MobileAuthorizationController.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/MobileAuthorizationController.java new file mode 100644 index 0000000..2cc9952 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/controller/secutiry/MobileAuthorizationController.java @@ -0,0 +1,92 @@ +package org.nl.system.controller.secutiry; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.dev33.satoken.secure.SaSecureUtil; +import cn.dev33.satoken.stp.SaLoginModel; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nl.common.exception.BadRequestException; +import org.nl.common.utils.RsaUtils; +import org.nl.common.utils.dto.CurrentUser; +import org.nl.config.RsaProperties; +import org.nl.system.service.role.ISysRoleService; +import org.nl.system.service.secutiry.dto.AuthUserDto; +import org.nl.system.service.user.ISysUserService; +import org.nl.system.service.user.dao.SysUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * @Author: lyd + * @Description: 手持登录鉴权 + * @Date: 2023/7/31 + */ +@Slf4j +@RestController +@RequestMapping("/mobile/auth") +@Api(tags = "手持:系统授权接口") +public class MobileAuthorizationController { + @Autowired + private ISysUserService userService; + @Autowired + private ISysRoleService roleService; + @ApiOperation("登录授权") + @PostMapping(value = "/login") + @SaIgnore + public ResponseEntity login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { + // 密码解密 - 前端的加密规则: encrypt(根据实际更改) + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword()); + // 校验数据库 + // 根据用户名查询,在比对密码 + SysUser userInfo = userService.getOne(new LambdaQueryWrapper() + .eq(SysUser::getUsername, authUser.getUsername())); // 拿到多个已经抛出异常 + if (ObjectUtil.isEmpty(userInfo) || !userInfo.getPassword().equals(SaSecureUtil.md5BySalt(password, "salt"))) { // 这里需要密码加密 + throw new BadRequestException("账号或密码错误!"); + } + // 获取权限列表 - 登录查找权限 + List permissionList = roleService.getPermissionList((JSONObject) JSON.toJSON(userInfo)); + + if (!userInfo.getIs_used()) { + throw new BadRequestException("账号未激活"); + } + + // 登录输入,登出删除 + CurrentUser user = new CurrentUser(); + user.setId(userInfo.getUser_id()); + user.setUsername(userInfo.getUsername()); + user.setPresonName(userInfo.getPerson_name()); + user.setUser(userInfo); + user.setPermissions(permissionList); + + // SaLoginModel 配置登录相关参数 + StpUtil.login(userInfo.getUser_id(), new SaLoginModel() + .setDevice("PE") // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型 + .setExtra("loginInfo", user) // Token挂载的扩展参数 (此方法只有在集成jwt插件时才会生效) + ); + + // 返回 token 与 用户信息 + JSONObject jsonObject = new JSONObject(); +// jsonObject.put("roles", permissionList); + jsonObject.put("user", userInfo); + JSONObject authInfo = new JSONObject(2) {{ + put("token", "Bearer " + StpUtil.getTokenValue()); + put("user", jsonObject); + }}; + + return ResponseEntity.ok(authInfo); + } +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/ISysDeptService.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/ISysDeptService.java index 3e2df59..8d159d8 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/ISysDeptService.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/ISysDeptService.java @@ -65,4 +65,6 @@ public interface ISysDeptService extends IService { void createDept(SysDept dept); + List getUserDeptByUserId(String userId); + } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.java index 97d0e9b..33ce82b 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.java @@ -41,4 +41,6 @@ public interface SysDeptMapper extends BaseMapper { * @return */ String findAllChild(String pid); + + List getUserDeptByUserId(String userId); } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.xml b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.xml index b5ec9e8..37eb4c5 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.xml +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/dao/mapper/SysDeptMapper.xml @@ -5,7 +5,7 @@ replace into sys_user_dept values - (#{user},#{dept}) + (#{user},#{dept}) @@ -14,7 +14,7 @@ update sys_dept set sub_count = - (select m.count from (select count(*) count from sys_dept where pid = #{pid}) as m) + (select m.count from (select count(*) count from sys_dept where pid = #{pid}) as m) where dept_id = #{pid} + diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java index 93ea266..dbe47eb 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java @@ -176,4 +176,9 @@ public class SysDeptServiceImpl extends ServiceImpl impl sysDeptMapper.updateSubCount(dept.getPid()); } } + + @Override + public List getUserDeptByUserId(String userId) { + return sysDeptMapper.getUserDeptByUserId(userId); + } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java index b63ef55..ec0188a 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java @@ -18,9 +18,11 @@ package org.nl.system.service.secutiry.impl; import cn.dev33.satoken.secure.SaSecureUtil; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -28,6 +30,8 @@ import org.nl.common.utils.*; import org.nl.config.RsaProperties; import org.nl.common.exception.BadRequestException; import org.nl.common.utils.dto.CurrentUser; +import org.nl.system.service.dept.ISysDeptService; +import org.nl.system.service.dept.dao.SysDept; import org.nl.system.service.secutiry.dto.UserDto; import org.nl.system.service.role.ISysRoleService; import org.nl.system.service.secutiry.dto.AuthUserDto; @@ -55,6 +59,8 @@ public class OnlineUserService { @Autowired private ISysUserService sysUserService; @Autowired + private ISysDeptService deptService; + @Autowired private ISysRoleService roleService; @Autowired private RedisUtils redisUtils; @@ -69,20 +75,27 @@ public class OnlineUserService { * @param token / * @param request / */ - public void save(UserDto userDto, String token, HttpServletRequest request){ -// String dept = userDto.getDept().getName(); - String dept = ""; + public void save(SysUser userDto, String token, HttpServletRequest request){ + // 获取用户部门 + List userDeptByUserId = deptService.getUserDeptByUserId(userDto.getUser_id()); + StringBuilder sb = new StringBuilder(); + for (SysDept dept : userDeptByUserId) { + sb.append(dept.getName()).append("、"); + } + if (sb.length() > 0) { + sb.setLength(sb.length() - 1); + } + String dept = sb.toString(); String ip = StringUtils.getIp(request); String browser = StringUtils.getBrowser(request); - // String address = StringUtils.getCityInfo(ip); - String address = "局域网"; + String address = StringUtils.getCityInfo(ip); OnlineUserDto onlineUserDto = null; try { -// onlineUserDto = new OnlineUserDto(userDto.getUsername(), userDto.getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); + onlineUserDto = new OnlineUserDto(userDto.getUsername(), userDto.getPerson_name(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); } catch (Exception e) { log.error(e.getMessage(),e); } - redisUtils.set(token, onlineUserDto, StpUtil.getTokenTimeout()); + redisUtils.set("oline-" + userDto.getUsername(), onlineUserDto, StpUtil.getTokenTimeout()); } /** @@ -105,21 +118,12 @@ public class OnlineUserService { * @return / */ public List getAll(String filter){ - List keys = redisUtils.scan("*"); + List keys = redisUtils.scan("oline-*"); Collections.reverse(keys); List onlineUserDtos = new ArrayList<>(); for (String key : keys) { - if (key.length() == 1511) { - OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key); - if(StrUtil.isNotEmpty(filter)){ - if(onlineUserDto.toString().contains(filter)){ - onlineUserDtos.add(onlineUserDto); - } - } else { - onlineUserDtos.add(onlineUserDto); - } - } - + OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key); + onlineUserDtos.add(onlineUserDto); } onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime())); return onlineUserDtos; @@ -127,10 +131,26 @@ public class OnlineUserService { /** * 踢出用户 - * @param key / + * @param key: OnlineUserDto / + */ + public void kickOut(OnlineUserDto key) { + // 获取用户 + SysUser one = sysUserService.getOne(new LambdaQueryWrapper().eq(SysUser::getUsername, key.getUserName())); + if (ObjectUtil.isNotEmpty(one)) { + redisUtils.del("oline-" + one.getUsername()); + } + // 下线 + StpUtil.logoutByTokenValue(key.getKey()); // 通过token强退 + } + + /** + * 踢出用户 + * @param key:token / */ - public void kickOut(String key){ + public void kickOut(String key) { redisUtils.del(key); + // 下线 + StpUtil.logoutByTokenValue(key); // 通过token强退 } /** @@ -211,7 +231,7 @@ public class OnlineUserService { } } @SneakyThrows - public Map login(Map paramMap){ + public Map login(Map paramMap, HttpServletRequest request){ // 密码解密 - 前端的加密规则: encrypt AuthUserDto authUser = JSON.toJavaObject((JSON) JSON.toJSON(paramMap), AuthUserDto.class); String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword()); @@ -263,7 +283,7 @@ public class OnlineUserService { put("user", user); }}; // 保存在线信息 -// onlineUserService.save(userDto, StpUtil.getTokenValue(), request); + this.save(userInfo, StpUtil.getTokenValue(), request); return authInfo; } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java index f1c6384..7e47ceb 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java @@ -3,6 +3,7 @@ package org.nl.wms.sch.task_manage.task; import org.nl.wms.sch.task_manage.AbstractTask; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -15,6 +16,7 @@ import java.util.Map; * @desc 采用获取注解来标识任务类型,并通过扫描和反射的方式来获取任务实例 */ @Component +@Lazy public class TaskFactory { private final Map taskMap;