refactor(system): 重构用户在线信息和用户缓存相关类名
This commit is contained in:
+5
-5
@@ -28,7 +28,7 @@ import cn.odboy.system.dal.model.SystemUserInfoVo;
|
|||||||
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
||||||
import cn.odboy.system.dal.model.SystemUserLoginArgs;
|
import cn.odboy.system.dal.model.SystemUserLoginArgs;
|
||||||
import cn.odboy.system.dal.redis.SystemCacheKey;
|
import cn.odboy.system.dal.redis.SystemCacheKey;
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import cn.odboy.system.framework.permission.core.CsSecurityHelper;
|
import cn.odboy.system.framework.permission.core.CsSecurityHelper;
|
||||||
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
||||||
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
|
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
|
||||||
@@ -66,7 +66,7 @@ public class SystemAuthController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CsRedisHelper redisHelper;
|
private CsRedisHelper redisHelper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserOnlineInfoRedis onlineUserService;
|
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
@Autowired
|
@Autowired
|
||||||
private TokenProvider tokenProvider;
|
private TokenProvider tokenProvider;
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -108,10 +108,10 @@ public class SystemAuthController {
|
|||||||
}};
|
}};
|
||||||
if (properties.getLogin().isSingle()) {
|
if (properties.getLogin().isSingle()) {
|
||||||
// 踢掉之前已经登录的token
|
// 踢掉之前已经登录的token
|
||||||
onlineUserService.kickOutByUsername(loginRequest.getUsername());
|
systemUserOnlineInfoDAO.kickOutByUsername(loginRequest.getUsername());
|
||||||
}
|
}
|
||||||
// 保存在线信息
|
// 保存在线信息
|
||||||
onlineUserService.saveUserJwtModelByToken(jwtUser, token, request);
|
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
|
||||||
// 返回登录信息
|
// 返回登录信息
|
||||||
return ResponseEntity.ok(authInfo);
|
return ResponseEntity.ok(authInfo);
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ public class SystemAuthController {
|
|||||||
@AnonymousPostMapping(value = "/logout")
|
@AnonymousPostMapping(value = "/logout")
|
||||||
public ResponseEntity<Void> logout(HttpServletRequest request) {
|
public ResponseEntity<Void> logout(HttpServletRequest request) {
|
||||||
String token = tokenProvider.getToken(request);
|
String token = tokenProvider.getToken(request);
|
||||||
onlineUserService.logoutByToken(token);
|
systemUserOnlineInfoDAO.logoutByToken(token);
|
||||||
return ResponseEntity.ok(null);
|
return ResponseEntity.ok(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -19,14 +19,13 @@ package cn.odboy.system.controller;
|
|||||||
import cn.odboy.base.CsPageArgs;
|
import cn.odboy.base.CsPageArgs;
|
||||||
import cn.odboy.base.CsPageResult;
|
import cn.odboy.base.CsPageResult;
|
||||||
import cn.odboy.system.dal.model.SystemUserOnlineVo;
|
import cn.odboy.system.dal.model.SystemUserOnlineVo;
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import cn.odboy.util.CsDesEncryptUtil;
|
import cn.odboy.util.CsDesEncryptUtil;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -41,22 +40,21 @@ import java.util.Set;
|
|||||||
@Api(tags = "系统:在线用户管理")
|
@Api(tags = "系统:在线用户管理")
|
||||||
public class SystemOnlineController {
|
public class SystemOnlineController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserOnlineInfoRedis systemUserOnlineInfoRedis;
|
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
|
|
||||||
@ApiOperation("查询在线用户")
|
@ApiOperation("查询在线用户")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@PreAuthorize("@el.check()")
|
@PreAuthorize("@el.check()")
|
||||||
public ResponseEntity<CsPageResult<SystemUserOnlineVo>> queryOnlineUser(@Validated @RequestBody CsPageArgs<SystemUserOnlineVo> args) {
|
public ResponseEntity<CsPageResult<SystemUserOnlineVo>> queryOnlineUser(@Validated @RequestBody CsPageArgs<SystemUserOnlineVo> args) {
|
||||||
IPage<SystemUserOnlineVo> page = new Page<>(args.getPage(), args.getSize());
|
IPage<SystemUserOnlineVo> page = new Page<>(args.getPage(), args.getSize());
|
||||||
return ResponseEntity.ok(systemUserOnlineInfoRedis.queryUserOnlineModelPage(args.getArgs(), page));
|
return ResponseEntity.ok(systemUserOnlineInfoDAO.queryUserOnlineModelPage(args.getArgs(), page));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("导出数据")
|
@ApiOperation("导出数据")
|
||||||
@GetMapping(value = "/download")
|
@GetMapping(value = "/download")
|
||||||
@PreAuthorize("@el.check()")
|
@PreAuthorize("@el.check()")
|
||||||
public void exportOnlineUser(HttpServletResponse response, String username) throws IOException {
|
public void exportOnlineUser(HttpServletResponse response, String username) throws IOException {
|
||||||
systemUserOnlineInfoRedis.downloadUserOnlineModelExcel(systemUserOnlineInfoRedis.queryUserOnlineModelListByUsername(
|
systemUserOnlineInfoDAO.downloadUserOnlineModelExcel(systemUserOnlineInfoDAO.queryUserOnlineModelListByUsername(username), response);
|
||||||
username), response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("踢出用户")
|
@ApiOperation("踢出用户")
|
||||||
@@ -66,7 +64,7 @@ public class SystemOnlineController {
|
|||||||
for (String token : keys) {
|
for (String token : keys) {
|
||||||
// 解密Key
|
// 解密Key
|
||||||
token = CsDesEncryptUtil.desDecrypt(token);
|
token = CsDesEncryptUtil.desDecrypt(token);
|
||||||
systemUserOnlineInfoRedis.logoutByToken(token);
|
systemUserOnlineInfoDAO.logoutByToken(token);
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(null);
|
return ResponseEntity.ok(null);
|
||||||
}
|
}
|
||||||
|
|||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2025 Odboy
|
|
||||||
*
|
|
||||||
* 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 cn.odboy.system.dal.redis;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.RandomUtil;
|
|
||||||
import cn.odboy.framework.redis.CsRedisHelper;
|
|
||||||
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
|
||||||
import cn.odboy.util.CsStringUtil;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户缓存管理
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SystemUserInfoRedis {
|
|
||||||
@Autowired
|
|
||||||
private CsRedisHelper redisHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加缓存到Redis
|
|
||||||
*
|
|
||||||
* @param userName 用户名
|
|
||||||
*/
|
|
||||||
@Async
|
|
||||||
public void saveUserLoginInfoByUserName(String userName, SystemUserJwtVo user) {
|
|
||||||
if (CsStringUtil.isNotEmpty(userName)) {
|
|
||||||
// 添加数据, 避免数据同时过期(2小时左右)
|
|
||||||
long time = 7200 + RandomUtil.randomInt(900, 1800);
|
|
||||||
redisHelper.set(SystemCacheKey.USER_INFO + userName, user, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理用户缓存信息 用户信息变更时
|
|
||||||
*
|
|
||||||
* @param userName 用户名
|
|
||||||
*/
|
|
||||||
@Async
|
|
||||||
public void deleteUserLoginInfoByUserName(String userName) {
|
|
||||||
if (CsStringUtil.isNotEmpty(userName)) {
|
|
||||||
// 清除数据
|
|
||||||
redisHelper.del(SystemCacheKey.USER_INFO + userName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回用户缓存
|
|
||||||
*
|
|
||||||
* @param username 用户名
|
|
||||||
* @return UserJwtVo
|
|
||||||
*/
|
|
||||||
|
|
||||||
public SystemUserJwtVo getUserLoginInfoByUserName(String username) {
|
|
||||||
if (CsStringUtil.isNotEmpty(username)) {
|
|
||||||
// 获取数据
|
|
||||||
return redisHelper.get(SystemCacheKey.USER_INFO + username, SystemUserJwtVo.class);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-173
@@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2025 Odboy
|
|
||||||
*
|
|
||||||
* 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 cn.odboy.system.dal.redis;
|
|
||||||
|
|
||||||
import cn.odboy.base.CsPageResult;
|
|
||||||
import cn.odboy.framework.properties.AppProperties;
|
|
||||||
import cn.odboy.framework.redis.CsRedisHelper;
|
|
||||||
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
|
||||||
import cn.odboy.system.dal.model.SystemUserOnlineVo;
|
|
||||||
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
|
||||||
import cn.odboy.util.*;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class SystemUserOnlineInfoRedis {
|
|
||||||
private final AppProperties properties;
|
|
||||||
private final TokenProvider tokenProvider;
|
|
||||||
private final CsRedisHelper redisHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存在线用户信息
|
|
||||||
*
|
|
||||||
* @param userJwtVo /
|
|
||||||
* @param token /
|
|
||||||
* @param request /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void saveUserJwtModelByToken(SystemUserJwtVo userJwtVo, String token, HttpServletRequest request) {
|
|
||||||
String dept = userJwtVo.getUser().getDept().getName();
|
|
||||||
String ip = CsBrowserUtil.getIp(request);
|
|
||||||
String id = tokenProvider.getId(token);
|
|
||||||
String version = CsBrowserUtil.getVersion(request);
|
|
||||||
String address = CsIPUtil.getCityInfo(ip);
|
|
||||||
SystemUserOnlineVo userOnlineVo = null;
|
|
||||||
try {
|
|
||||||
userOnlineVo = new SystemUserOnlineVo();
|
|
||||||
userOnlineVo.setUid(id);
|
|
||||||
userOnlineVo.setUserName(userJwtVo.getUsername());
|
|
||||||
userOnlineVo.setNickName(userJwtVo.getUser().getNickName());
|
|
||||||
userOnlineVo.setDept(dept);
|
|
||||||
userOnlineVo.setBrowser(version);
|
|
||||||
userOnlineVo.setIp(ip);
|
|
||||||
userOnlineVo.setAddress(address);
|
|
||||||
userOnlineVo.setKey(CsDesEncryptUtil.desEncrypt(token));
|
|
||||||
userOnlineVo.setLoginTime(new Date());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
String loginKey = tokenProvider.loginKey(token);
|
|
||||||
redisHelper.set(loginKey, userOnlineVo, properties.getJwt().getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 退出登录
|
|
||||||
*
|
|
||||||
* @param token /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void logoutByToken(String token) {
|
|
||||||
String loginKey = tokenProvider.loginKey(token);
|
|
||||||
redisHelper.del(loginKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出
|
|
||||||
*
|
|
||||||
* @param all /
|
|
||||||
* @param response /
|
|
||||||
* @throws IOException /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void downloadUserOnlineModelExcel(List<SystemUserOnlineVo> all, HttpServletResponse response)
|
|
||||||
throws IOException {
|
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
|
||||||
for (SystemUserOnlineVo user : all) {
|
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
|
||||||
map.put("用户名", user.getUserName());
|
|
||||||
map.put("部门", user.getDept());
|
|
||||||
map.put("登录IP", user.getIp());
|
|
||||||
map.put("登录地点", user.getAddress());
|
|
||||||
map.put("浏览器", user.getBrowser());
|
|
||||||
map.put("登录日期", user.getLoginTime());
|
|
||||||
list.add(map);
|
|
||||||
}
|
|
||||||
CsFileUtil.downloadExcel(list, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据用户名强退用户
|
|
||||||
*
|
|
||||||
* @param username /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void kickOutByUsername(String username) {
|
|
||||||
String loginKey = SystemCacheKey.ONLINE_USER + username + "*";
|
|
||||||
redisHelper.scanDel(loginKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询全部数据
|
|
||||||
*
|
|
||||||
* @param onlineVo /
|
|
||||||
* @param pageable /
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CsPageResult<SystemUserOnlineVo> queryUserOnlineModelPage(
|
|
||||||
SystemUserOnlineVo onlineVo,
|
|
||||||
IPage<SystemUserOnlineVo> pageable) {
|
|
||||||
String username = null;
|
|
||||||
if (onlineVo != null) {
|
|
||||||
username = onlineVo.getUserName();
|
|
||||||
}
|
|
||||||
List<SystemUserOnlineVo> onlineUserList = queryUserOnlineModelListByUsername(username);
|
|
||||||
List<SystemUserOnlineVo> paging = CsPageUtil.softPaging(pageable.getCurrent(), pageable.getSize(), onlineUserList);
|
|
||||||
return CsPageUtil.toPage(paging, onlineUserList.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询全部数据,不分页
|
|
||||||
*
|
|
||||||
* @param username /
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public List<SystemUserOnlineVo> queryUserOnlineModelListByUsername(String username) {
|
|
||||||
String loginKey = SystemCacheKey.ONLINE_USER + (CsStringUtil.isBlank(username) ? "" : "*" + username);
|
|
||||||
List<String> keys = redisHelper.scan(loginKey + "*");
|
|
||||||
Collections.reverse(keys);
|
|
||||||
List<SystemUserOnlineVo> onlineUserList = new ArrayList<>();
|
|
||||||
for (String key : keys) {
|
|
||||||
onlineUserList.add(redisHelper.get(key, SystemUserOnlineVo.class));
|
|
||||||
}
|
|
||||||
onlineUserList.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
|
|
||||||
return onlineUserList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询用户
|
|
||||||
*
|
|
||||||
* @param key /
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
|
|
||||||
public SystemUserOnlineVo queryUserOnlineModelByKey(String key) {
|
|
||||||
return redisHelper.get(key, SystemUserOnlineVo.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+19
-54
@@ -17,7 +17,7 @@
|
|||||||
package cn.odboy.system.framework.permission.config;
|
package cn.odboy.system.framework.permission.config;
|
||||||
|
|
||||||
import cn.odboy.constant.RequestMethodEnum;
|
import cn.odboy.constant.RequestMethodEnum;
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import cn.odboy.system.framework.permission.core.handler.JwtAccessDeniedHandler;
|
import cn.odboy.system.framework.permission.core.handler.JwtAccessDeniedHandler;
|
||||||
import cn.odboy.system.framework.permission.core.handler.JwtAuthenticationEntryPoint;
|
import cn.odboy.system.framework.permission.core.handler.JwtAuthenticationEntryPoint;
|
||||||
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
||||||
@@ -53,7 +53,7 @@ public class SpringSecurityConfig {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserOnlineInfoRedis systemUserOnlineInfoRedis;
|
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
||||||
@@ -73,76 +73,41 @@ public class SpringSecurityConfig {
|
|||||||
Map<String, Set<String>> anonymousUrls = CsAnonTagUtil.getAnonymousUrl(applicationContext);
|
Map<String, Set<String>> anonymousUrls = CsAnonTagUtil.getAnonymousUrl(applicationContext);
|
||||||
return httpSecurity
|
return httpSecurity
|
||||||
// 禁用 CSRF
|
// 禁用 CSRF
|
||||||
.csrf()
|
.csrf().disable().addFilter(corsFilter)
|
||||||
.disable()
|
|
||||||
.addFilter(corsFilter)
|
|
||||||
// 授权异常
|
// 授权异常
|
||||||
.exceptionHandling()
|
.exceptionHandling().authenticationEntryPoint(authenticationErrorHandler).accessDeniedHandler(jwtAccessDeniedHandler)
|
||||||
.authenticationEntryPoint(authenticationErrorHandler)
|
|
||||||
.accessDeniedHandler(jwtAccessDeniedHandler)
|
|
||||||
// 防止iframe 造成跨域
|
// 防止iframe 造成跨域
|
||||||
.and()
|
.and().headers().frameOptions().disable()
|
||||||
.headers()
|
|
||||||
.frameOptions()
|
|
||||||
.disable()
|
|
||||||
// 不创建会话
|
// 不创建会话
|
||||||
.and()
|
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
|
||||||
.sessionManagement()
|
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
||||||
.and()
|
|
||||||
.authorizeRequests()
|
|
||||||
// 静态资源等等
|
// 静态资源等等
|
||||||
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/websocket/**")
|
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/websocket/**").permitAll()
|
||||||
.permitAll()
|
|
||||||
// swagger 文档
|
// swagger 文档
|
||||||
.antMatchers("/swagger-ui.html")
|
.antMatchers("/swagger-ui.html").permitAll().antMatchers("/swagger-resources/**").permitAll().antMatchers("/webjars/**").permitAll().antMatchers("/*/api-docs").permitAll()
|
||||||
.permitAll()
|
|
||||||
.antMatchers("/swagger-resources/**")
|
|
||||||
.permitAll()
|
|
||||||
.antMatchers("/webjars/**")
|
|
||||||
.permitAll()
|
|
||||||
.antMatchers("/*/api-docs")
|
|
||||||
.permitAll()
|
|
||||||
// 文件
|
// 文件
|
||||||
.antMatchers("/avatar/**")
|
.antMatchers("/avatar/**").permitAll().antMatchers("/file/**").permitAll()
|
||||||
.permitAll()
|
|
||||||
.antMatchers("/file/**")
|
|
||||||
.permitAll()
|
|
||||||
// 阿里巴巴 druid
|
// 阿里巴巴 druid
|
||||||
.antMatchers("/druid/**")
|
.antMatchers("/druid/**").permitAll()
|
||||||
.permitAll()
|
|
||||||
// 放行OPTIONS请求
|
// 放行OPTIONS请求
|
||||||
.antMatchers(HttpMethod.OPTIONS, "/**")
|
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||||
.permitAll()
|
|
||||||
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
|
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
|
||||||
// GET
|
// GET
|
||||||
.antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0]))
|
.antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// POST
|
// POST
|
||||||
.antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0]))
|
.antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// PUT
|
// PUT
|
||||||
.antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0]))
|
.antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// PATCH
|
// PATCH
|
||||||
.antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0]))
|
.antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// DELETE
|
// DELETE
|
||||||
.antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0]))
|
.antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// 所有类型的接口都放行
|
// 所有类型的接口都放行
|
||||||
.antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0]))
|
.antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
|
||||||
.permitAll()
|
|
||||||
// 所有请求都需要认证
|
// 所有请求都需要认证
|
||||||
.anyRequest()
|
.anyRequest().authenticated().and().apply(securityConfigurerAdapter()).and().build();
|
||||||
.authenticated()
|
|
||||||
.and()
|
|
||||||
.apply(securityConfigurerAdapter())
|
|
||||||
.and()
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TokenConfigurer securityConfigurerAdapter() {
|
private TokenConfigurer securityConfigurerAdapter() {
|
||||||
return new TokenConfigurer(tokenProvider, systemUserOnlineInfoRedis);
|
return new TokenConfigurer(tokenProvider, systemUserOnlineInfoDAO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package cn.odboy.system.framework.permission.config;
|
package cn.odboy.system.framework.permission.config;
|
||||||
|
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import cn.odboy.system.framework.permission.core.handler.TokenFilter;
|
import cn.odboy.system.framework.permission.core.handler.TokenFilter;
|
||||||
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
|
||||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||||
@@ -26,16 +26,16 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
|||||||
|
|
||||||
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||||
private final TokenProvider tokenProvider;
|
private final TokenProvider tokenProvider;
|
||||||
private final SystemUserOnlineInfoRedis systemUserOnlineInfoRedis;
|
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
|
|
||||||
public TokenConfigurer(TokenProvider tokenProvider, SystemUserOnlineInfoRedis systemUserOnlineInfoRedis) {
|
public TokenConfigurer(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||||
this.tokenProvider = tokenProvider;
|
this.tokenProvider = tokenProvider;
|
||||||
this.systemUserOnlineInfoRedis = systemUserOnlineInfoRedis;
|
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(HttpSecurity http) {
|
public void configure(HttpSecurity http) {
|
||||||
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoRedis);
|
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
|
||||||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -19,7 +19,7 @@ package cn.odboy.system.framework.permission.core.handler;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.odboy.constant.SystemConst;
|
import cn.odboy.constant.SystemConst;
|
||||||
import cn.odboy.system.dal.model.SystemUserOnlineVo;
|
import cn.odboy.system.dal.model.SystemUserOnlineVo;
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@@ -36,14 +36,14 @@ import java.io.IOException;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class TokenFilter extends GenericFilterBean {
|
public class TokenFilter extends GenericFilterBean {
|
||||||
private final TokenProvider tokenProvider;
|
private final TokenProvider tokenProvider;
|
||||||
private final SystemUserOnlineInfoRedis systemUserOnlineInfoRedis;
|
private final SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenProvider Token
|
* @param tokenProvider Token
|
||||||
* @param systemUserOnlineInfoRedis 用户在线
|
* @param systemUserOnlineInfoDAO 用户在线
|
||||||
*/
|
*/
|
||||||
public TokenFilter(TokenProvider tokenProvider, SystemUserOnlineInfoRedis systemUserOnlineInfoRedis) {
|
public TokenFilter(TokenProvider tokenProvider, SystemUserOnlineInfoDAO systemUserOnlineInfoDAO) {
|
||||||
this.systemUserOnlineInfoRedis = systemUserOnlineInfoRedis;
|
this.systemUserOnlineInfoDAO = systemUserOnlineInfoDAO;
|
||||||
this.tokenProvider = tokenProvider;
|
this.tokenProvider = tokenProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ public class TokenFilter extends GenericFilterBean {
|
|||||||
if (StrUtil.isNotBlank(token)) {
|
if (StrUtil.isNotBlank(token)) {
|
||||||
// 获取用户Token的Key
|
// 获取用户Token的Key
|
||||||
String loginKey = tokenProvider.loginKey(token);
|
String loginKey = tokenProvider.loginKey(token);
|
||||||
SystemUserOnlineVo userOnlineVo = systemUserOnlineInfoRedis.queryUserOnlineModelByKey(loginKey);
|
SystemUserOnlineVo userOnlineVo = systemUserOnlineInfoDAO.queryUserOnlineModelByKey(loginKey);
|
||||||
// 判断用户在线信息是否为空
|
// 判断用户在线信息是否为空
|
||||||
if (userOnlineVo != null) {
|
if (userOnlineVo != null) {
|
||||||
// Token 续期判断
|
// Token 续期判断
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,7 @@ import cn.odboy.framework.exception.BadRequestException;
|
|||||||
import cn.odboy.system.dal.dataobject.SystemUserTb;
|
import cn.odboy.system.dal.dataobject.SystemUserTb;
|
||||||
import cn.odboy.system.dal.model.SystemRoleCodeVo;
|
import cn.odboy.system.dal.model.SystemRoleCodeVo;
|
||||||
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
import cn.odboy.system.dal.model.SystemUserJwtVo;
|
||||||
import cn.odboy.system.dal.redis.SystemUserInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserInfoDAO;
|
||||||
import cn.odboy.system.service.SystemDataService;
|
import cn.odboy.system.service.SystemDataService;
|
||||||
import cn.odboy.system.service.SystemRoleService;
|
import cn.odboy.system.service.SystemRoleService;
|
||||||
import cn.odboy.system.service.SystemUserService;
|
import cn.odboy.system.service.SystemUserService;
|
||||||
@@ -44,11 +44,11 @@ public class UserDetailsHandler implements UserDetailsService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemDataService systemDataService;
|
private SystemDataService systemDataService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserInfoRedis systemUserInfoRedis;
|
private SystemUserInfoDAO systemUserInfoDAO;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemUserJwtVo loadUserByUsername(String username) {
|
public SystemUserJwtVo loadUserByUsername(String username) {
|
||||||
SystemUserJwtVo userJwtVo = systemUserInfoRedis.getUserLoginInfoByUserName(username);
|
SystemUserJwtVo userJwtVo = systemUserInfoDAO.getUserLoginInfoByUserName(username);
|
||||||
if (userJwtVo == null) {
|
if (userJwtVo == null) {
|
||||||
SystemUserTb user = systemUserService.getUserByUsername(username);
|
SystemUserTb user = systemUserService.getUserByUsername(username);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@@ -62,7 +62,7 @@ public class UserDetailsHandler implements UserDetailsService {
|
|||||||
// 初始化JwtUserDto
|
// 初始化JwtUserDto
|
||||||
userJwtVo = new SystemUserJwtVo(user, systemDataService.queryDeptIdListByArgs(user), authorities);
|
userJwtVo = new SystemUserJwtVo(user, systemDataService.queryDeptIdListByArgs(user), authorities);
|
||||||
// 添加缓存数据
|
// 添加缓存数据
|
||||||
systemUserInfoRedis.saveUserLoginInfoByUserName(username, userJwtVo);
|
systemUserInfoDAO.saveUserLoginInfoByUserName(username, userJwtVo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return userJwtVo;
|
return userJwtVo;
|
||||||
|
|||||||
+13
-13
@@ -27,8 +27,8 @@ import cn.odboy.system.dal.model.SystemQueryUserArgs;
|
|||||||
import cn.odboy.system.dal.mysql.SystemUserJobMapper;
|
import cn.odboy.system.dal.mysql.SystemUserJobMapper;
|
||||||
import cn.odboy.system.dal.mysql.SystemUserMapper;
|
import cn.odboy.system.dal.mysql.SystemUserMapper;
|
||||||
import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
|
import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
|
||||||
import cn.odboy.system.dal.redis.SystemUserInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserInfoDAO;
|
||||||
import cn.odboy.system.dal.redis.SystemUserOnlineInfoRedis;
|
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
|
||||||
import cn.odboy.system.framework.permission.core.CsSecurityHelper;
|
import cn.odboy.system.framework.permission.core.CsSecurityHelper;
|
||||||
import cn.odboy.util.CsFileUtil;
|
import cn.odboy.util.CsFileUtil;
|
||||||
import cn.odboy.util.CsPageUtil;
|
import cn.odboy.util.CsPageUtil;
|
||||||
@@ -56,9 +56,9 @@ public class SystemUserService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserRoleMapper systemUserRoleMapper;
|
private SystemUserRoleMapper systemUserRoleMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserInfoRedis systemUserInfoRedis;
|
private SystemUserInfoDAO systemUserInfoDAO;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemUserOnlineInfoRedis systemUserOnlineInfoRedis;
|
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
|
||||||
@Autowired
|
@Autowired
|
||||||
private CsFileLocalUploadHelper fileUploadPathHelper;
|
private CsFileLocalUploadHelper fileUploadPathHelper;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ public class SystemUserService {
|
|||||||
}
|
}
|
||||||
// 如果用户被禁用, 则清除用户登录信息
|
// 如果用户被禁用, 则清除用户登录信息
|
||||||
if (!args.getEnabled()) {
|
if (!args.getEnabled()) {
|
||||||
systemUserOnlineInfoRedis.kickOutByUsername(args.getUsername());
|
systemUserOnlineInfoDAO.kickOutByUsername(args.getUsername());
|
||||||
}
|
}
|
||||||
user.setDeptId(args.getDept().getId());
|
user.setDeptId(args.getDept().getId());
|
||||||
user.setUsername(args.getUsername());
|
user.setUsername(args.getUsername());
|
||||||
@@ -125,7 +125,7 @@ public class SystemUserService {
|
|||||||
user.setGender(args.getGender());
|
user.setGender(args.getGender());
|
||||||
systemUserMapper.insertOrUpdate(user);
|
systemUserMapper.insertOrUpdate(user);
|
||||||
// 清除用户登录缓存
|
// 清除用户登录缓存
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(user.getUsername());
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
|
||||||
// 更新用户岗位
|
// 更新用户岗位
|
||||||
systemUserJobMapper.batchDeleteUserJob(Collections.singleton(args.getId()));
|
systemUserJobMapper.batchDeleteUserJob(Collections.singleton(args.getId()));
|
||||||
systemUserJobMapper.batchInsertUserJob(args.getJobs(), args.getId());
|
systemUserJobMapper.batchInsertUserJob(args.getJobs(), args.getId());
|
||||||
@@ -151,7 +151,7 @@ public class SystemUserService {
|
|||||||
user.setPhone(args.getPhone());
|
user.setPhone(args.getPhone());
|
||||||
user.setGender(args.getGender());
|
user.setGender(args.getGender());
|
||||||
systemUserMapper.insertOrUpdate(user);
|
systemUserMapper.insertOrUpdate(user);
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(user.getUsername());
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,7 +165,7 @@ public class SystemUserService {
|
|||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
// 清理缓存
|
// 清理缓存
|
||||||
SystemUserTb user = systemUserMapper.selectById(id);
|
SystemUserTb user = systemUserMapper.selectById(id);
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(user.getUsername());
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
|
||||||
}
|
}
|
||||||
systemUserMapper.deleteByIds(ids);
|
systemUserMapper.deleteByIds(ids);
|
||||||
// 删除用户岗位
|
// 删除用户岗位
|
||||||
@@ -184,7 +184,7 @@ public class SystemUserService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void modifyUserPasswordByUsername(String username, String encryptPassword) {
|
public void modifyUserPasswordByUsername(String username, String encryptPassword) {
|
||||||
systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
|
systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(username);
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,9 +200,9 @@ public class SystemUserService {
|
|||||||
// 清除缓存
|
// 清除缓存
|
||||||
users.forEach(user -> {
|
users.forEach(user -> {
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(user.getUsername());
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
|
||||||
// 强制退出
|
// 强制退出
|
||||||
systemUserOnlineInfoRedis.kickOutByUsername(user.getUsername());
|
systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername());
|
||||||
});
|
});
|
||||||
// 重置密码
|
// 重置密码
|
||||||
systemUserMapper.batchUpdatePassword(password, ids);
|
systemUserMapper.batchUpdatePassword(password, ids);
|
||||||
@@ -238,7 +238,7 @@ public class SystemUserService {
|
|||||||
if (CsStringUtil.isNotBlank(oldPath)) {
|
if (CsStringUtil.isNotBlank(oldPath)) {
|
||||||
CsFileUtil.del(oldPath);
|
CsFileUtil.del(oldPath);
|
||||||
}
|
}
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(username);
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
|
||||||
return new HashMap<>(1) {{
|
return new HashMap<>(1) {{
|
||||||
put("avatar", file.getName());
|
put("avatar", file.getName());
|
||||||
}};
|
}};
|
||||||
@@ -254,7 +254,7 @@ public class SystemUserService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void modifyUserEmailByUsername(String username, String email) {
|
public void modifyUserEmailByUsername(String username, String email) {
|
||||||
systemUserMapper.updateUserEmailByUsername(username, email);
|
systemUserMapper.updateUserEmailByUsername(username, email);
|
||||||
systemUserInfoRedis.deleteUserLoginInfoByUserName(username);
|
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user