数据加解密和完整性校验

This commit is contained in:
jiang 2024-07-24 10:50:53 +08:00
parent 56c5ff428b
commit 5edaf204f6
9 changed files with 426 additions and 361 deletions

View File

@ -3,6 +3,7 @@ package com.bonus.system.api.domain;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.bonus.common.core.annotation.Excel; import com.bonus.common.core.annotation.Excel;
@ -17,286 +18,288 @@ import com.bonus.common.core.xss.Xss;
* *
* @author bonus * @author bonus
*/ */
public class SysUser extends BaseEntity public class SysUser extends BaseEntity {
{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 用户ID */ /**
* 用户ID
*/
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId; private Long userId;
/** 部门ID */ /**
* 部门ID
*/
@Excel(name = "部门编号", type = Type.IMPORT) @Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId; private Long deptId;
/** 用户账号 */ /**
* 用户账号
*/
@Excel(name = "登录名称") @Excel(name = "登录名称")
private String userName; private String userName;
/** 用户昵称 */ /**
* 用户昵称
*/
@Excel(name = "用户名称") @Excel(name = "用户名称")
private String nickName; private String nickName;
/** 用户邮箱 */ /**
* 用户邮箱
*/
@Excel(name = "用户邮箱") @Excel(name = "用户邮箱")
private String email; private String email;
/** 手机号码 */ /**
* 手机号码
*/
@Excel(name = "手机号码", cellType = ColumnType.TEXT) @Excel(name = "手机号码", cellType = ColumnType.TEXT)
private String phonenumber; private String phonenumber;
/** 用户性别 */ /**
* 用户性别
*/
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex; private String sex;
/** 用户头像 */ /**
* 用户头像
*/
private String avatar; private String avatar;
/** 密码 */ /**
* 密码
*/
private String password; private String password;
/** 帐号状态0正常 1停用 */ /**
* 帐号状态0正常 1停用
*/
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status; private String status;
/** 删除标志0代表存在 2代表删除 */ /**
* 删除标志0代表存在 2代表删除
*/
private String delFlag; private String delFlag;
/** 最后登录IP */ /**
* 最后登录IP
*/
@Excel(name = "最后登录IP", type = Type.EXPORT) @Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp; private String loginIp;
/** 最后登录时间 */ /**
* 最后登录时间
*/
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate; private Date loginDate;
/** 部门对象 */ /**
* 部门对象
*/
@Excels({ @Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
}) })
private SysDept dept; private SysDept dept;
/** 角色对象 */ /**
* 角色对象
*/
private List<SysRole> roles; private List<SysRole> roles;
/** 角色组 */ /**
* 角色组
*/
private Long[] roleIds; private Long[] roleIds;
/** 岗位组 */ /**
* 岗位组
*/
private Long[] postIds; private Long[] postIds;
/** 角色ID */ /**
* 角色ID
*/
private Long roleId; private Long roleId;
/** 登录权限 */ /**
* 登录权限
*/
private String loginType; private String loginType;
/**
* 审批状态
*/
private String approvalStatus;
public SysUser() public SysUser() {
{
} }
public SysUser(Long userId)
{ public SysUser(Long userId) {
this.userId = userId; this.userId = userId;
} }
public Long getUserId() public Long getUserId() {
{
return userId; return userId;
} }
public void setUserId(Long userId) public void setUserId(Long userId) {
{
this.userId = userId; this.userId = userId;
} }
public boolean isAdmin() public boolean isAdmin() {
{
return isAdmin(this.userId); return isAdmin(this.userId);
} }
public static boolean isAdmin(Long userId) public static boolean isAdmin(Long userId) {
{
return userId != null && 1L == userId; return userId != null && 1L == userId;
} }
public Long getDeptId() public Long getDeptId() {
{
return deptId; return deptId;
} }
public void setDeptId(Long deptId) public void setDeptId(Long deptId) {
{
this.deptId = deptId; this.deptId = deptId;
} }
@Xss(message = "用户昵称不能包含脚本字符") @Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName() public String getNickName() {
{
return nickName; return nickName;
} }
public void setNickName(String nickName) public void setNickName(String nickName) {
{
this.nickName = nickName; this.nickName = nickName;
} }
@Xss(message = "用户账号不能包含脚本字符") @Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空") @NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName() public String getUserName() {
{
return userName; return userName;
} }
public void setUserName(String userName) public void setUserName(String userName) {
{
this.userName = userName; this.userName = userName;
} }
@Email(message = "邮箱格式不正确") @Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail() public String getEmail() {
{
return email; return email;
} }
public void setEmail(String email) public void setEmail(String email) {
{
this.email = email; this.email = email;
} }
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber() public String getPhonenumber() {
{
return phonenumber; return phonenumber;
} }
public void setPhonenumber(String phonenumber) public void setPhonenumber(String phonenumber) {
{
this.phonenumber = phonenumber; this.phonenumber = phonenumber;
} }
public String getSex() public String getSex() {
{
return sex; return sex;
} }
public void setSex(String sex) public void setSex(String sex) {
{
this.sex = sex; this.sex = sex;
} }
public String getAvatar() public String getAvatar() {
{
return avatar; return avatar;
} }
public void setAvatar(String avatar) public void setAvatar(String avatar) {
{
this.avatar = avatar; this.avatar = avatar;
} }
public String getPassword() public String getPassword() {
{
return password; return password;
} }
public void setPassword(String password) public void setPassword(String password) {
{
this.password = password; this.password = password;
} }
public String getStatus() public String getStatus() {
{
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status) {
{
this.status = status; this.status = status;
} }
public String getDelFlag() public String getDelFlag() {
{
return delFlag; return delFlag;
} }
public void setDelFlag(String delFlag) public void setDelFlag(String delFlag) {
{
this.delFlag = delFlag; this.delFlag = delFlag;
} }
public String getLoginIp() public String getLoginIp() {
{
return loginIp; return loginIp;
} }
public void setLoginIp(String loginIp) public void setLoginIp(String loginIp) {
{
this.loginIp = loginIp; this.loginIp = loginIp;
} }
public Date getLoginDate() public Date getLoginDate() {
{
return loginDate; return loginDate;
} }
public void setLoginDate(Date loginDate) public void setLoginDate(Date loginDate) {
{
this.loginDate = loginDate; this.loginDate = loginDate;
} }
public SysDept getDept() public SysDept getDept() {
{
return dept; return dept;
} }
public void setDept(SysDept dept) public void setDept(SysDept dept) {
{
this.dept = dept; this.dept = dept;
} }
public List<SysRole> getRoles() public List<SysRole> getRoles() {
{
return roles; return roles;
} }
public void setRoles(List<SysRole> roles) public void setRoles(List<SysRole> roles) {
{
this.roles = roles; this.roles = roles;
} }
public Long[] getRoleIds() public Long[] getRoleIds() {
{
return roleIds; return roleIds;
} }
public void setRoleIds(Long[] roleIds) public void setRoleIds(Long[] roleIds) {
{
this.roleIds = roleIds; this.roleIds = roleIds;
} }
public Long[] getPostIds() public Long[] getPostIds() {
{
return postIds; return postIds;
} }
public void setPostIds(Long[] postIds) public void setPostIds(Long[] postIds) {
{
this.postIds = postIds; this.postIds = postIds;
} }
public Long getRoleId() public Long getRoleId() {
{
return roleId; return roleId;
} }
public void setRoleId(Long roleId) public void setRoleId(Long roleId) {
{
this.roleId = roleId; this.roleId = roleId;
} }
@ -308,6 +311,14 @@ public class SysUser extends BaseEntity
this.loginType = loginType; this.loginType = loginType;
} }
public String getApprovalStatus() {
return approvalStatus;
}
public void setApprovalStatus(String approvalStatus) {
this.approvalStatus = approvalStatus;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

View File

@ -84,7 +84,7 @@ public class AesCbcUtils {
String json="{\"username\":\"guest\",\"password\":\"admin@123\"}"; String json="{\"username\":\"guest\",\"password\":\"admin@123\"}";
String data=encrypt(json); String data=encrypt(json);
System.err.println(data); System.err.println(data);
String jm=decrypt("HpouTnMjl/Of1leko+SHm3D436XwOROzSOhMqU0ZNUISeD/iXPK9t49sMEuBw3YO"); String jm=decrypt("\"yeCxaGhmdDt+zDsKPr1prukR15BfIMLMOYIFKdgffGpMV76qVD8ANU4zsLiRZ87+7hd1Yje182nHhUOp/TeYCRuuUPQzmuXH7ikYVEWR1Rmc8uLq3G/BTMU6wFMSRFDBXARRl+dvnpyfX+MleF0KB1OAeuOIKv1gQPskmvDiFAniUlowf/96ZzMl7Bokqc/Lse8lMV92IQB14yQNa0+u/2kvdirzrcq+HCt9K8Ot3C59mjDqg49WoM65LEmaHmZqzdmmjbQlGH7ZOAFTLvF5kPzUsMz5Uim1uNvByB3eLFohc1UgB28DWoTyh43sRMPpq3S1BB20gcrBf3uVra/4qehBr3z98CGhGRyKHbjsCKl0Ri6YO1rp5aMRd9Y3wbOJFrZXFag5iifQx+ooDBeu6h1KCb5JfCjyAmw9+pgEL6X3eELPzK13XjblDyEikjx2Edv45MGsC0DUcjvz/Sb4E/8rn3o1Ep7W31xNCdn5mzZ8VO9POhE3DMK6woeN2C7TW+7YO/Zs9e4zKLS4vThvk5urCn2Ff2HkVBzoPtP2imuqQrY8898sbLllyaJEG0DPSrCf985ZgVa03JsO/EkMr3KAiHV5SHBZS1XEXqjdpL+YEdOnlfBXUk83kJhLj9rhUrTFza7ednQSzjq4XpIJJVy2aJhhj1chsmIM1Xl//0Dbak9Lb6VUq5Xr2IFAjNTgyxwtcFCdEvp4YZCSP6kqWgEpeAVlejyYOcNckUnWkjeHjtfgwvVsvUjWzyIRFCa7m/oY28xBV16RmW/r4XXquqKVdbPtATzrmf7pJCynXZ3IPd9ZGc1OTLnss9Ln9XNTH0E/I4Ma95fn9uxA+sOQkQ==\"");
String jiemi=decrypt(data); String jiemi=decrypt(data);
System.err.println(jm); System.err.println(jm);
System.err.println(jiemi); System.err.println(jiemi);

View File

@ -3,163 +3,191 @@ package com.bonus.gateway.filter;
import com.bonus.common.core.exception.CaptchaException; import com.bonus.common.core.exception.CaptchaException;
import com.bonus.common.core.utils.StringUtils; import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.encryption.AesCbcUtils; import com.bonus.common.core.utils.encryption.AesCbcUtils;
import com.bonus.common.core.utils.global.CommonConstant; import com.bonus.common.core.utils.encryption.Sm3Util;
import com.bonus.common.core.utils.global.SystemGlobal;
import com.bonus.gateway.module.GatewayContext;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.lang.reflect.Field;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets;
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import java.util.Arrays;
import java.util.Collections;
/** import java.util.List;
* 参数自动解密 import java.util.Map;
* 拦截 import java.util.stream.Collectors;
* * @author bonus
*/
@Slf4j @Slf4j
@Component @Component
public class AecDecryptParamFilter extends AbstractGatewayFilterFactory { public class AecDecryptParamFilter extends AbstractGatewayFilterFactory {
@Value("${system.decryptEnabled}") @Value("${system.decryptEnabled}")
public boolean jaData; public boolean decryptEnabled;
public final static String HEARD_NAME = "decrypt"; public static final String HEADER_NAME = "decrypt";
public static final String HMAC_HEADER_NAME = "Params-Hash";
@Override @Override
public GatewayFilter apply(Object config) { public GatewayFilter apply(Object config) {
return (exchange, chain) -> { return (exchange, chain) -> {
ServerHttpRequest serverHttpRequest = exchange.getRequest(); if (!decryptEnabled) {
String head = serverHttpRequest.getHeaders().getFirst(HEARD_NAME); log.info("解密功能已禁用,直接继续过滤链。");
if (StringUtils.isNotEmpty(head) && HEARD_NAME.equals(head)) {
return chain.filter(exchange); return chain.filter(exchange);
} }
if (!jaData) {
return chain.filter(exchange);
}
//get请求 默认
if (HttpMethod.GET.matches(serverHttpRequest.getMethodValue())) {//如果是get
if (exchange.getRequest().getQueryParams().isEmpty()) {//如果参数是空的
return chain.filter(exchange);
} else {
try {
updateRequestParam(exchange);
return chain.filter(exchange);
} catch (Exception e) {
log.error(e.toString(), e);
return CommonConstant.buildResponse(exchange, HttpStatus.BAD_REQUEST.value(), "请求参数异常");
}
}
}
if (HttpMethod.DELETE.matches(serverHttpRequest.getMethodValue())) { ServerHttpRequest request = exchange.getRequest();
HttpMethod method = request.getMethod();
if (method == null) {
log.error("请求方法为 null无法处理请求。");
return chain.filter(exchange); return chain.filter(exchange);
} }
HttpHeaders heard = serverHttpRequest.getHeaders();
if (heard != null) {
Object object = heard.getFirst("Content-Type");
if (object != null) {
String contentType = object.toString();
if (contentType.contains(MULTIPART_FORM_DATA_VALUE)) {
return chain.filter(exchange);
}
}
}
byte[] decrypBytes;
GatewayContext gatewayContext = exchange.getAttribute(GatewayContext.CACHE_GATEWAY_CONTEXT);
if (StringUtils.isEmpty(gatewayContext.getCacheBody())) {
if (!exchange.getRequest().getQueryParams().isEmpty()) {
try { try {
updateRequestParam(exchange); if (method == HttpMethod.GET) {
return chain.filter(exchange); return handleGetRequest(exchange, chain);
}
return handleRequest(exchange, chain);
} catch (Exception e) { } catch (Exception e) {
log.error(e.toString(), e); log.error("处理请求时发生错误: {}", e.getMessage(), e);
return CommonConstant.buildResponse(exchange, HttpStatus.BAD_REQUEST.value(), "请输入正确的请求参数"); exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
} return exchange.getResponse().setComplete();
}
//强制加密
// return CommonConstant.buildResponse(exchange, HttpStatus.BAD_REQUEST.value(), "请求参数不正确!");
//未强制加密
return chain.filter(exchange);
}
try {
// 获取request body
String requestBody = gatewayContext.getCacheBody();
String decryptMsg = AesCbcUtils.decrypt(requestBody);
gatewayContext.setCacheBody(decryptMsg);
decrypBytes = decryptMsg.getBytes();
} catch (Exception e) {
log.error("数据 解密失败:{}", e);
return CommonConstant.buildResponse(exchange, 201, "请求参数不正确!");
}
// 根据解密后的参数重新构建请求
DataBufferFactory dataBufferFactory = exchange.getResponse().bufferFactory();
Flux<DataBuffer> bodyFlux = Flux.just(dataBufferFactory.wrap(decrypBytes));
ServerHttpRequest newRequest = serverHttpRequest.mutate().uri(serverHttpRequest.getURI()).build();
newRequest = new ServerHttpRequestDecorator(newRequest) {
@Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
} }
}; };
HttpHeaders headers = new HttpHeaders(); }
headers.putAll(exchange.getRequest().getHeaders());
// 由于修改了传递参数需要重新设置CONTENT_LENGTH长度是字节长度不是字符串长度 private Mono<Void> handleGetRequest(ServerWebExchange exchange, GatewayFilterChain chain) {
int length = decrypBytes.length; try {
headers.remove(HttpHeaders.CONTENT_LENGTH); ServerWebExchange updatedExchange = updateRequestParam(exchange);
headers.setContentLength(length); if (updatedExchange != null) {
newRequest = new ServerHttpRequestDecorator(newRequest) { return chain.filter(updatedExchange);
} else {
return chain.filter(exchange);
}
} catch (Exception e) {
log.error("处理 GET 请求时发生错误: {}", e.getMessage(), e);
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
return exchange.getResponse().setComplete();
}
}
private Mono<Void> handleRequest(ServerWebExchange exchange, GatewayFilterChain chain) {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
byte[] body = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(body);
DataBufferUtils.release(dataBuffer);
String requestBody = new String(body, StandardCharsets.UTF_8);
// 去掉多余的引号如果有
if (requestBody.startsWith("\"") && requestBody.endsWith("\"")) {
requestBody = requestBody.substring(1, requestBody.length() - 1);
}
String decryptedBody;
try {
String providedHmac = exchange.getRequest().getHeaders().getFirst(HMAC_HEADER_NAME);
integrityVerification(providedHmac, requestBody);
decryptedBody = AesCbcUtils.decrypt(requestBody);
} catch (Exception e) {
log.error("解密请求体时发生错误: {}", e.getMessage(), e);
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
return exchange.getResponse().setComplete();
}
DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory();
DataBuffer newBody = bufferFactory.wrap(decryptedBody.getBytes(StandardCharsets.UTF_8));
ServerHttpRequest newRequest = createNewRequest(exchange, newBody);
return chain.filter(exchange.mutate().request(newRequest).build());
});
}
private ServerHttpRequest createNewRequest(ServerWebExchange exchange, DataBuffer newBody) {
return new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return Flux.just(newBody);
}
@Override @Override
public HttpHeaders getHeaders() { public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.CONTENT_LENGTH);
headers.setContentLength(newBody.readableByteCount());
return headers; return headers;
} }
}; };
// 把解密后的数据重置到exchange自定义属性中,在之后的日志GlobalLogFilter从此处获取请求参数打印日志
exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT, gatewayContext);
return chain.filter(exchange.mutate().request(newRequest).build());
};
} }
private ServerWebExchange updateRequestParam(ServerWebExchange exchange) throws NoSuchFieldException, IllegalAccessException {
/**
* 修改前端传的参数
*/
private void updateRequestParam(ServerWebExchange exchange) throws NoSuchFieldException, IllegalAccessException {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
URI uri = request.getURI(); URI uri = request.getURI();
//请求参数
String query = uri.getQuery(); String query = uri.getQuery();
if (StringUtils.isNotBlank(query)) { if (StringUtils.isNotBlank(query)) {
//解密请求参数 String providedHmac = exchange.getRequest().getHeaders().getFirst(HMAC_HEADER_NAME);
String param = AesCbcUtils.decrypt(query); integrityVerification(providedHmac, query);
if (StringUtils.isEmpty(param)) { String decryptedParam;
try {
decryptedParam = AesCbcUtils.decrypt(query);
} catch (Exception e) {
log.error("解密查询参数时发生错误: {}", e.getMessage(), e);
throw new CaptchaException("请求参数不正确"); throw new CaptchaException("请求参数不正确");
} }
//使用反射强行拿出 URI query if (StringUtils.isEmpty(decryptedParam)) {
Field targetQuery = uri.getClass().getDeclaredField("query"); log.error("解密后的参数为空");
//授权 throw new CaptchaException("请求参数不正确");
targetQuery.setAccessible(true);
//重新设置参数
targetQuery.set(uri, param);
} }
Map<String, List<String>> queryParams = Arrays.stream(decryptedParam.split("&"))
.map(param -> param.split("="))
.collect(Collectors.toMap(
param -> param[0],
param -> Collections.singletonList(param[1])
));
URI newUri = UriComponentsBuilder.fromUri(uri)
.replaceQueryParams(CollectionUtils.toMultiValueMap(queryParams))
.build(true)
.toUri();
ServerHttpRequest newRequest = request.mutate().uri(newUri).build();
return exchange.mutate().request(newRequest).build();
}
return null;
} }
/**
* 数据完整性校验
*
* @param providedHmac 请求头中的 HMAC
* @param query 请求参数
*/
private void integrityVerification(String providedHmac, String query) {
if (providedHmac == null) {
log.error("请求头中缺少 Params-Hash");
throw new CaptchaException("请求参数不正确");
}
String encrypt = Sm3Util.encrypt(query);
log.debug("加密后的参数: {}", encrypt);
log.debug("请求头中的 Params-Hash: {}", providedHmac);
if (!encrypt.equals(providedHmac)) {
log.error("参数校验失败");
throw new CaptchaException("请求参数不正确");
}
}
} }

