feat: remove aes/rsa encrypt
This commit is contained in:
@@ -1,51 +0,0 @@
|
|||||||
package com.schisandra.auth.application.controller;
|
|
||||||
|
|
||||||
import com.schisandra.auth.common.entity.Result;
|
|
||||||
import com.schisandra.auth.common.redis.RedisUtil;
|
|
||||||
import com.schisandra.auth.common.utils.MD5Util;
|
|
||||||
import com.schisandra.auth.common.utils.RSAUtils;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ClassName EncryptController
|
|
||||||
* @Description TODO
|
|
||||||
* @Author L
|
|
||||||
* @Date 2024/1/29 9:18
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/encrypt")
|
|
||||||
@Slf4j
|
|
||||||
public class EncryptController {
|
|
||||||
@Resource
|
|
||||||
private RedisUtil redisUtil;
|
|
||||||
private String authPublicKeyPrefix = "auth.publicKey";
|
|
||||||
private String authPrivateKeyPrefix = "auth.privateKey";
|
|
||||||
|
|
||||||
@GetMapping("/getPublicKey")
|
|
||||||
public Result getPublicKey() throws Exception {
|
|
||||||
//获取当前登陆账号对应的token,这行代码就不贴了。
|
|
||||||
String token="12345";
|
|
||||||
String publicKey="";
|
|
||||||
if (StringUtils.isNotBlank(token)) {
|
|
||||||
Map<String, String> stringStringMap = RSAUtils.genKeyPair();
|
|
||||||
publicKey = stringStringMap.get("publicKey");
|
|
||||||
String privateKey = stringStringMap.get("privateKey");
|
|
||||||
String md5Token = MD5Util.md5(token);
|
|
||||||
//这个地方的存放时间根据你的token存放时间走
|
|
||||||
redisUtil.set(md5Token + "publicKey", publicKey);
|
|
||||||
redisUtil.set(md5Token + "privateKey", privateKey);
|
|
||||||
return Result.ok(publicKey);
|
|
||||||
}
|
|
||||||
return Result.ok(publicKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@@ -1,100 +0,0 @@
|
|||||||
package com.schisandra.auth.application.filter;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.schisandra.auth.application.wrapper.EncryptRequestWrapper;
|
|
||||||
import com.schisandra.auth.application.wrapper.ResponseWrapper;
|
|
||||||
import com.schisandra.auth.common.entity.ApiEncryptRes;
|
|
||||||
import com.schisandra.auth.common.utils.ApiSecurityUtils;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.boot.web.servlet.filter.OrderedFilter;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class EncryptApiFilter extends OncePerRequestFilter implements OrderedFilter {
|
|
||||||
public static final int DEFAULT_ORDER = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
|
||||||
String servletPath = request.getServletPath();
|
|
||||||
|
|
||||||
ResponseWrapper wrapper = new ResponseWrapper(response);
|
|
||||||
String requestContent = null;
|
|
||||||
|
|
||||||
if (ServletUtil.isMultipart(request)) {
|
|
||||||
} else {
|
|
||||||
EncryptRequestWrapper encryptRequestWrapper = EncryptRequestWrapper.newOrGetMultiReadHttpServletRequest(request);
|
|
||||||
requestContent = encryptRequestWrapper.getBody();
|
|
||||||
request = encryptRequestWrapper;
|
|
||||||
|
|
||||||
}
|
|
||||||
log.debug("{}>>>{}", servletPath, requestContent);
|
|
||||||
|
|
||||||
try {
|
|
||||||
filterChain.doFilter(request, wrapper);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
process(request, wrapper, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("AesFilter error", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
protected void process(HttpServletRequest request, ResponseWrapper responseWrapper, HttpServletResponse response) {
|
|
||||||
|
|
||||||
String servletPath = request.getRequestURI();
|
|
||||||
String isencrypt = request.getHeader("Isencrypt");
|
|
||||||
ServletOutputStream out = response.getOutputStream();
|
|
||||||
if (ResponseWrapper.isJsonContentType(responseWrapper.getContentType())) {
|
|
||||||
String responseContent = responseWrapper.getTextContent();
|
|
||||||
if (StrUtil.isNotEmpty(responseContent)&&StringUtils.isNotBlank(isencrypt)) {
|
|
||||||
String JSPublicKey = ((EncryptRequestWrapper)request).getJSPublicKey();
|
|
||||||
if (StringUtils.isNotBlank(JSPublicKey)) {
|
|
||||||
ApiEncryptRes apiEncryptRes = ApiSecurityUtils.encrypt(JSON.toJSONString(responseContent), JSPublicKey);
|
|
||||||
responseContent = JSONUtil.toJsonStr(apiEncryptRes);
|
|
||||||
}
|
|
||||||
log.info("{}<<<{}", servletPath, responseContent);
|
|
||||||
byte[] bytes = responseContent.getBytes(StandardCharsets.UTF_8);
|
|
||||||
response.setContentLength(bytes.length);
|
|
||||||
out.write(bytes);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
} else {
|
|
||||||
responseWrapper.getByteArrayOutputStream().writeTo(out);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
responseWrapper.getByteArrayOutputStream().writeTo(out);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet() throws ServletException {
|
|
||||||
super.afterPropertiesSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return DEFAULT_ORDER;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,257 +0,0 @@
|
|||||||
package com.schisandra.auth.application.wrapper;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import com.schisandra.auth.common.redis.RedisUtil;
|
|
||||||
import com.schisandra.auth.common.utils.ApiSecurityUtils;
|
|
||||||
import com.schisandra.auth.common.utils.MD5Util;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.servlet.ReadListener;
|
|
||||||
import javax.servlet.ServletInputStream;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.io.FastByteArrayOutputStream;
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.core.lang.Assert;
|
|
||||||
import cn.hutool.http.ContentType;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
|
||||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
|
||||||
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
|
|
||||||
import org.springframework.web.util.WebUtils;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ClassName requestWrapper
|
|
||||||
* @Description TODO
|
|
||||||
* @Author landaiqing
|
|
||||||
* @Date 2024/1/31 17:58
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确保request可以多次读取
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class EncryptRequestWrapper extends HttpServletRequestWrapper {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//2024-02-02由于在过滤器中无法直接通过Autowired获取Bean,因此需要通过spring上下文来获取IOC管理的实体类
|
|
||||||
// @Autowired
|
|
||||||
// private RedisUtil redisUtil;
|
|
||||||
|
|
||||||
protected FastByteArrayOutputStream cachedContent;
|
|
||||||
protected String JSPublicKey;
|
|
||||||
protected EncryptRequestWrapper(HttpServletRequest request ) {
|
|
||||||
|
|
||||||
super(request);
|
|
||||||
RedisUtil redisUtils =getBean(RedisUtil.class, request);
|
|
||||||
this.copyBody(redisUtils);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 此处主要是用于读取 RedisUtil
|
|
||||||
* @param clazz
|
|
||||||
* @param request
|
|
||||||
* @param <T>
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public <T> T getBean(Class<T> clazz, HttpServletRequest request){
|
|
||||||
WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
|
|
||||||
return applicationContext.getBean(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EncryptRequestWrapper newOrGetMultiReadHttpServletRequest(HttpServletRequest request) {
|
|
||||||
EncryptRequestWrapper multiReadHttpServletRequest = getMultiReadHttpServletRequest(request);
|
|
||||||
if (null != multiReadHttpServletRequest) {
|
|
||||||
return multiReadHttpServletRequest;
|
|
||||||
} else {
|
|
||||||
String contentType = request.getContentType();
|
|
||||||
if (contentType != null && contentType.contains(ContentType.MULTIPART.getValue())) {
|
|
||||||
// 将转化后的 request 放入过滤链中
|
|
||||||
request = new StandardServletMultipartResolver().resolveMultipart(request);
|
|
||||||
}
|
|
||||||
return new EncryptRequestWrapper(request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EncryptRequestWrapper getMultiReadHttpServletRequest(HttpServletRequest request) {
|
|
||||||
EncryptRequestWrapper nativeRequest = WebUtils.getNativeRequest(request, EncryptRequestWrapper.class);
|
|
||||||
if (null != nativeRequest) {
|
|
||||||
return nativeRequest;
|
|
||||||
} else if (request instanceof EncryptRequestWrapper) {
|
|
||||||
return (EncryptRequestWrapper) request;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//重新读取请求,因为request只可以被读取一次,需要重新设置为可多次读取
|
|
||||||
@SneakyThrows
|
|
||||||
protected void copyBody(RedisUtil redisUtils) {
|
|
||||||
int length = this.getContentLength();
|
|
||||||
if (length > 0) {
|
|
||||||
cachedContent = IoUtil.read(getRequest().getInputStream());
|
|
||||||
if (StringUtils.isNotBlank(this.getHeader("Isencrypt"))&&StringUtils.isNotBlank(this.getHeader("X-Access-Token"))) {
|
|
||||||
String body = new String(cachedContent.toByteArray());
|
|
||||||
log.info("------------------- body = " + body + "------------------------");
|
|
||||||
if (StringUtils.isNotBlank(body)) {
|
|
||||||
JSONObject jsonBody = JSONObject.parseObject(body);
|
|
||||||
if(null != jsonBody){
|
|
||||||
String dataEncrypt = jsonBody.getString("data");
|
|
||||||
String aeskey = jsonBody.getString("aeskey");
|
|
||||||
JSPublicKey = jsonBody.getString("frontPublicKey");
|
|
||||||
String data;
|
|
||||||
JSONObject json = null;
|
|
||||||
log.info("------------------- dataEncrypt = " + dataEncrypt + "------------------------");
|
|
||||||
log.info("------------------- aesKey = " + aeskey + "------------------------");
|
|
||||||
String token = this.getHeader("X-Access-Token");
|
|
||||||
String md5Token = MD5Util.md5(token);
|
|
||||||
String privateKey = Convert.toStr(redisUtils.get(md5Token + "privateKey"));
|
|
||||||
data = ApiSecurityUtils.decrypt(aeskey, dataEncrypt,privateKey);
|
|
||||||
// 如果数据不为空就编译
|
|
||||||
if (StringUtils.isNotBlank(data)) {
|
|
||||||
//如果参数为空前端传回undefined
|
|
||||||
if ("undefined".equalsIgnoreCase(data)) {
|
|
||||||
json = new JSONObject();
|
|
||||||
} else {
|
|
||||||
json = JSONObject.parseObject(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json != null) {
|
|
||||||
body = json.toJSONString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.info("------------------- body = " + body + "------------------------");
|
|
||||||
cachedContent.reset();
|
|
||||||
cachedContent.write( body.getBytes(), 0, body.getBytes().length);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cachedContent = new FastByteArrayOutputStream();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getContentLength() {
|
|
||||||
if (null != cachedContent) {
|
|
||||||
return cachedContent.size();
|
|
||||||
}
|
|
||||||
return super.getContentLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getByteArrayBody() {
|
|
||||||
return cachedContent.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBody() {
|
|
||||||
String body = null;
|
|
||||||
if (cachedContent != null && cachedContent.size() > 0) {
|
|
||||||
body = new String(cachedContent.toByteArray());
|
|
||||||
}
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSortBody() {
|
|
||||||
return JSONObject.toJSONString(this.getBody(TreeMap.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T getBody(Class<T> type) {
|
|
||||||
return cn.hutool.json.JSONUtil.toBean(this.getBody(), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
//这个方法为获取前端给后端用于加密aeskey的rsa公钥
|
|
||||||
public String getJSPublicKey(){
|
|
||||||
return JSPublicKey;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public BufferedReader getReader() throws IOException {
|
|
||||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServletInputStream getInputStream() throws IOException {
|
|
||||||
if (this.getContentLength() < 1) {
|
|
||||||
return super.getInputStream();
|
|
||||||
}
|
|
||||||
return new ResettableServletInputStream(new ByteArrayInputStream(cachedContent.toByteArray()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ResettableServletInputStream extends ServletInputStream {
|
|
||||||
|
|
||||||
private final InputStream sourceStream;
|
|
||||||
|
|
||||||
private boolean finished = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a DelegatingServletInputStream for the given source stream.
|
|
||||||
*
|
|
||||||
* @param sourceStream the source stream (never {@code null})
|
|
||||||
*/
|
|
||||||
public ResettableServletInputStream(InputStream sourceStream) {
|
|
||||||
Assert.notNull(sourceStream, "Source InputStream must not be null");
|
|
||||||
this.sourceStream = sourceStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the underlying source stream (never {@code null}).
|
|
||||||
*/
|
|
||||||
public final InputStream getSourceStream() {
|
|
||||||
return this.sourceStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int read() throws IOException {
|
|
||||||
int data = this.sourceStream.read();
|
|
||||||
if (data == -1) {
|
|
||||||
this.finished = true;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int available() throws IOException {
|
|
||||||
return this.sourceStream.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
super.close();
|
|
||||||
this.sourceStream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFinished() {
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReady() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setReadListener(ReadListener readListener) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@@ -1,114 +0,0 @@
|
|||||||
package com.schisandra.auth.application.wrapper;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.WriteListener;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpServletResponseWrapper;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
/** * 返回值输出代理类
|
|
||||||
* @ClassName ResponseWrapper
|
|
||||||
* @Description TODO
|
|
||||||
* @Author L
|
|
||||||
* @Date 2024/1/31 18:58
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class ResponseWrapper extends HttpServletResponseWrapper {
|
|
||||||
ByteArrayOutputStream _stream = new ByteArrayOutputStream();
|
|
||||||
PrintWriter _pw = new PrintWriter(_stream);
|
|
||||||
|
|
||||||
public ResponseWrapper(HttpServletResponse resp) throws IOException {
|
|
||||||
super(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 覆盖getWriter()方法,将字符流缓冲到本地
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public PrintWriter getWriter() throws IOException {
|
|
||||||
return _pw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 覆盖getOutputStream()方法,将字节流缓冲到本地
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ServletOutputStream getOutputStream() throws IOException {
|
|
||||||
return new ServletOutputStream() {
|
|
||||||
@Override
|
|
||||||
public boolean isReady() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWriteListener(WriteListener writeListener) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(int b) throws IOException {
|
|
||||||
_stream.write(b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 把缓冲区内容写入输出流后关闭
|
|
||||||
*
|
|
||||||
* @author xxj
|
|
||||||
*/
|
|
||||||
public void flush() {
|
|
||||||
try {
|
|
||||||
_pw.flush();
|
|
||||||
_pw.close();
|
|
||||||
_stream.flush();
|
|
||||||
_stream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字节流
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public ByteArrayOutputStream getByteArrayOutputStream() {
|
|
||||||
return _stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将换出区内容转为文本输出
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getTextContent() {
|
|
||||||
flush();
|
|
||||||
return _stream.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isTextContentType(String contentType) {
|
|
||||||
boolean flag = false;
|
|
||||||
if (StrUtil.isBlank(contentType)) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
flag = StrUtil.startWithIgnoreCase(contentType, "text");
|
|
||||||
if (!flag) {
|
|
||||||
flag = isJsonContentType(contentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJsonContentType(String contentType) {
|
|
||||||
return !StrUtil.isBlank(contentType)
|
|
||||||
&& (StrUtil.containsIgnoreCase(contentType, "application/problem+json")
|
|
||||||
|| StrUtil.containsIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE));
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user