mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
完善用户登录
This commit is contained in:
@@ -3,5 +3,16 @@ package cn.lihongjie.coal.common;
|
||||
import java.util.*;
|
||||
|
||||
public class Constants {
|
||||
public static final String CACHE_RESOURCE = "resource";
|
||||
public static final String CACHE_USER_PERMISSIONS = "userPermissions";
|
||||
public static final String CACHE_USER_RESOURCES = "userResources";
|
||||
public static final String CACHE_RESOURCE_BY_URL = "resourceByUrl";
|
||||
public static final String CACHE_PERMISSION = "permission";
|
||||
public static final String CACHE_PERMISSION_BY_TYPE = "permissionByType";
|
||||
public static final String CACHE_SYSCONFIG = "sysconfig";
|
||||
public static final String CACHE_RESOURCE_API_TREE = "resourceApiTree";
|
||||
public static final String CACHE_RESOURCE_MENU_TREE = "resourceMenuTree";
|
||||
public static String SYSCONFIG_ENABLE_CAPTCHA = "enable_captcha";
|
||||
public static String SYSCONFIG_SESSION_TIMEOUT = "session_timeout";
|
||||
public static String SYSCONFIG_ACCOUNT_MAX_ONLINE = "account_max_online";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.lihongjie.coal.common;
|
||||
|
||||
import cn.lihongjie.coal.session.SessionService;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Ctx {
|
||||
return getAuthentication().getUser().getSysAdmin();
|
||||
}
|
||||
|
||||
public static UserEntity currentUser() {
|
||||
public static UserDto currentUser() {
|
||||
return getAuthentication().getUser();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,14 @@ package cn.lihongjie.coal.filter;
|
||||
import cn.lihongjie.coal.base.dto.R;
|
||||
import cn.lihongjie.coal.common.Ctx;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.permission.entity.PermissionEntity;
|
||||
import cn.lihongjie.coal.permission.dto.PermissionDto;
|
||||
import cn.lihongjie.coal.permission.service.PermissionService;
|
||||
import cn.lihongjie.coal.resource.dto.ResourceDto;
|
||||
import cn.lihongjie.coal.resource.entity.ResourceEntity;
|
||||
import cn.lihongjie.coal.resource.service.ResourceService;
|
||||
import cn.lihongjie.coal.role.service.RoleService;
|
||||
import cn.lihongjie.coal.session.SessionService;
|
||||
import cn.lihongjie.coal.spring.config.SystemConfig;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -92,6 +91,15 @@ public class AuthFilter extends OncePerRequestFilter {
|
||||
|
||||
@Autowired UserService userService;
|
||||
|
||||
private static void doFilter(
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<TransactionStatus> getTransactionStatusConsumer(
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
|
||||
|
||||
@@ -99,97 +107,80 @@ public class AuthFilter extends OncePerRequestFilter {
|
||||
MDC.remove("user");
|
||||
if (isMatches(request)) {
|
||||
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
doFilter(request, response, filterChain);
|
||||
return;
|
||||
}
|
||||
|
||||
String sessionId = request.getHeader("X-Token");
|
||||
|
||||
Optional<ResourceEntity> resource = resourceService.findUrl(getRequestURI(request));
|
||||
Optional<ResourceDto> resource =
|
||||
resourceService.findUrlFromCache(getRequestURI(request));
|
||||
|
||||
if (resource.isEmpty()) {
|
||||
writeResponse(new BizException("invalidUrl", "资源未找到"), response);
|
||||
return;
|
||||
}
|
||||
|
||||
request.setAttribute("__resourceEntity", resource.get());
|
||||
|
||||
// 未登录用户访问
|
||||
if (StringUtils.isEmpty(sessionId)) {
|
||||
// 找到匿名权限
|
||||
List<PermissionEntity> permissions = permissionService.getByType("0");
|
||||
List<PermissionDto> permissions = permissionService.getByTypeFromCache("0");
|
||||
|
||||
if (permissions.stream()
|
||||
.flatMap(
|
||||
x ->
|
||||
ObjectUtils.defaultIfNull(
|
||||
x.getResources(),
|
||||
new ArrayList<ResourceEntity>())
|
||||
.stream())
|
||||
.anyMatch(
|
||||
x -> StringUtils.equals(x.getId(), resource.get().getId()))
|
||||
|| BooleanUtils.isTrue(resource.get().getAnonymous())) {
|
||||
boolean isAnonymous =
|
||||
permissions.stream()
|
||||
.flatMap(
|
||||
x ->
|
||||
ObjectUtils.defaultIfNull(
|
||||
x.getResources(),
|
||||
new ArrayList<PermissionDto>())
|
||||
.stream())
|
||||
.anyMatch(
|
||||
x ->
|
||||
StringUtils.equals(
|
||||
x.getId(), resource.get().getId()))
|
||||
|| BooleanUtils.isTrue(resource.get().getAnonymous());
|
||||
if (isAnonymous) {
|
||||
|
||||
sessionService.anonymousSession();
|
||||
UserEntity user = Ctx.currentUser();
|
||||
UserDto user = Ctx.currentUser();
|
||||
MDC.put("user", user.getUsername());
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
doFilter(request, response, filterChain);
|
||||
|
||||
} else {
|
||||
|
||||
writeResponse(new BizException("loginRequired", "请先登录"), response);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
|
||||
sessionService.rebuildSession(sessionId);
|
||||
|
||||
} catch (BizException ex) {
|
||||
|
||||
writeResponse(ex, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var user = Ctx.currentUser();
|
||||
MDC.put("user", user.getUsername());
|
||||
|
||||
Optional<ResourceDto> userResource =
|
||||
Stream.ofAll(userService.resources(user.getId()))
|
||||
.filter(x -> StringUtils.equals(x.getId(), resource.get().getId()))
|
||||
.headOption()
|
||||
.toJavaOptional();
|
||||
|
||||
if (userResource.isEmpty() && BooleanUtils.isFalse(user.getSysAdmin())) {
|
||||
|
||||
writeResponse(new BizException("invalidAccess", "当前资源未授权,请联系机构管理员处理。"), response);
|
||||
} else {
|
||||
|
||||
try {
|
||||
|
||||
sessionService.rebuildSession(sessionId);
|
||||
|
||||
} catch (BizException ex) {
|
||||
|
||||
writeResponse(ex, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
UserEntity user = Ctx.currentUser();
|
||||
MDC.put("user", user.getUsername());
|
||||
|
||||
Optional<ResourceDto> userResource =
|
||||
Stream.ofAll(userService.resources(user.getId()))
|
||||
.filter(x -> StringUtils.equals(x.getId(), resource.get().getId()))
|
||||
.headOption()
|
||||
.toJavaOptional();
|
||||
|
||||
if (userResource.isEmpty() && BooleanUtils.isFalse(user.getSysAdmin())) {
|
||||
|
||||
writeResponse(
|
||||
new BizException("invalidAccess", "当前资源未授权,请联系机构管理员处理。"), response);
|
||||
} else {
|
||||
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
logger.warn(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
doFilter(request, response, filterChain);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.lihongjie.coal.loginUser.controller;
|
||||
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.loginUser.dto.CreateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.UpdateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.service.LoginUserService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
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;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/loginUser")
|
||||
@SysLog(module = "登录用户")
|
||||
@Slf4j
|
||||
public class LoginUserController {
|
||||
@Autowired private LoginUserService service;
|
||||
|
||||
@PostMapping("/create")
|
||||
public LoginUserDto create(@RequestBody CreateLoginUserDto request) {
|
||||
return this.service.create(request);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public LoginUserDto update(@RequestBody UpdateLoginUserDto request) {
|
||||
return this.service.update(request);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody IdRequest request) {
|
||||
this.service.delete(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PostMapping("/getById")
|
||||
public LoginUserDto getById(@RequestBody IdRequest request) {
|
||||
return this.service.getById(request.getId());
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
public Page<LoginUserDto> list(@RequestBody CommonQuery request) {
|
||||
return this.service.list(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.lihongjie.coal.loginUser.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class CreateLoginUserDto extends CommonDto {
|
||||
private UserDto user;
|
||||
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
private Integer timeout;
|
||||
private LocalDateTime loginTime;
|
||||
private LocalDateTime expireTime;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.lihongjie.coal.loginUser.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class LoginUserDto extends CommonDto {
|
||||
|
||||
private UserDto user;
|
||||
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
private Integer timeout;
|
||||
private LocalDateTime loginTime;
|
||||
private LocalDateTime expireTime;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.lihongjie.coal.loginUser.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class UpdateLoginUserDto extends CommonDto {
|
||||
private UserDto user;
|
||||
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
private Integer timeout;
|
||||
private LocalDateTime loginTime;
|
||||
private LocalDateTime expireTime;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.lihongjie.coal.loginUser.entity;
|
||||
|
||||
import cn.lihongjie.coal.base.entity.CommonEntity;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class LoginUserEntity extends CommonEntity {
|
||||
|
||||
@ManyToOne private UserEntity user;
|
||||
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
private Integer timeout;
|
||||
private LocalDateTime loginTime;
|
||||
private LocalDateTime expireTime;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.lihongjie.coal.loginUser.mapper;
|
||||
|
||||
import cn.lihongjie.coal.base.mapper.BaseMapper;
|
||||
import cn.lihongjie.coal.base.mapper.CommonMapper;
|
||||
import cn.lihongjie.coal.loginUser.dto.CreateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.UpdateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.control.DeepClone;
|
||||
|
||||
@Mapper(
|
||||
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
|
||||
uses = {CommonMapper.class},
|
||||
mappingControl = DeepClone.class)
|
||||
public interface LoginUserMapper
|
||||
extends BaseMapper<LoginUserEntity, LoginUserDto, CreateLoginUserDto, UpdateLoginUserDto> {}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.lihongjie.coal.loginUser.repository;
|
||||
|
||||
import cn.lihongjie.coal.base.dao.BaseRepository;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface LoginUserRepository extends BaseRepository<LoginUserEntity> {
|
||||
@Transactional
|
||||
@Modifying
|
||||
@Query("update LoginUserEntity l set l.expireTime = ?1 where l.id = ?2")
|
||||
void updateExpireTimeById(LocalDateTime expireTime, String id);
|
||||
|
||||
List<LoginUserEntity> findAllByUser(UserEntity user);
|
||||
|
||||
int deleteAllByExpireTimeBefore(LocalDateTime now);
|
||||
|
||||
List<LoginUserEntity> findAllByExpireTimeBefore(LocalDateTime now);
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package cn.lihongjie.coal.loginUser.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.loginUser.dto.CreateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.dto.UpdateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
import cn.lihongjie.coal.loginUser.mapper.LoginUserMapper;
|
||||
import cn.lihongjie.coal.loginUser.repository.LoginUserRepository;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LoginUserService extends BaseService<LoginUserEntity, LoginUserRepository> {
|
||||
public static final String CACHE_LOGIN_USER_BY_ID = "loginUserById";
|
||||
@Autowired SysConfigService sysConfigService;
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
@Autowired CacheManager cacheManager;
|
||||
@Autowired private LoginUserRepository repository;
|
||||
@Autowired private LoginUserMapper mapper;
|
||||
@Autowired private ConversionService conversionService;
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
executorService.scheduleAtFixedRate(this::deleteExpireSession, 1, 1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
executorService.shutdown();
|
||||
executorService.awaitTermination(1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
public LoginUserDto create(CreateLoginUserDto request) {
|
||||
LoginUserEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public LoginUserDto update(UpdateLoginUserDto request) {
|
||||
LoginUserEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
this.repository.deleteAllById(request.getIds());
|
||||
}
|
||||
|
||||
public LoginUserDto getById(String id) {
|
||||
LoginUserEntity entity = repository.get(id);
|
||||
|
||||
return mapper.toDto(entity);
|
||||
}
|
||||
|
||||
public Page<LoginUserDto> list(CommonQuery query) {
|
||||
Page<LoginUserEntity> page =
|
||||
repository.findAll(
|
||||
query.specification(conversionService),
|
||||
PageRequest.of(
|
||||
query.getPageNo(),
|
||||
query.getPageSize(),
|
||||
Sort.by(query.getOrders())));
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
|
||||
public void newLogin(LoginUserEntity entity) {
|
||||
|
||||
entity.setLoginTime(LocalDateTime.now());
|
||||
int seconds =
|
||||
Integer.parseInt(
|
||||
sysConfigService.getConfigVal(Constants.SYSCONFIG_SESSION_TIMEOUT));
|
||||
entity.setTimeout(seconds);
|
||||
entity.setExpireTime(LocalDateTime.now().plusSeconds(seconds));
|
||||
|
||||
List<LoginUserEntity> exists = this.repository.findAllByUser(entity.getUser());
|
||||
|
||||
if (!exists.isEmpty()) {
|
||||
|
||||
int maxOnlineAccount =
|
||||
Integer.parseInt(
|
||||
sysConfigService.getConfigVal(Constants.SYSCONFIG_ACCOUNT_MAX_ONLINE));
|
||||
|
||||
if (exists.size() >= maxOnlineAccount) {
|
||||
List<LoginUserEntity> toDelete =
|
||||
exists.stream()
|
||||
.sorted(Comparator.comparing(LoginUserEntity::getLoginTime))
|
||||
.limit(exists.size() - maxOnlineAccount + 1)
|
||||
.collect(Collectors.toList());
|
||||
log.warn(
|
||||
"用户 {} 已经在其他地方登录, 之前 {}个 登录将被强制下线",
|
||||
entity.getUser().getUsername(),
|
||||
toDelete.size());
|
||||
this.repository.deleteAll(toDelete);
|
||||
}
|
||||
}
|
||||
|
||||
this.save(entity);
|
||||
}
|
||||
|
||||
public void deleteExpireSession() {
|
||||
|
||||
List<LoginUserEntity> list = this.repository.findAllByExpireTimeBefore(LocalDateTime.now());
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
log.info("删除过期会话 {} 个", list.size());
|
||||
for (LoginUserEntity user : list) {
|
||||
this.clearCache(user.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void touch(LoginUserDto loginDto) {
|
||||
|
||||
Integer timeout = loginDto.getTimeout();
|
||||
|
||||
LocalDateTime expireTime = loginDto.getExpireTime();
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
if (now.isAfter(expireTime.minusSeconds(timeout / 2))) {
|
||||
|
||||
LocalDateTime newExpireTime =
|
||||
LocalDateTime.now()
|
||||
.plusSeconds(
|
||||
Integer.parseInt(
|
||||
sysConfigService.getConfigVal(
|
||||
Constants.SYSCONFIG_SESSION_TIMEOUT)));
|
||||
this.repository.updateExpireTimeById(newExpireTime, loginDto.getId());
|
||||
|
||||
log.info("更新会话过期时间: {} from {} to {}", loginDto.getId(), expireTime, newExpireTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = CACHE_LOGIN_USER_BY_ID, key = "#entity.id")
|
||||
public LoginUserDto getFromCache(LoginUserEntity entity) {
|
||||
|
||||
LoginUserDto dto = this.mapper.toDto(entity);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public void clearCache(String id) {
|
||||
if (id == null) {
|
||||
this.cacheManager.getCache(CACHE_LOGIN_USER_BY_ID).clear();
|
||||
} else {
|
||||
|
||||
this.cacheManager.getCache(CACHE_LOGIN_USER_BY_ID).evict(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = CACHE_LOGIN_USER_BY_ID, key = "#id")
|
||||
public LoginUserDto getFromCache(String id) {
|
||||
|
||||
LoginUserDto dto = this.mapper.toDto(this.get(id));
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public void deleteLogin(String sessionId) {
|
||||
|
||||
this.repository.deleteById(sessionId);
|
||||
this.clearCache(sessionId);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package cn.lihongjie.coal.permission.service;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.permission.dto.CreatePermissionDto;
|
||||
import cn.lihongjie.coal.permission.dto.PermissionDto;
|
||||
import cn.lihongjie.coal.permission.dto.PermissionExportDto;
|
||||
@@ -22,7 +23,11 @@ import jakarta.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -46,26 +51,8 @@ public class PermissionService extends BaseService<PermissionEntity, PermissionR
|
||||
@PostConstruct
|
||||
public void init() {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public PermissionDto create(CreatePermissionDto request) {
|
||||
|
||||
PermissionEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public PermissionDto update(UpdatePermissionDto request) {
|
||||
PermissionEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
@Autowired CacheManager cacheManager;
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
|
||||
@@ -101,6 +88,33 @@ public class PermissionService extends BaseService<PermissionEntity, PermissionR
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public PermissionDto create(CreatePermissionDto request) {
|
||||
|
||||
PermissionEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
this.clearCache();
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public List<PermissionEntity> getByType(String type) {
|
||||
return this.repository.findAllByPermissionType(type);
|
||||
}
|
||||
|
||||
public List<PermissionEntity> getByTypes(String[] types) {
|
||||
return this.repository.findAllByPermissionTypeIn(types);
|
||||
}
|
||||
|
||||
public PermissionDto update(UpdatePermissionDto request) {
|
||||
PermissionEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
this.clearCache();
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public void importAll(PermissionImportDto dto) {
|
||||
|
||||
List<ResourceEntity> all = resourceService.findAll();
|
||||
@@ -165,14 +179,8 @@ public class PermissionService extends BaseService<PermissionEntity, PermissionR
|
||||
|
||||
this.repository.save(permission);
|
||||
}
|
||||
}
|
||||
|
||||
public List<PermissionEntity> getByType(String type) {
|
||||
return this.repository.findAllByPermissionType(type);
|
||||
}
|
||||
|
||||
public List<PermissionEntity> getByTypes(String[] types) {
|
||||
return this.repository.findAllByPermissionTypeIn(types);
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
@@ -197,5 +205,28 @@ public class PermissionService extends BaseService<PermissionEntity, PermissionR
|
||||
|
||||
this.repository.save(permission);
|
||||
}
|
||||
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_PERMISSION)
|
||||
public List<PermissionDto> getAllFromCache() {
|
||||
|
||||
List<PermissionEntity> all = this.findAll();
|
||||
|
||||
return all.stream().map(this.mapper::toDto).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_PERMISSION_BY_TYPE, key = "#type")
|
||||
public List<PermissionDto> getByTypeFromCache(String type) {
|
||||
|
||||
return applicationContext.getBean(this.getClass()).getAllFromCache().stream()
|
||||
.filter(x -> StringUtils.equals(x.getPermissionType(), type))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
cacheManager.getCache(Constants.CACHE_PERMISSION).clear();
|
||||
cacheManager.getCache(Constants.CACHE_PERMISSION_BY_TYPE).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ package cn.lihongjie.coal.resource.service;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.resource.dto.CreateResourceDto;
|
||||
import cn.lihongjie.coal.resource.dto.ResourceDto;
|
||||
import cn.lihongjie.coal.resource.dto.ResourceTreeDto;
|
||||
import cn.lihongjie.coal.resource.dto.UpdateResourceDto;
|
||||
import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.permission.service.PermissionService;
|
||||
import cn.lihongjie.coal.resource.dto.*;
|
||||
import cn.lihongjie.coal.resource.entity.ResourceEntity;
|
||||
import cn.lihongjie.coal.resource.mapper.ResourceMapper;
|
||||
import cn.lihongjie.coal.resource.repository.ResourceRepository;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.persistence.EntityManager;
|
||||
@@ -25,6 +25,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.Cache;
|
||||
import org.hibernate.Session;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -41,6 +44,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -56,33 +60,8 @@ public class ResourceService extends BaseService<ResourceEntity, ResourceReposit
|
||||
@PostConstruct
|
||||
public void init() {}
|
||||
|
||||
public ResourceDto create(CreateResourceDto request) {
|
||||
|
||||
ResourceEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.getSessionFactory()
|
||||
.getCache()
|
||||
.evictCollectionData("cn.lihongjie.coal.resource.entity.ResourceEntity.children");
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public ResourceDto update(UpdateResourceDto request) {
|
||||
ResourceEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.getSessionFactory()
|
||||
.getCache()
|
||||
.evictCollectionData("cn.lihongjie.coal.resource.entity.ResourceEntity.children");
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
@Autowired CacheManager cacheManager;
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
|
||||
@@ -129,6 +108,51 @@ public class ResourceService extends BaseService<ResourceEntity, ResourceReposit
|
||||
.stream()
|
||||
.findFirst();
|
||||
}
|
||||
@Autowired PermissionService permissionService;
|
||||
|
||||
private List<String> getAllUrls() {
|
||||
Map<RequestMappingInfo, HandlerMethod> handlerMethods =
|
||||
requestMappingHandlerMapping.getHandlerMethods();
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
|
||||
|
||||
RequestMappingInfo info = entry.getKey();
|
||||
HandlerMethod method = entry.getValue();
|
||||
if (!method.getMethod()
|
||||
.getDeclaringClass()
|
||||
.getCanonicalName()
|
||||
.startsWith("cn.lihongjie")) {
|
||||
continue;
|
||||
}
|
||||
for (PathPattern pattern : info.getPathPatternsCondition().getPatterns()) {
|
||||
String ps = pattern.getPatternString();
|
||||
|
||||
urls.add(ps);
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
@Autowired UserService userService;
|
||||
|
||||
public ResourceDto create(CreateResourceDto request) {
|
||||
|
||||
ResourceEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
this.clearCache();
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public ResourceDto update(UpdateResourceDto request) {
|
||||
ResourceEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
this.clearCache();
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void initUrlResource() {
|
||||
@@ -177,40 +201,51 @@ public class ResourceService extends BaseService<ResourceEntity, ResourceReposit
|
||||
}
|
||||
|
||||
this.save(root);
|
||||
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
private List<String> getAllUrls() {
|
||||
Map<RequestMappingInfo, HandlerMethod> handlerMethods =
|
||||
requestMappingHandlerMapping.getHandlerMethods();
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
|
||||
|
||||
RequestMappingInfo info = entry.getKey();
|
||||
HandlerMethod method = entry.getValue();
|
||||
if (!method.getMethod()
|
||||
.getDeclaringClass()
|
||||
.getCanonicalName()
|
||||
.startsWith("cn.lihongjie")) {
|
||||
continue;
|
||||
}
|
||||
for (PathPattern pattern : info.getPathPatternsCondition().getPatterns()) {
|
||||
String ps = pattern.getPatternString();
|
||||
|
||||
urls.add(ps);
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_RESOURCE_MENU_TREE)
|
||||
public List<ResourceTreeDto> menuTree() {
|
||||
|
||||
return this.mapper.toTreeDto(
|
||||
this.repository.findAllByTypeAndParentIsNullOrderBySortKey("0"));
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_RESOURCE_API_TREE)
|
||||
public List<ResourceTreeDto> apiTree() {
|
||||
return this.mapper.toTreeDto(
|
||||
this.repository.findAllByTypeAndParentIsNullOrderBySortKey("3"));
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_RESOURCE)
|
||||
public List<ResourceDto> resourcesFromCache() {
|
||||
return this.repository.findAll().stream()
|
||||
.map(re -> mapper.toDto(re))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = Constants.CACHE_RESOURCE_BY_URL, key = "#url")
|
||||
public Optional<ResourceDto> findUrlFromCache(String url) {
|
||||
|
||||
return applicationContext.getBean(this.getClass()).resourcesFromCache().stream()
|
||||
.filter(
|
||||
x -> {
|
||||
return StringUtils.equals(x.getCode(), url)
|
||||
&& StringUtils.equals(x.getType(), "3");
|
||||
})
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
|
||||
cacheManager.getCache(Constants.CACHE_RESOURCE).clear();
|
||||
cacheManager.getCache(Constants.CACHE_RESOURCE_BY_URL).clear();
|
||||
cacheManager.getCache(Constants.CACHE_RESOURCE_MENU_TREE).clear();
|
||||
cacheManager.getCache(Constants.CACHE_RESOURCE_API_TREE).clear();
|
||||
permissionService.clearCache();
|
||||
|
||||
cacheManager.getCache(Constants.CACHE_USER_PERMISSIONS).clear();
|
||||
cacheManager.getCache(Constants.CACHE_USER_RESOURCES).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import cn.lihongjie.coal.script.service.ScriptService;
|
||||
import cn.lihongjie.coal.session.SessionService;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
import cn.lihongjie.coal.user.mapper.UserMapper;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -44,6 +45,8 @@ public class InitDataRunner implements CommandLineRunner {
|
||||
|
||||
@Autowired PermissionService permissionService;
|
||||
|
||||
@Autowired UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(String... args) throws Exception {
|
||||
@@ -56,7 +59,8 @@ public class InitDataRunner implements CommandLineRunner {
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
context.setAuthentication(new SessionService.MyAuthentication(null, u, ""));
|
||||
context.setAuthentication(
|
||||
new SessionService.MyAuthentication(null, userMapper.toDto(u), ""));
|
||||
|
||||
SecurityContextHolder.setContext(context);
|
||||
|
||||
|
||||
@@ -4,13 +4,17 @@ import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.common.Ctx;
|
||||
import cn.lihongjie.coal.common.RequestUtils;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.ip.IpQueryService;
|
||||
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
import cn.lihongjie.coal.loginUser.service.LoginUserService;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.organization.service.OrganizationService;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
@@ -48,6 +52,8 @@ public class SessionService {
|
||||
@Autowired OrganizationService organizationService;
|
||||
@Autowired ObjectMapper objectMapper;
|
||||
|
||||
@Autowired LoginUserService loginUserService;
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*
|
||||
@@ -76,6 +82,8 @@ public class SessionService {
|
||||
return new CaptchaDto(id, base64);
|
||||
}
|
||||
|
||||
@Autowired IpQueryService ipQueryService;
|
||||
|
||||
@SneakyThrows
|
||||
public void login(LoginDto dto) {
|
||||
HttpServletRequest request =
|
||||
@@ -93,7 +101,8 @@ public class SessionService {
|
||||
}
|
||||
|
||||
if (!StringUtils.equals(expectCaptcha, dto.getCaptcha())) {
|
||||
throw new BizException("验证码错误");
|
||||
stringRedisTemplate.opsForValue().getAndDelete(captchaId);
|
||||
throw new BizException("验证码错误, 请刷新验证码重试");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,21 +124,29 @@ public class SessionService {
|
||||
throw new BizException("用户名或者密码错误");
|
||||
}
|
||||
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
LoginUserEntity entity = new LoginUserEntity();
|
||||
entity.setUser(user);
|
||||
entity.setCaptcha(dto.getCaptcha());
|
||||
entity.setIp(RequestUtils.getIp(request));
|
||||
entity.setUa(RequestUtils.getUa(request));
|
||||
try {
|
||||
|
||||
entity.setLocation(ipQueryService.query(entity.getIp()));
|
||||
} catch (Exception e) {
|
||||
log.warn("查询ip地址失败 {}", entity.getIp(), e);
|
||||
}
|
||||
loginUserService.newLogin(entity);
|
||||
|
||||
LoginUserDto loginUserDto = loginUserService.getFromCache(entity);
|
||||
|
||||
String sessionId = entity.getId();
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
context.setAuthentication(new MyAuthentication(dto, user, sessionId));
|
||||
context.setAuthentication(
|
||||
new MyAuthentication(loginUserDto, loginUserDto.getUser(), sessionId));
|
||||
|
||||
SecurityContextHolder.setContext(context);
|
||||
dto.setUserId(user.getId());
|
||||
dto.setSessionId(sessionId);
|
||||
dto.setUa(RequestUtils.getUa(request));
|
||||
dto.setIp(RequestUtils.getIp(request));
|
||||
|
||||
stringRedisTemplate
|
||||
.opsForValue()
|
||||
.set(sessionId, objectMapper.writeValueAsString(dto), 1, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -140,18 +157,14 @@ public class SessionService {
|
||||
return;
|
||||
}
|
||||
|
||||
String jsonstring =
|
||||
stringRedisTemplate.opsForValue().getAndExpire(sessionId, 1, TimeUnit.HOURS);
|
||||
|
||||
if (StringUtils.isEmpty(jsonstring)) {
|
||||
throw new BizException("invalidToken", "会话已过期,请重新登录");
|
||||
}
|
||||
LoginDto loginDto = null;
|
||||
|
||||
LoginUserDto loginDto;
|
||||
try {
|
||||
loginDto = objectMapper.readValue(jsonstring, LoginDto.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BizException("invalidToken", "会话异常,请重新登录");
|
||||
|
||||
loginDto = loginUserService.getFromCache(sessionId);
|
||||
} catch (Exception e) {
|
||||
log.warn("会话已过期 {}", sessionId);
|
||||
logout(sessionId);
|
||||
throw new BizException("invalidToken", "会话已过期,请重新登录");
|
||||
}
|
||||
|
||||
HttpServletRequest request =
|
||||
@@ -161,37 +174,23 @@ public class SessionService {
|
||||
String currentUa = RequestUtils.getUa(request);
|
||||
if (!StringUtils.equalsIgnoreCase(currentIp, loginDto.getIp())) {
|
||||
|
||||
// 针对企业双线接入的情况, 允许使用两个IP登录
|
||||
if (StringUtils.isEmpty(loginDto.getIp2())) {
|
||||
// 如果两个ip都不匹配, 则认为是异常登录
|
||||
|
||||
loginDto.setIp2(currentIp);
|
||||
// 写入新的ip地址
|
||||
stringRedisTemplate
|
||||
.opsForValue()
|
||||
.set(
|
||||
sessionId,
|
||||
objectMapper.writeValueAsString(loginDto),
|
||||
1,
|
||||
TimeUnit.HOURS);
|
||||
} else {
|
||||
// 如果两个ip都不匹配, 则认为是异常登录
|
||||
if (!StringUtils.equalsIgnoreCase(currentIp, loginDto.getIp2())) {
|
||||
log.warn("检测到IP变化: {} {}", loginDto, currentIp);
|
||||
|
||||
log.warn("检测到IP变化: {} {}", loginDto, currentIp);
|
||||
|
||||
logout(loginDto.getSessionId());
|
||||
throw new BizException("invalidToken", "检测到IP发生变化,请重新登录");
|
||||
}
|
||||
}
|
||||
logout(loginDto.getId());
|
||||
throw new BizException("invalidToken", "检测到IP发生变化,请重新登录");
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(currentUa, loginDto.getUa())) {
|
||||
|
||||
log.warn("检测到浏览器变化: {} {}", loginDto, currentUa);
|
||||
logout(loginDto.getSessionId());
|
||||
logout(loginDto.getId());
|
||||
throw new BizException("invalidToken", "检测到浏览器发生变化,请重新登录");
|
||||
}
|
||||
|
||||
UserEntity user = userService.get(loginDto.getUserId());
|
||||
loginUserService.touch(loginDto);
|
||||
|
||||
UserDto user = loginDto.getUser();
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
@@ -204,7 +203,7 @@ public class SessionService {
|
||||
|
||||
if (sessionId != null) {
|
||||
|
||||
stringRedisTemplate.opsForValue().getAndDelete(sessionId);
|
||||
loginUserService.deleteLogin(sessionId);
|
||||
try {
|
||||
|
||||
userService.clearUserCache(Ctx.currentUser().getId());
|
||||
@@ -214,13 +213,11 @@ public class SessionService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void anonymousSession() {
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
UserEntity user = new UserEntity();
|
||||
UserDto user = new UserDto();
|
||||
user.setName("匿名用户");
|
||||
user.setUsername("anonymous");
|
||||
context.setAuthentication(new MyAuthentication(null, user, "-1"));
|
||||
@@ -230,11 +227,11 @@ public class SessionService {
|
||||
|
||||
@Data
|
||||
public static class MyAuthentication implements Authentication {
|
||||
private final LoginDto dto;
|
||||
private final UserEntity user;
|
||||
private final LoginUserDto dto;
|
||||
private final UserDto user;
|
||||
private final String sessionId;
|
||||
|
||||
public MyAuthentication(LoginDto dto, UserEntity user, String sessionId) {
|
||||
public MyAuthentication(LoginUserDto dto, UserDto user, String sessionId) {
|
||||
this.dto = dto;
|
||||
this.user = user;
|
||||
this.sessionId = sessionId;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@@ -66,6 +67,32 @@ public class SysConfigService extends BaseService<SysConfigEntity, SysConfigRepo
|
||||
entity.setType("3");
|
||||
repository.save(entity);
|
||||
}
|
||||
|
||||
if (!all.containsKey(Constants.SYSCONFIG_SESSION_TIMEOUT)) {
|
||||
SysConfigEntity entity = new SysConfigEntity();
|
||||
entity.setName("登录会话超时时间(s)");
|
||||
entity.setCode(Constants.SYSCONFIG_SESSION_TIMEOUT);
|
||||
entity.setConfigVal(TimeUnit.HOURS.toSeconds(1) + "");
|
||||
entity.setDictCode(null);
|
||||
entity.setMaxValue((int) TimeUnit.HOURS.toSeconds(24));
|
||||
entity.setMinValue((int) TimeUnit.MINUTES.toSeconds(1));
|
||||
entity.setRegexValidator(null);
|
||||
entity.setType("2");
|
||||
repository.save(entity);
|
||||
}
|
||||
|
||||
if (!all.containsKey(Constants.SYSCONFIG_ACCOUNT_MAX_ONLINE)) {
|
||||
SysConfigEntity entity = new SysConfigEntity();
|
||||
entity.setName("账户同时登录人数");
|
||||
entity.setCode(Constants.SYSCONFIG_ACCOUNT_MAX_ONLINE);
|
||||
entity.setConfigVal("1");
|
||||
entity.setDictCode(null);
|
||||
entity.setMaxValue(1000);
|
||||
entity.setMinValue(1);
|
||||
entity.setRegexValidator(null);
|
||||
entity.setType("2");
|
||||
repository.save(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -25,9 +25,14 @@ public class UserDto extends OrgCommonDto {
|
||||
@Comment("机构管理员标识")
|
||||
private Boolean orgAdmin;
|
||||
|
||||
@Comment("系统管理员标识")
|
||||
private Boolean sysAdmin;
|
||||
|
||||
private List<RoleDto> roles;
|
||||
private List<RoleDto> otherRoles;
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
public static class RoleDto extends OrgCommonDto {}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.entity.BaseEntity;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.common.Ctx;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
@@ -123,7 +124,7 @@ public class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
}
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userResources", key = "#request.id")
|
||||
@CacheEvict(cacheNames = Constants.CACHE_USER_RESOURCES, key = "#request.id")
|
||||
public UserDto update(UpdateUserDto request) {
|
||||
UserEntity user = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(user, request);
|
||||
@@ -238,7 +239,7 @@ public class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
|
||||
@Autowired CacheManager cacheManager;
|
||||
|
||||
@Cacheable(cacheNames = "userResources", key = "#id")
|
||||
@Cacheable(cacheNames = Constants.CACHE_USER_RESOURCES, key = "#id")
|
||||
public List<ResourceDto> resources(String id) {
|
||||
|
||||
UserEntity user = get(id);
|
||||
@@ -267,7 +268,7 @@ public class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
|
||||
@Autowired PermissionMapper permissionMapper;
|
||||
|
||||
@Cacheable(cacheNames = "userPermissions", key = "#id")
|
||||
@Cacheable(cacheNames = Constants.CACHE_USER_PERMISSIONS, key = "#id")
|
||||
public List<PermissionSimpleDto> permissions(String id) {
|
||||
|
||||
UserEntity user = get(id);
|
||||
@@ -293,13 +294,13 @@ public class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
public void clearUserCache(String id) {
|
||||
try {
|
||||
|
||||
cacheManager.getCache("userResources").evict(id);
|
||||
cacheManager.getCache(Constants.CACHE_USER_RESOURCES).evict(id);
|
||||
} catch (Exception e) {
|
||||
log.error("清除用户资源缓存失败", e);
|
||||
}
|
||||
try {
|
||||
|
||||
cacheManager.getCache("userPermissions").evict(id);
|
||||
cacheManager.getCache(Constants.CACHE_USER_PERMISSIONS).evict(id);
|
||||
} catch (Exception e) {
|
||||
log.error("清除用户权限缓存失败", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user