Compare commits

...

2 Commits

Author SHA1 Message Date
soul2 077751021e 修复解密问题 1 year ago
soul2 7e63ad937d 尝试修复 失败次数1 1 year ago
  1. 2
      src/main/java/cn/soul2/jyjc/admin/JavaJyjcAdminApplication.java
  2. 4
      src/main/java/cn/soul2/jyjc/admin/bean/UserLoginStatusBean.java
  3. 28
      src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java
  4. 45
      src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java
  5. 1
      src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java
  6. 16
      src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java
  7. 84
      src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java
  8. 2
      src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java
  9. 2
      src/main/resources/application-cors.yml

@ -3,7 +3,6 @@ package cn.soul2.jyjc.admin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* @author Soul2
@ -11,7 +10,6 @@ import org.springframework.context.annotation.ComponentScan;
*/
@SpringBootApplication
@MapperScan("cn.soul2.jyjc.admin.mapper")
@ComponentScan("cn.soul2.jyjc.admin.config")
public class JavaJyjcAdminApplication {
public static void main(String[] args) {

@ -1,4 +1,4 @@
package cn.soul2.jyjc.admin.config;
package cn.soul2.jyjc.admin.bean;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import org.apache.commons.lang3.StringUtils;
@ -80,7 +80,7 @@ public class UserLoginStatusBean {
return Boolean.FALSE;
}
UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null);
if (loginStatus.getLapseTime() != null) {
if (loginStatus != null && loginStatus.getLapseTime() != null) {
LocalDateTime now = LocalDateTime.now();
if (now.isAfter(loginStatus.getLapseTime())) {
logout(token);

@ -1,28 +0,0 @@
package cn.soul2.jyjc.admin.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author Soul2
* @date 2024-03-25
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Value("${cors.allow-origin}")
private String[] allowOrigin;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedOrigins(allowOrigin)
.allowCredentials(true)
.allowedMethods("POST")
.maxAge(3600);
}
}

@ -1,7 +1,12 @@
package cn.soul2.jyjc.admin.config;
import cn.soul2.jyjc.admin.interceptor.FinallyInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -15,9 +20,47 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Value("${cors.allow-origin}")
private String[] allowOrigin;
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置允许跨域请求的域名
for (String url : allowOrigin) {
config.addAllowedOrigin(url);
}
// 是否允许证书 不再默认开启
// config.setAllowCredentials(true);
// 设置允许的方法
config.addAllowedMethod("*");
// 允许任何头
config.addAllowedHeader("*");
config.addExposedHeader("token");
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedHeaders("*")
// .allowedOrigins(allowOrigin)
// .allowCredentials(true)
// .allowedMethods("POST")
// .maxAge(3600);
// }
@Bean
FinallyInterceptor createFinallyInterceptor() {
return new FinallyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FinallyInterceptor())
registry.addInterceptor(createFinallyInterceptor())
// 拦截所有路径
.addPathPatterns("/**");
}

@ -27,6 +27,7 @@ public class ReplaceStreamFilter implements Filter {
return;
} else {
ServletRequest requestWrapper = new ShaoduoRequestWrapper((HttpServletRequest) request);
// System.out.printf("ReplaceStreamFilter触发, Method: %s, URI: %s%n", ((HttpServletRequest) request).getMethod(), ((HttpServletRequest) request).getRequestURI());
chain.doFilter(requestWrapper, response);
return;
}

@ -14,7 +14,7 @@ import java.nio.charset.StandardCharsets;
/**
* @author shaoduo
* @description 包装HttpServletRequest目的是让其输入流可重复读
* @since 1.0
* @since <a href="https://blog.csdn.net/shaoduo/article/details/122322578">shaoduo</a>
**/
@Slf4j
public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
@ -23,7 +23,7 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
*/
private byte[] body;
public ShaoduoRequestWrapper(HttpServletRequest request) throws IOException {
public ShaoduoRequestWrapper(HttpServletRequest request) {
super(request);
// 将body数据存储起来
@ -51,9 +51,8 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
*
* @return String
*/
public String getBodyString() {
public String getBodyString() throws IOException {
InputStream inputStream = new ByteArrayInputStream(body);
return inputStream2String(inputStream);
}
@ -63,7 +62,6 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
* @param val
*/
public void setBody(String val) {
body = val.getBytes(StandardCharsets.UTF_8);
}
@ -73,7 +71,7 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
* @param inputStream inputStream
* @return String
*/
private String inputStream2String(InputStream inputStream) {
private String inputStream2String(InputStream inputStream) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
@ -95,8 +93,6 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
}
}
}
return sb.toString();
}
@ -106,13 +102,13 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
}
@Override
public ServletInputStream getInputStream() throws IOException {
public ServletInputStream getInputStream() {
final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
public int read() {
return inputStream.read();
}

@ -2,22 +2,21 @@ package cn.soul2.jyjc.admin.interceptor;
import cn.soul2.jyjc.admin.annotation.SkinEncrypt;
import cn.soul2.jyjc.admin.annotation.SkinLogin;
import cn.soul2.jyjc.admin.config.UserLoginStatusBean;
import cn.soul2.jyjc.admin.bean.UserLoginStatusBean;
import cn.soul2.jyjc.admin.filter.ShaoduoRequestWrapper;
import cn.soul2.jyjc.admin.utils.EncryptUtils;
import cn.soul2.jyjc.admin.vo.base.Back;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
/**
@ -29,18 +28,14 @@ import java.lang.reflect.Method;
@Slf4j
public class FinallyInterceptor implements HandlerInterceptor {
@Autowired
@Lazy
private ApplicationContext context;
@Resource
@Lazy
private UserLoginStatusBean userLoginStatusBean;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
boolean pass = false;
// 允许OPTIONS请求通过
if ("OPTIONS".equals(request.getMethod()) && request.getHeader("Origin") != null) {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
return true;
}
// 如果不是映射到方法直接通过
@ -68,60 +63,63 @@ public class FinallyInterceptor implements HandlerInterceptor {
if (request.getContentType() == null) {
pass = true;
}
// 如果类型不是json 就放行
if (!(request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE))) {
pass = true;
}
}
// 跳过使用SkinEncrypt注解的情况
// 跳过使用 @SkinEncrypt 的情况
if (skinEncrypt != null) {
pass = true;
}
ShaoduoRequestWrapper shaoduoRequestWrapper;
if (request instanceof ShaoduoRequestWrapper) {
shaoduoRequestWrapper = (ShaoduoRequestWrapper) request;
} else {
shaoduoRequestWrapper = new ShaoduoRequestWrapper(request);
request = shaoduoRequestWrapper;
}
String jsonParamBody = shaoduoRequestWrapper.getBodyString();
JSONObject obj = JSON.parseObject(EncryptUtils.decrypt(jsonParamBody));
String afterBody = JSONObject.toJSONString(obj);
System.out.println("加密前 " + jsonParamBody);
System.out.println("解密后 " + afterBody);
shaoduoRequestWrapper.setBody(afterBody);
String temp = new ShaoduoRequestWrapper(shaoduoRequestWrapper).getBodyString();
System.out.println("过滤器中缓存 " + temp);
if (!pass) {
ShaoduoRequestWrapper shaoduoRequestWrapper;
try {
shaoduoRequestWrapper = (ShaoduoRequestWrapper) request;
} catch (Exception e) {
System.out.printf("request.ClassTypeError: %s%n", request.getClass().getName());
return true;
}
String sourceParamBody = shaoduoRequestWrapper.getBodyString();
JSONObject obj = JSON.parseObject(EncryptUtils.decrypt(sourceParamBody));
String afterBody = JSONObject.toJSONString(obj);
shaoduoRequestWrapper.setBody(afterBody);
log.info(String.format("解密: %s -> %s", sourceParamBody, afterBody));
/*
token验证
*/
}
/* token验证 */
if (hasSkinLogin) {
// 如果存在,绕过拦截器
// 跳过使用 @SkinLogin 的情况
pass = true;
} else {
// 验证token
if (userLoginStatusBean == null) {
userLoginStatusBean = context.getBean(UserLoginStatusBean.class);
}
// 检查 token 是否存在并且有效
if (token == null) {
// 没有Token,拒绝请求
response.setStatus(40401);
pass = false;
} else if (userLoginStatusBean != null && !userLoginStatusBean.containsToken(token)) {
// Token 无效,拒绝请求,可以返回特定的响应状态码,例如 401 Unauthorized
response.setStatus(40401);
pass = false;
} else if (userLoginStatusBean != null) {
if (!userLoginStatusBean.containsToken(token)) {
// Token 无效,拒绝请求
response.setStatus(0);
Back<String> back = new Back<String>().setCode(40401).setMessage("Token invalid!");
// 转换为 JSON 字符串
ObjectMapper objectMapper = new ObjectMapper();
String responseBody = objectMapper.writeValueAsString(back);
// 输出错误信息到响应中
PrintWriter writer = response.getWriter();
writer.print(responseBody);
writer.flush();
pass = false;
} else {
// token存在, 通过拦截器
pass = true;
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return pass;
}

@ -1,6 +1,6 @@
package cn.soul2.jyjc.admin.repository.impl;
import cn.soul2.jyjc.admin.config.UserLoginStatusBean;
import cn.soul2.jyjc.admin.bean.UserLoginStatusBean;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;

@ -1,7 +1,7 @@
# 允许跨域的地址
cors:
allow-origin: http://localhost
allow-origin: http://localhost:6100, http://localhost:7620
---
spring:

Loading…
Cancel
Save