View File

@ -16,18 +16,16 @@ import com.bonus.common.core.utils.ServletUtils;
* @author bonus * @author bonus
*/ */
@Component @Component
public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> {
{
@Value("${system.encryptEnabled}") @Value("${system.encryptEnabled}")
public boolean encryptEnabled; public boolean encryptEnabled;
@Override @Override
public GatewayFilter apply(Config config) public GatewayFilter apply(Config config) {
{
return (exchange, chain) -> { return (exchange, chain) -> {
String url = exchange.getRequest().getURI().getPath(); String url = exchange.getRequest().getURI().getPath();
if (config.matchBlacklist(url)) if (config.matchBlacklist(url)) {
{
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问", encryptEnabled); return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问", encryptEnabled);
} }
@ -35,29 +33,24 @@ public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUr
}; };
} }
public BlackListUrlFilter() public BlackListUrlFilter() {
{
super(Config.class); super(Config.class);
} }
public static class Config public static class Config {
{
private List<String> blacklistUrl; private List<String> blacklistUrl;
private List<Pattern> blacklistUrlPattern = new ArrayList<>(); private List<Pattern> blacklistUrlPattern = new ArrayList<>();
public boolean matchBlacklist(String url) public boolean matchBlacklist(String url) {
{
return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find()); return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find());
} }
public List<String> getBlacklistUrl() public List<String> getBlacklistUrl() {
{
return blacklistUrl; return blacklistUrl;
} }
public void setBlacklistUrl(List<String> blacklistUrl) public void setBlacklistUrl(List<String> blacklistUrl) {
{
this.blacklistUrl = blacklistUrl; this.blacklistUrl = blacklistUrl;
this.blacklistUrlPattern.clear(); this.blacklistUrlPattern.clear();
this.blacklistUrl.forEach(url -> { this.blacklistUrl.forEach(url -> {

View File

@ -50,8 +50,7 @@ import com.bonus.system.service.ISysUserService;
*/ */
@RestController @RestController
@RequestMapping("/user") @RequestMapping("/user")
public class SysUserController extends BaseController public class SysUserController extends BaseController {
{
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@ -130,11 +129,9 @@ public class SysUserController extends BaseController
*/ */
@InnerAuth @InnerAuth
@GetMapping("/info/{username}") @GetMapping("/info/{username}")
public R<LoginUser> info(@PathVariable("username") String username) public R<LoginUser> info(@PathVariable("username") String username) {
{
SysUser sysUser = userService.selectUserByUserName(username); SysUser sysUser = userService.selectUserByUserName(username);
if (StringUtils.isNull(sysUser)) if (StringUtils.isNull(sysUser)) {
{
return R.fail("用户名或密码错误"); return R.fail("用户名或密码错误");
} }
// 角色集合 // 角色集合
@ -154,17 +151,14 @@ public class SysUserController extends BaseController
*/ */
@InnerAuth @InnerAuth
@PostMapping("/register") @PostMapping("/register")
public R<Boolean> register(@RequestBody SysUser sysUser) public R<Boolean> register(@RequestBody SysUser sysUser) {
{
String username = sysUser.getUserName(); String username = sysUser.getUserName();
final String stringTrue = "true"; final String stringTrue = "true";
final String configKeyRegisterUser = "sys.account.registerUser"; final String configKeyRegisterUser = "sys.account.registerUser";
if (!(stringTrue.equals(configService.selectConfigByKey(configKeyRegisterUser)))) if (!(stringTrue.equals(configService.selectConfigByKey(configKeyRegisterUser)))) {
{
return R.fail("当前系统没有开启注册功能!"); return R.fail("当前系统没有开启注册功能!");
} }
if (!userService.checkUserNameUnique(sysUser)) if (!userService.checkUserNameUnique(sysUser)) {
{
return R.fail("保存用户'" + username + "'失败,注册账号已存在"); return R.fail("保存用户'" + username + "'失败,注册账号已存在");
} }
return R.ok(userService.registerUser(sysUser)); return R.ok(userService.registerUser(sysUser));
@ -206,8 +200,7 @@ public class SysUserController extends BaseController
List<SysRole> roles = roleService.selectRoleAll(); List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", roles); ajax.put("roles", roles);
ajax.put("posts", postService.selectPostAll()); ajax.put("posts", postService.selectPostAll());
if (StringUtils.isNotNull(userId)) if (StringUtils.isNotNull(userId)) {
{
SysUser sysUser = userService.selectUserById(userId); SysUser sysUser = userService.selectUserById(userId);
ajax.put(AjaxResult.DATA_TAG, sysUser); ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId)); ajax.put("postIds", postService.selectPostListByUserId(userId));
@ -230,16 +223,11 @@ public class SysUserController extends BaseController
try { try {
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds()); roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user)) {
{
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
String pwd = ValidateUtils.isPwd(user.getPassword()); String pwd = ValidateUtils.isPwd(user.getPassword());
@ -267,16 +255,11 @@ public class SysUserController extends BaseController
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds()); roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user)) {
{
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setUpdateBy(SecurityUtils.getUsername()); user.setUpdateBy(SecurityUtils.getUsername());
@ -392,4 +375,18 @@ public class SysUserController extends BaseController
} }
return error("系统异常,请联系管理员"); return error("系统异常,请联系管理员");
} }
/**
* 修改用户审批状态
*/
@RequiresPermissions("system:user:approval")
@PostMapping("/approvalStatus")
public AjaxResult approvalStatus(@RequestBody SysUser user) {
try {
return success(userService.approvalStatus(user.getUserId()));
} catch (Exception e) {
logger.error(e.toString(), e);
}
return error("系统异常,请联系管理员");
}
} }

View File

@ -125,4 +125,6 @@ public interface SysUserMapper {
* @return 结果 * @return 结果
*/ */
public SysUser checkEmailUnique(String email); public SysUser checkEmailUnique(String email);
Integer approvalStatus(Long userId);
} }

View File

@ -1,7 +1,10 @@
package com.bonus.system.service; package com.bonus.system.service;
import java.util.List; import java.util.List;
import com.bonus.common.core.domain.R;
import com.bonus.system.api.domain.SysUser; import com.bonus.system.api.domain.SysUser;
import org.apache.poi.ss.formula.functions.T;
/** /**
* 用户 业务层 * 用户 业务层
@ -203,4 +206,6 @@ public interface ISysUserService
* @return 结果 * @return 结果
*/ */
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName); public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
R<T> approvalStatus(Long userId);
} }

View File

@ -5,6 +5,8 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.Validator; import javax.validation.Validator;
import com.bonus.common.core.domain.R;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -519,4 +521,23 @@ public class SysUserServiceImpl implements ISysUserService {
return successMsg.toString(); return successMsg.toString();
} }
/**
* @param userId
* @return
*/
@Override
public R<T> approvalStatus(Long userId) {
try {
Integer i = userMapper.approvalStatus(userId);
if (i > 0) {
return R.ok();
} else {
return R.fail();
}
} catch (Exception e) {
e.printStackTrace();
return R.fail();
}
}
} }

View File

@ -24,6 +24,7 @@
<result property="updateTime" column="update_time"/> <result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/> <result property="remark" column="remark"/>
<result property="loginType" column="login_type"/> <result property="loginType" column="login_type"/>
<result property="approvalStatus" column="approval_status"/>
<association property="dept" javaType="SysDept" resultMap="deptResult"/> <association property="dept" javaType="SysDept" resultMap="deptResult"/>
<collection property="roles" javaType="java.util.List" resultMap="RoleResult"/> <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
@ -87,7 +88,8 @@
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult"> <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status,
u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.approval_status, d.dept_name,
d.leader from sys_user
u u
left join sys_dept d on u.dept_id = d.dept_id left join sys_dept d on u.dept_id = d.dept_id
where u.del_flag = '0' where u.del_flag = '0'
@ -268,6 +270,12 @@
set password = #{password} set password = #{password}
where user_name = #{userName} where user_name = #{userName}
</update> </update>
<update id="approvalStatus">
update sys_user
set approval_status = '1',
status='0'
where user_id = #{userId}
</update>
<delete id="deleteUserById" parameterType="Long"> <delete id="deleteUserById" parameterType="Long">
update sys_user update sys_user