feat: 优化Security

This commit is contained in:
yulinling 2025-06-23 22:23:26 +08:00
parent 018c644d68
commit 5d44035a2f
13 changed files with 196 additions and 64 deletions

View File

@ -1,5 +1,6 @@
package asia.yulinling.workflow.config; package asia.yulinling.workflow.config;
import asia.yulinling.workflow.scope.RequestScopeData;
import asia.yulinling.workflow.security.*; import asia.yulinling.workflow.security.*;
import asia.yulinling.workflow.utils.JwtUtil; import asia.yulinling.workflow.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -34,6 +35,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
@Slf4j @Slf4j
public class SecurityConfig { public class SecurityConfig {
private final RequestScopeData scopeData;
private final JwtUserDetailsService jwtUserDetailsService; private final JwtUserDetailsService jwtUserDetailsService;
private final JwtRbacAuthenticationService jwtRbacAuthenticationService; private final JwtRbacAuthenticationService jwtRbacAuthenticationService;
@ -56,19 +58,19 @@ public class SecurityConfig {
) )
// 认证请求 // 认证请求
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/**").permitAll() .requestMatchers("/auth/**").permitAll()
.requestMatchers("/auth/register").permitAll() .requestMatchers("/auth/register").permitAll()
.anyRequest().access((authenticationSupplier, requestAuthorizationContext) -> { .anyRequest().access((authenticationSupplier, requestAuthorizationContext) -> {
HttpServletRequest request = requestAuthorizationContext.getRequest(); HttpServletRequest request = requestAuthorizationContext.getRequest();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new AuthorizationDecision( return new AuthorizationDecision(
jwtRbacAuthenticationService.hasPermission(request, authentication) jwtRbacAuthenticationService.hasPermission(request, authentication)
); );
}) })
) )
// JWT过滤器 // JWT过滤器
.addFilterBefore( .addFilterBefore(
new JwtAuthenticationFilter(jwtUtil, jwtUserDetailsService), new JwtAuthenticationFilter(jwtUtil, scopeData, jwtUserDetailsService),
UsernamePasswordAuthenticationFilter.class UsernamePasswordAuthenticationFilter.class
); );

View File

@ -0,0 +1,39 @@
package asia.yulinling.workflow.dto.request;
import lombok.Data;
/**
* <p>
* 更新用户信息类
* </p>
*
* @author YLL
* @since 2025/6/23
*/
@Data
public class UpdateUserRequest {
/**
* 主键id
*/
private Long id;
/**
* 昵称
*/
private String nickname;
/**
* 生日
*/
private String birthday;
/**
* 性别,-1,-2
*/
private Integer sex;
/**
* 手机号
*/
private String phone;
}

View File

@ -4,13 +4,11 @@ import asia.yulinling.workflow.model.entity.Permission;
import asia.yulinling.workflow.model.entity.Role; import asia.yulinling.workflow.model.entity.Role;
import asia.yulinling.workflow.model.entity.User; import asia.yulinling.workflow.model.entity.User;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
@ -37,7 +35,6 @@ public class UserPrincipal implements UserDetails {
/** /**
* 主键id * 主键id
*/ */
@TableId(type = IdType.AUTO)
private Long id; private Long id;
/** /**
@ -53,7 +50,6 @@ public class UserPrincipal implements UserDetails {
/** /**
* 加密后的密码 * 加密后的密码
*/ */
@JsonIgnore
private String password; private String password;
/** /**
@ -156,8 +152,6 @@ public class UserPrincipal implements UserDetails {
List<Role> roles, List<Role> roles,
List<Permission> permissions) { List<Permission> permissions) {
log.info("roleNames{}\n{}authorities", roles, permissions);
List<String> roleNames = roles List<String> roleNames = roles
.stream() .stream()
.map(Role::getName) .map(Role::getName)
@ -171,20 +165,12 @@ public class UserPrincipal implements UserDetails {
new SimpleGrantedAuthority(permission.getPermission())) new SimpleGrantedAuthority(permission.getPermission()))
.collect(Collectors.toList()); .collect(Collectors.toList());
return new UserPrincipal( UserPrincipal userPrincipal = new UserPrincipal();
user.getId(), BeanUtils.copyProperties(user, userPrincipal);
user.getUsername(), userPrincipal.setRoles(roleNames);
user.getPassword(), userPrincipal.setAuthorities(authorities);
user.getNickname(),
user.getPhone(), return userPrincipal;
user.getEmail(),
user.getBirthday(),
user.getSex(),
user.getStatus(),
user.getCreateTime(),
user.getUpdateTime(),
roleNames,
authorities);
} }

View File

@ -4,7 +4,7 @@ import lombok.Data;
/** /**
* <p> * <p>
* 用户信息VO * 用户信息VO
* </p> * </p>
* *
* @author YLL * @author YLL

View File

@ -0,0 +1,22 @@
package asia.yulinling.workflow.scope;
import lombok.Data;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
/**
* <p>
* 请求生命周期的全局数据
* </p>
*
* @author YLL
* @since 2025/6/23
*/
@Component
@RequestScope
@Data
public class RequestScopeData {
private String token;
private Long userId;
private boolean isLogin;
}

View File

@ -1,8 +1,8 @@
package asia.yulinling.workflow.security; package asia.yulinling.workflow.security;
import asia.yulinling.workflow.exception.SecurityException; import asia.yulinling.workflow.exception.SecurityException;
import asia.yulinling.workflow.constant.Status;
import asia.yulinling.workflow.model.vo.user.UserPrincipal; import asia.yulinling.workflow.model.vo.user.UserPrincipal;
import asia.yulinling.workflow.scope.RequestScopeData;
import asia.yulinling.workflow.utils.JwtUtil; import asia.yulinling.workflow.utils.JwtUtil;
import asia.yulinling.workflow.utils.ResponseUtil; import asia.yulinling.workflow.utils.ResponseUtil;
import jakarta.servlet.FilterChain; import jakarta.servlet.FilterChain;
@ -32,6 +32,7 @@ import java.io.IOException;
@Slf4j @Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter { public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil; private final JwtUtil jwtUtil;
private final RequestScopeData scopeData;
private final JwtUserDetailsService jwtUserDetailsService; private final JwtUserDetailsService jwtUserDetailsService;
@Override @Override
@ -45,7 +46,12 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
if (StringUtils.hasText(token) && jwtUtil.validateToken(token)) { if (StringUtils.hasText(token) && jwtUtil.validateToken(token)) {
try { try {
// 2. 解析token获取username // 2. 解析token获取username
String username = jwtUtil.parseToken(token).getSubject(); String username = jwtUtil.getUsernameByToken(token);
Long userId = jwtUtil.getUserIdByToken(token);
scopeData.setUserId(userId);
scopeData.setToken(token);
scopeData.setLogin(true);
// 3. 根据username验证password // 3. 根据username验证password
UserPrincipal userPrincipal = jwtUserDetailsService.loadUserByUsername(username); UserPrincipal userPrincipal = jwtUserDetailsService.loadUserByUsername(username);
@ -57,11 +63,12 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} catch (SecurityException e) { } catch (SecurityException e) {
log.error("Security异常:{}", e.getMessage()); log.error("Security异常:{}", e.getMessage());
ResponseUtil.renderJson(response, e); ResponseUtil.renderJson(response, e);
} }
} else {
scopeData.setLogin(false);
} }
filterChain.doFilter(request, response); filterChain.doFilter(request, response);

View File

@ -12,7 +12,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
@ -57,8 +56,8 @@ public class JwtRbacAuthenticationService {
List<Permission> pagePerms = permissions.stream() List<Permission> pagePerms = permissions.stream()
.filter(permission -> Objects.equals(permission.getType(), 1)) .filter(permission -> Objects.equals(permission.getType(), 1))
.filter(permission -> !StringUtils.isEmpty(permission.getUrl())) .filter(permission -> !permission.getUrl().isEmpty())
.filter(permission -> !StringUtils.isEmpty(permission.getMethod())) .filter(permission -> !permission.getMethod().isEmpty())
.toList(); .toList();
for (Permission permission : pagePerms) { for (Permission permission : pagePerms) {

View File

@ -2,7 +2,6 @@ package asia.yulinling.workflow.security;
import asia.yulinling.workflow.mapper.PermissionMapper; import asia.yulinling.workflow.mapper.PermissionMapper;
import asia.yulinling.workflow.mapper.RoleMapper; import asia.yulinling.workflow.mapper.RoleMapper;
import asia.yulinling.workflow.mapper.RoleUserMapper;
import asia.yulinling.workflow.mapper.UserMapper; import asia.yulinling.workflow.mapper.UserMapper;
import asia.yulinling.workflow.model.entity.Permission; import asia.yulinling.workflow.model.entity.Permission;
import asia.yulinling.workflow.model.entity.Role; import asia.yulinling.workflow.model.entity.Role;
@ -12,6 +11,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -33,7 +33,6 @@ import java.util.stream.Collectors;
public class JwtUserDetailsService implements UserDetailsService { public class JwtUserDetailsService implements UserDetailsService {
private final UserMapper userMapper; private final UserMapper userMapper;
private final RoleMapper roleMapper; private final RoleMapper roleMapper;
private final RoleUserMapper roleUserMapper;
private final PermissionMapper permissionMapper; private final PermissionMapper permissionMapper;
@Override @Override
@ -53,21 +52,20 @@ public class JwtUserDetailsService implements UserDetailsService {
log.error("未找到用户信息{}", username); log.error("未找到用户信息{}", username);
throw new UsernameNotFoundException("未找到用户信息:" + username); throw new UsernameNotFoundException("未找到用户信息:" + username);
} }
log.info("username:{}", username);
// 3. 查找用户对应的角色 // 3. 查找用户对应的角色
List<Role> roles = roleMapper.selectRoleByUserId(user.getId()); List<Role> roles = roleMapper.selectRoleByUserId(user.getId());
if (roles.isEmpty()) { if (roles.isEmpty()) {
log.error("未找到角色信息{}", roles); log.error("未找到角色信息{}", roles);
throw new UsernameNotFoundException("未找到角色信息" + roles); throw new AccessDeniedException("未找到角色信息" + roles);
} }
List<Permission> permissions = permissionMapper.selectPermissionsByRoleId(roles.stream().map(Role::getId).collect(Collectors.toList())); List<Permission> permissions = permissionMapper.selectPermissionsByRoleId(roles.stream().map(Role::getId).collect(Collectors.toList()));
if (permissions.isEmpty()) { if (permissions.isEmpty()) {
log.error("未找到权限信息{}", permissions); log.error("未找到权限信息{}", permissions);
throw new UsernameNotFoundException("未找到权限信息" + permissions); throw new AccessDeniedException("未找到权限信息" + permissions);
} }
// 4. 返回User // 4. 返回User

View File

@ -1,8 +1,9 @@
package asia.yulinling.workflow.service; package asia.yulinling.workflow.service;
import asia.yulinling.workflow.dto.request.PageParam; import asia.yulinling.workflow.dto.request.PageParam;
import asia.yulinling.workflow.model.ApiResponse; import asia.yulinling.workflow.dto.request.UpdateUserRequest;
import asia.yulinling.workflow.dto.response.PageResult; import asia.yulinling.workflow.dto.response.PageResult;
import asia.yulinling.workflow.model.ApiResponse;
import asia.yulinling.workflow.model.vo.user.UserVO; import asia.yulinling.workflow.model.vo.user.UserVO;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -24,4 +25,12 @@ public interface UserService {
* @return 用户列表 * @return 用户列表
*/ */
ApiResponse<PageResult<UserVO>> getUserListByPage(PageParam pageParam); ApiResponse<PageResult<UserVO>> getUserListByPage(PageParam pageParam);
/**
* 更新用户信息
*
* @param request UpdateUserRequest
* @return 更新状态
*/
ApiResponse<?> updateUserInfo(UpdateUserRequest request);
} }

View File

@ -1,18 +1,23 @@
package asia.yulinling.workflow.service.impl; package asia.yulinling.workflow.service.impl;
import asia.yulinling.workflow.dto.request.PageParam; import asia.yulinling.workflow.dto.request.PageParam;
import asia.yulinling.workflow.dto.request.UpdateUserRequest;
import asia.yulinling.workflow.dto.response.PageResult;
import asia.yulinling.workflow.mapper.UserMapper; import asia.yulinling.workflow.mapper.UserMapper;
import asia.yulinling.workflow.model.ApiResponse; import asia.yulinling.workflow.model.ApiResponse;
import asia.yulinling.workflow.dto.response.PageResult;
import asia.yulinling.workflow.model.entity.User; import asia.yulinling.workflow.model.entity.User;
import asia.yulinling.workflow.model.vo.user.UserVO; import asia.yulinling.workflow.model.vo.user.UserVO;
import asia.yulinling.workflow.scope.RequestScopeData;
import asia.yulinling.workflow.service.UserService; import asia.yulinling.workflow.service.UserService;
import asia.yulinling.workflow.utils.PageUtil; import asia.yulinling.workflow.utils.PageUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,6 +37,7 @@ public class UserServiceImpl implements UserService {
/** 注入用户Mapper */ /** 注入用户Mapper */
private final UserMapper userMapper; private final UserMapper userMapper;
private final RequestScopeData scopeData;
/** /**
* 获取用户列表分页 * 获取用户列表分页
@ -65,4 +71,41 @@ public class UserServiceImpl implements UserService {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/**
* 更新用户信息
*
* @param request UpdateUserRequest
* @return 更新状态
*/
@Override
@Transactional(rollbackFor = Exception.class)
public ApiResponse<?> updateUserInfo(UpdateUserRequest request) {
Long userId = scopeData.getUserId();
Long requestUserId = request.getId();
if (!requestUserId.equals(userId)) {
log.error("user id not match, scopeData: {}, requestUserId: {}", requestUserId, userId);
throw new RuntimeException("用户Id不匹配");
}
User user = new User();
BeanUtils.copyProperties(request, user);
LambdaUpdateWrapper<User> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
userLambdaUpdateWrapper.eq(User::getId, userId);
userLambdaUpdateWrapper.set(StringUtils.hasText(request.getNickname()), User::getNickname, request.getNickname());
userLambdaUpdateWrapper.set(StringUtils.hasText(request.getBirthday()), User::getBirthday, request.getBirthday());
userLambdaUpdateWrapper.set(request.getSex() != null, User::getSex, request.getSex());
userLambdaUpdateWrapper.set(StringUtils.hasText(request.getPhone()), User::getPhone, request.getPhone());
try {
userMapper.update(userLambdaUpdateWrapper);
return ApiResponse.ofSuccess("更新成功");
} catch (Exception e) {
log.error("update user error:{}", e.getMessage());
return ApiResponse.ofSuccess("更新失败");
}
}
} }

View File

@ -3,7 +3,9 @@ package asia.yulinling.workflow.utils;
import asia.yulinling.workflow.constant.Const; import asia.yulinling.workflow.constant.Const;
import asia.yulinling.workflow.constant.Status; import asia.yulinling.workflow.constant.Status;
import asia.yulinling.workflow.exception.SecurityException; import asia.yulinling.workflow.exception.SecurityException;
import asia.yulinling.workflow.model.vo.user.UserPrincipal;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -13,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.security.Key; import java.security.Key;
@ -59,6 +60,27 @@ public class JwtUtil {
* @return JWT * @return JWT
*/ */
public String generateToken(Authentication authentication, boolean isRememberMe) { public String generateToken(Authentication authentication, boolean isRememberMe) {
// 1. 解析principal
Object principal = authentication.getPrincipal();
Long userId = null;
String username = null;
if (principal instanceof UserPrincipal) {
userId = ((UserPrincipal) principal).getId();
username = ((UserPrincipal) principal).getUsername();
}
return generateToken(userId, username, isRememberMe);
}
/**
* 创建JWT
*
* @param userId 用户Id
* @param username 用户名
* @param isRememberMe 记住我
* @return JWT
*/
public String generateToken(Long userId, String username, boolean isRememberMe) {
// 1. 当前时间 // 1. 当前时间
Date now = new Date(); Date now = new Date();
@ -66,18 +88,20 @@ public class JwtUtil {
long ttl = isRememberMe ? this.remember : this.ttl; long ttl = isRememberMe ? this.remember : this.ttl;
Date expiration = new Date(now.getTime() + ttl); Date expiration = new Date(now.getTime() + ttl);
// 3. 构建 JWT // 3. 构建JwtBuilder
String username = authentication.getName();
JwtBuilder builder = Jwts.builder() JwtBuilder builder = Jwts.builder()
.setSubject(username) .setSubject(username)
.claim("userId", userId)
.setIssuedAt(now) .setIssuedAt(now)
.setExpiration(expiration) .setExpiration(expiration)
.signWith(this.key()); .signWith(this.key());
// 4. 生成token // 4. 生成token
String token = builder.compact(); String token = builder.compact();
// 5. 将token存入redis // 5. 将token存入redis
stringRedisTemplate.opsForValue().set(Const.REDIS_JWT_KEY_PREFIX + username, token, ttl, TimeUnit.SECONDS); stringRedisTemplate.opsForValue().set(Const.REDIS_JWT_KEY_PREFIX + username, token, ttl, TimeUnit.SECONDS);
// 6. 返回生成的token // 6. 返回生成的token
return token; return token;
} }
@ -122,6 +146,16 @@ public class JwtUtil {
} }
} }
public Long getUserIdByToken(String token) {
Claims claims = parseToken(token);
return (Long) claims.get("userId");
}
public String getUsernameByToken(String token) {
Claims claims = parseToken(token);
return claims.getSubject();
}
/** /**
* 校验Token * 校验Token
* *

View File

@ -1,24 +1,22 @@
BEGIN; BEGIN;
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379288399872, '测试页面', '/test', 1, 'page:test', 'GET', 1, 0); VALUES (1072806379288399872, '测试页面', '/test', 1, 'page:test', 'GET', 1, 0, NULL, NULL);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379313565696, '测试页面-查询', '/**/test', 2, 'btn:test:query', 'GET', 1, 1072806379288399872); VALUES (1072806379313565696, '测试页面-查询', '/**/test', 2, 'btn:test:query', 'GET', 1, 1072806379288399872, NULL,
NULL);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379330342912, '测试页面-添加', '/**/test', 2, 'btn:test:insert', 'POST', 2, 1072806379288399872); VALUES (1072806379330342912, '测试页面-添加', '/**/test', 2, 'btn:test:insert', 'POST', 2, 1072806379288399872, NULL,
NULL);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379342925824, '监控在线用户页面', '/monitor', 1, 'page:monitor:online', NULL, 2, 0); VALUES (1072806379342925824, '监控在线用户页面', '/monitor', 1, 'page:monitor:online', NULL, 2, 0, NULL, NULL);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379363897344, '在线用户页面-查询', '/**/api/monitor/online/user', 2, 'btn:monitor:online:query', 'GET', VALUES (1072806379363897344, '在线用户页面-查询', '/**/api/monitor/online/user', 2, 'btn:monitor:online:query', 'GET',
1, 1, 1072806379342925824, NULL, NULL);
1072806379342925824);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379384868864, '在线用户页面-踢出', '/**/api/monitor/online/user/kickout', 2, VALUES (1072806379384868864, '在线用户页面-踢出', '/**/api/monitor/online/user/kickout', 2,
'btn:monitor:online:kickout', 'btn:monitor:online:kickout', 'DELETE', 2, 1072806379342925824, NULL, NULL);
'DELETE', 2, 1072806379342925824);
INSERT INTO `wk_permission` INSERT INTO `wk_permission`
VALUES (1072806379384868865, '用户列表', '/users', 1, VALUES (1072806379384868865, '用户列表', '/users', 1, 'page:test', 'GET', 1, 0, NULL, NULL);
'page:test',
'GET', 1, 0);
COMMIT; COMMIT;
BEGIN; BEGIN;

View File

@ -21,11 +21,6 @@ public class UserServiceTest extends WorkFlowMainTests {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Test
public void getUserList() {
ApiResponse<PageResult<UserVO>> users = userService.getUserList();
Assertions.assertEquals(200, users.getCode().intValue());
}
@Test @Test
public void getUserListByPage() { public void getUserListByPage() {