perf: 优化社区版token机制

This commit is contained in:
fit2cloud-chenyw 2024-09-30 15:47:38 +08:00
parent 631da3aee4
commit b3bb62b123
4 changed files with 92 additions and 79 deletions

View File

@ -0,0 +1,79 @@
package io.dataease.auth.filter;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import io.dataease.auth.bo.TokenUserBO;
import io.dataease.auth.config.SubstituleLoginConfig;
import io.dataease.license.utils.LicenseUtil;
import io.dataease.utils.*;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ReflectionUtils;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
public class CommunityTokenFilter implements Filter {
private static final String headName = "DE-GATEWAY-FLAG";
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
Long userId = null;
String token = ServletUtils.getToken();
TokenUserBO userBO = null;
if (StringUtils.isNotBlank(token) && ObjectUtils.isNotEmpty(userBO = AuthUtils.getUser()) && ObjectUtils.isNotEmpty(userId = userBO.getUserId()) && !LicenseUtil.licenseValid()) {
String secret = null;
if (ObjectUtils.isEmpty(CommonBeanFactory.getBean("loginServer"))) {
String pwd = SubstituleLoginConfig.getPwd();
secret = Md5Utils.md5(pwd);
} else {
Object apisixTokenManage = CommonBeanFactory.getBean("apisixTokenManage");
Method method = DeReflectUtil.findMethod(apisixTokenManage.getClass(), "userCacheBO");
Object o = ReflectionUtils.invokeMethod(method, apisixTokenManage, userId);
Method pwdMethod = DeReflectUtil.findMethod(o.getClass(), "getPwd");
Object pwdObj = ReflectionUtils.invokeMethod(pwdMethod, o);
secret = pwdObj.toString();
}
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
Verification verification = JWT.require(algorithm).withClaim("uid", userId).withClaim("oid", userBO.getDefaultOid());
JWTVerifier verifier = verification.build();
DecodedJWT decode = JWT.decode(token);
algorithm.verify(decode);
verifier.verify(token);
} catch (Exception e) {
HttpServletResponse res = (HttpServletResponse) servletResponse;
LogUtil.error(e.getMessage(), e);
HttpHeaders headers = new HttpHeaders();
String msg = URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8).replace("+", "%20");
headers.add(headName, msg);
sendResponseEntity(res, new ResponseEntity<>(e.getMessage(), headers, HttpStatus.UNAUTHORIZED));
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
private void sendResponseEntity(HttpServletResponse httpResponse, ResponseEntity<String> responseEntity) throws IOException {
HttpHeaders headers = responseEntity.getHeaders();
HttpStatusCode statusCode = responseEntity.getStatusCode();
httpResponse.setStatus(statusCode.value());
for (String name : headers.keySet()) {
httpResponse.setHeader(name, headers.getFirst(name));
}
httpResponse.getWriter().write(Objects.requireNonNull(responseEntity.getBody()));
}
}

View File

@ -16,4 +16,14 @@ public class FilterConfig {
filter.setOrder(0); filter.setOrder(0);
return filter; return filter;
} }
@Bean
public FilterRegistrationBean communityFilter() {
FilterRegistrationBean filter = new FilterRegistrationBean<>();
filter.setName("communityTokenFilter");
filter.setFilter(new CommunityTokenFilter());
filter.addUrlPatterns("/*");
filter.setOrder(5);
return filter;
}
} }

View File

@ -3,28 +3,15 @@ package io.dataease.auth.filter;
import io.dataease.auth.bo.TokenUserBO; import io.dataease.auth.bo.TokenUserBO;
import io.dataease.constant.AuthConstant; import io.dataease.constant.AuthConstant;
import io.dataease.utils.*; import io.dataease.utils.*;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.*; import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects; import java.util.Objects;
public class TokenFilter implements Filter { public class TokenFilter implements Filter {
private static final String headName = "DE-GATEWAY-FLAG";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
@ -57,41 +44,9 @@ public class TokenFilter implements Filter {
return; return;
} }
String token = ServletUtils.getToken(); String token = ServletUtils.getToken();
TokenUserBO userBO = null; TokenUserBO userBO = TokenUtils.validate(token);
try {
userBO = TokenUtils.validate(token);
UserUtils.setUserInfo(userBO); UserUtils.setUserInfo(userBO);
} catch (Exception e) {
HttpServletResponse res = (HttpServletResponse) servletResponse;
LogUtil.error(e.getMessage(), e);
HttpHeaders headers = new HttpHeaders();
String msg = URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8).replace("+", "%20");
headers.add(headName, msg);
sendResponseEntity(res, new ResponseEntity<>(e.getMessage(), headers, HttpStatus.UNAUTHORIZED));
return;
}
filterChain.doFilter(servletRequest, servletResponse); filterChain.doFilter(servletRequest, servletResponse);
} }
@Override
public void destroy() {
}
private void sendResponseEntity(HttpServletResponse httpResponse, ResponseEntity<String> responseEntity) throws IOException {
HttpHeaders headers = responseEntity.getHeaders();
HttpStatusCode statusCode = responseEntity.getStatusCode();
// 设置状态码
httpResponse.setStatus(statusCode.value());
// 设置响应头
if (headers != null) {
for (String name : headers.keySet()) {
httpResponse.setHeader(name, headers.getFirst(name));
}
}
// 设置响应体
httpResponse.getWriter().write(responseEntity.getBody());
}
} }

View File

@ -1,19 +1,11 @@
package io.dataease.utils; package io.dataease.utils;
import com.auth0.jwt.JWT; import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import io.dataease.auth.bo.TokenUserBO; import io.dataease.auth.bo.TokenUserBO;
import io.dataease.auth.config.SubstituleLoginConfig;
import io.dataease.exception.DEException; import io.dataease.exception.DEException;
import io.dataease.license.utils.LicenseUtil;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
public class TokenUtils { public class TokenUtils {
@ -36,30 +28,7 @@ public class TokenUtils {
if (StringUtils.length(token) < 100) { if (StringUtils.length(token) < 100) {
DEException.throwException("token is invalid"); DEException.throwException("token is invalid");
} }
TokenUserBO userBO = userBOByToken(token); return userBOByToken(token);
if (ObjectUtils.isEmpty(userBO) || LicenseUtil.licenseValid()) {
return userBO;
}
Long userId = userBO.getUserId();
String secret = null;
if (ObjectUtils.isEmpty(CommonBeanFactory.getBean("loginServer"))) {
String pwd = SubstituleLoginConfig.getPwd();
secret = Md5Utils.md5(pwd);
} else {
Object apisixTokenManage = CommonBeanFactory.getBean("apisixTokenManage");
Method method = DeReflectUtil.findMethod(apisixTokenManage.getClass(), "userCacheBO");
Object o = ReflectionUtils.invokeMethod(method, apisixTokenManage, userId);
Method pwdMethod = DeReflectUtil.findMethod(o.getClass(), "getPwd");
Object pwdObj = ReflectionUtils.invokeMethod(pwdMethod, o);
secret = pwdObj.toString();
}
Algorithm algorithm = Algorithm.HMAC256(secret);
Verification verification = JWT.require(algorithm).withClaim("uid", userId).withClaim("oid", userBO.getDefaultOid());
JWTVerifier verifier = verification.build();
DecodedJWT decode = JWT.decode(token);
algorithm.verify(decode);
verifier.verify(token);
return userBO;
} }