登录会话拦截优化

This commit is contained in:
暮光:城中城
2021-11-23 22:30:25 +08:00
parent 80d525b735
commit b32c9a8f9e
12 changed files with 152 additions and 348 deletions

View File

@@ -3,8 +3,7 @@ package com.zyplayer.doc.manage.framework.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.zyplayer.doc.data.config.DocLoginOriginInterceptor;
import com.zyplayer.doc.manage.framework.interceptor.RequestInfoInterceptor;
import com.zyplayer.doc.manage.framework.interceptor.UserLoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
@@ -13,11 +12,11 @@ import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@@ -25,12 +24,10 @@ import java.util.List;
@Component
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Resource
RequestInfoInterceptor requestInfoInterceptor;
@Resource
DocLoginOriginInterceptor docLoginOriginInterceptor;
UserLoginInterceptor userLoginInterceptor;
@Override
public void addFormatters(FormatterRegistry registry) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -40,12 +37,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
dateFormatter.setLenient(true);
registry.addFormatter(dateFormatter);
}
@Bean
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(new MediaType("application", "json", Charset.forName("UTF-8")));
supportedMediaTypes.add(new MediaType("application", "json", StandardCharsets.UTF_8));
fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat);
@@ -57,12 +54,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, fastJsonHttpMessageConverter());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(docLoginOriginInterceptor);
registry.addInterceptor(requestInfoInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png",
"/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
registry.addInterceptor(userLoginInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png", "/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
}
}

View File

@@ -1,38 +0,0 @@
package com.zyplayer.doc.manage.framework.interceptor;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
/**
* 所有bean初始化后执行bean初始化了再初始化一些自己的东西
*/
@Component
public class InitServletContextAware implements InitializingBean,ServletContextAware {
private ServletContext context;
@Override
public void setServletContext(ServletContext context) {
this.context = context;
}
@Override
public void afterPropertiesSet() throws Exception {
ctx();
}
private void ctx(){
String ctx = context.getContextPath();
if (ctx != null && ctx.trim().length() > 0 && !ctx.trim().equals("/")) {
context.setAttribute("ctx", ctx+"/");
context.setAttribute("statics", ctx+"/statics/");
} else {
context.setAttribute("ctx", "/");
context.setAttribute("statics", "/statics/");
}
}
}

View File

@@ -1,55 +0,0 @@
package com.zyplayer.doc.manage.framework.interceptor;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.server.HttpServerRequest;
import com.zyplayer.doc.core.util.ThreadLocalUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
/**
* 记录当前请求信息
*/
@Component
public class RequestInfoInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(RequestInfoInterceptor.class);
private ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
/**
* 把当前请求记录到下来
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
Long startTime = startTimeThreadLocal.get();
startTime = Optional.ofNullable(startTime).orElse(System.currentTimeMillis());
long totalTime = System.currentTimeMillis() - startTime;// 结束时间
String clientIP = ServletUtil.getClientIP(request);
logger.info("IP{},总耗时:{}msURI{}", clientIP, totalTime, request.getRequestURI());
ThreadLocalUtil.clean();
startTimeThreadLocal.remove();
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object haddler, ModelAndView modelAndView) {
}
/**
* 记录请求信息
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
response.setContentType("application/json; charset=utf-8"); // 设定JSON格式标准输出、及编码
startTimeThreadLocal.set(System.currentTimeMillis());
ThreadLocalUtil.setHttpServletRequest(request);
return true;
}
}

View File

@@ -0,0 +1,101 @@
package com.zyplayer.doc.manage.framework.interceptor;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.core.json.HttpConst;
import com.zyplayer.doc.core.util.ThreadLocalUtil;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import org.apache.catalina.util.RequestUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
/**
* 用户登录拦截
*/
@Component
public class UserLoginInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(UserLoginInterceptor.class);
@Value("${zyplayer.doc.manage.originDomainRegex:}")
private String originDomainRegex;
private final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
Long startTime = startTimeThreadLocal.get();
startTime = Optional.ofNullable(startTime).orElse(System.currentTimeMillis());
long totalTime = System.currentTimeMillis() - startTime;
String clientIP = ServletUtil.getClientIP(request);
logger.info("IP{},总耗时:{}msURI{}", clientIP, totalTime, request.getRequestURI());
ThreadLocalUtil.clean();
startTimeThreadLocal.remove();
// 清理用户信息
DocUserUtil.clean();
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
startTimeThreadLocal.set(System.currentTimeMillis());
ThreadLocalUtil.setHttpServletRequest(request);
// 指定域名可跨域访问
if (StringUtils.isNotBlank(originDomainRegex)) {
String origin = request.getHeader("Origin");
if (StringUtils.isNotBlank(origin) && origin.toLowerCase().matches(originDomainRegex)) {
response.setHeader("Access-Control-Allow-Origin", origin); // 允许访问的域
response.setHeader("Access-Control-Allow-Methods", "HEAD,GET,POST,PUT,DELETE");// 允许GET、POST的外域请求
response.setHeader("Access-Control-Allow-Credentials", "true"); // 允许请求带cookie到服务器
response.setContentType("application/json; charset=utf-8"); // 设定JSON格式标准输出、及编码
}
}
if (!(handler instanceof HandlerMethod)) {
return true;
}
// 清理用户信息
DocUserUtil.clean();
// 设置token
Cookie cookie = ServletUtil.getCookie(request, HttpConst.ACCESS_TOKEN);
String accessToken = (cookie == null) ? null : cookie.getValue();
DocUserUtil.setAccessToken(accessToken);
AuthMan authMan = ((HandlerMethod) handler).getMethod().getAnnotation(AuthMan.class);
if (authMan == null) {
authMan = ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(AuthMan.class);
if (authMan == null) {
return true;
}
}
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
if (currentUser == null) {
String reason = "你访问的内容需要登录,请登录后再试";
DocResponseJson.failure(HttpConst.TOKEN_TIMEOUT, reason).send(response);
return false;
}
// 判断权限是否足够
boolean haveAuth = DocUserUtil.haveAuth(authMan.value());
if (haveAuth) {
return true;
}
String reasonStr = "没有操作权限,请联系管理员";
DocResponseJson.warn(reasonStr).send(response);
return false;
}
}