登录会话拦截优化
This commit is contained in:
10
pom.xml
10
pom.xml
@@ -145,16 +145,6 @@
|
|||||||
<artifactId>freemarker</artifactId>
|
<artifactId>freemarker</artifactId>
|
||||||
<version>2.3.28</version>
|
<version>2.3.28</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
<version>1.9.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjtools</artifactId>
|
|
||||||
<version>1.9.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.zyplayer.doc.core.json;
|
package com.zyplayer.doc.core.json;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@@ -20,9 +21,11 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public class DocResponseJson<T> implements ResponseJson<T> {
|
public class DocResponseJson<T> implements ResponseJson<T> {
|
||||||
private static SerializeConfig mapping = new SerializeConfig();
|
private static SerializeConfig mapping = new SerializeConfig();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiModelProperty(value = "状态码")
|
@ApiModelProperty(value = "状态码")
|
||||||
private Integer errCode;
|
private Integer errCode;
|
||||||
@ApiModelProperty(value = "返回值说明")
|
@ApiModelProperty(value = "返回值说明")
|
||||||
@@ -37,46 +40,46 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
private Integer pageSize;
|
private Integer pageSize;
|
||||||
@ApiModelProperty(value = "总页数")
|
@ApiModelProperty(value = "总页数")
|
||||||
private Integer totalPage;
|
private Integer totalPage;
|
||||||
|
|
||||||
public DocResponseJson() {
|
public DocResponseJson() {
|
||||||
this.errCode = 200;
|
this.errCode = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocResponseJson(Object data) {
|
public DocResponseJson(Object data) {
|
||||||
this.setData(data);
|
this.setData(data);
|
||||||
this.errCode = 200;
|
this.errCode = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocResponseJson(int errCode, String errMsg) {
|
public DocResponseJson(int errCode, String errMsg) {
|
||||||
super();
|
super();
|
||||||
this.errCode = errCode;
|
this.errCode = errCode;
|
||||||
this.errMsg = errMsg;
|
this.errMsg = errMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocResponseJson(int errCode, String errMsg, Object data) {
|
public DocResponseJson(int errCode, String errMsg, Object data) {
|
||||||
super();
|
super();
|
||||||
this.setData(data);
|
this.setData(data);
|
||||||
this.errCode = errCode;
|
this.errCode = errCode;
|
||||||
this.errMsg = errMsg;
|
this.errMsg = errMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocResponseJson(Integer errCode) {
|
public DocResponseJson(Integer errCode) {
|
||||||
super();
|
super();
|
||||||
this.errCode = errCode;
|
this.errCode = errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getErrCode() {
|
public Integer getErrCode() {
|
||||||
return errCode;
|
return errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setErrCode(Integer errCode) {
|
public void setErrCode(Integer errCode) {
|
||||||
this.errCode = errCode;
|
this.errCode = errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErrMsg() {
|
public String getErrMsg() {
|
||||||
return errMsg;
|
return errMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setErrMsg(String errMsg) {
|
public void setErrMsg(String errMsg) {
|
||||||
this.errMsg = errMsg;
|
this.errMsg = errMsg;
|
||||||
}
|
}
|
||||||
@@ -138,13 +141,13 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提示语
|
* 提示语
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
* @author 暮光:城中城
|
* @author 暮光:城中城
|
||||||
* @since 2018年8月7日
|
* @since 2018年8月7日
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static <T> DocResponseJson<T> warn(String errMsg) {
|
public static <T> DocResponseJson<T> warn(String errMsg) {
|
||||||
return new DocResponseJson<T>(300, errMsg);
|
return new DocResponseJson<T>(300, errMsg);
|
||||||
@@ -153,9 +156,9 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
/**
|
/**
|
||||||
* 错误
|
* 错误
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
* @author 暮光:城中城
|
* @author 暮光:城中城
|
||||||
* @since 2018年8月7日
|
* @since 2018年8月7日
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static <T> DocResponseJson<T> error(String errMsg) {
|
public static <T> DocResponseJson<T> error(String errMsg) {
|
||||||
return new DocResponseJson<T>(500, errMsg);
|
return new DocResponseJson<T>(500, errMsg);
|
||||||
@@ -164,31 +167,31 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
/**
|
/**
|
||||||
* 失败
|
* 失败
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
* @author 暮光:城中城
|
* @author 暮光:城中城
|
||||||
* @since 2018年8月7日
|
* @since 2018年8月7日
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static <T> DocResponseJson<T> failure(int errCode, String errMsg) {
|
public static <T> DocResponseJson<T> failure(int errCode, String errMsg) {
|
||||||
return new DocResponseJson<T>(errCode, errMsg);
|
return new DocResponseJson<T>(errCode, errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 成功的返回方法
|
* 成功的返回方法
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
* @author 暮光:城中城
|
* @author 暮光:城中城
|
||||||
* @since 2018年8月7日
|
* @since 2018年8月7日
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static <T> DocResponseJson<T> ok() {
|
public static <T> DocResponseJson<T> ok() {
|
||||||
return new DocResponseJson<>();
|
return new DocResponseJson<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 成功的返回方法
|
* 成功的返回方法
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
* @author 暮光:城中城
|
* @author 暮光:城中城
|
||||||
* @since 2018年8月7日
|
* @since 2018年8月7日
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static <T> DocResponseJson<T> ok(Object data) {
|
public static <T> DocResponseJson<T> ok(Object data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
@@ -198,7 +201,7 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
responseJson.setData(data);
|
responseJson.setData(data);
|
||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toJson() {
|
public String toJson() {
|
||||||
return JSON.toJSONString(this, mapping);
|
return JSON.toJSONString(this, mapping);
|
||||||
}
|
}
|
||||||
@@ -215,6 +218,7 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
public boolean isOk() {
|
public boolean isOk() {
|
||||||
return Objects.equals(this.errCode, 200);
|
return Objects.equals(this.errCode, 200);
|
||||||
}
|
}
|
||||||
@@ -223,5 +227,5 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
|
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,14 +99,6 @@
|
|||||||
<groupId>org.freemarker</groupId>
|
<groupId>org.freemarker</groupId>
|
||||||
<artifactId>freemarker</artifactId>
|
<artifactId>freemarker</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjtools</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
package com.zyplayer.doc.data.aspect;
|
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
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.json.ResponseJson;
|
|
||||||
import com.zyplayer.doc.core.util.ThreadLocalUtil;
|
|
||||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
|
||||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
|
||||||
import com.zyplayer.doc.data.utils.BeanUtil;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class AuthAspect {
|
|
||||||
|
|
||||||
@Around(value = "@annotation(com.zyplayer.doc.core.annotation.AuthMan) || @within(com.zyplayer.doc.core.annotation.AuthMan)")
|
|
||||||
public Object authController(ProceedingJoinPoint pjp) throws Throwable {
|
|
||||||
AuthMan authMan = BeanUtil.getAnnotation(pjp, AuthMan.class);
|
|
||||||
ResponseBody responseBody = BeanUtil.getAnnotation(pjp, ResponseBody.class);
|
|
||||||
RestController restController = BeanUtil.getAnnotation(pjp, RestController.class);
|
|
||||||
boolean isResponseBody = (restController != null || responseBody != null);
|
|
||||||
|
|
||||||
Class<?> returnType = ((MethodSignature) pjp.getSignature()).getMethod().getReturnType();
|
|
||||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
|
||||||
if (currentUser == null) {
|
|
||||||
String reason = "你访问的内容需要登录,请登录后再试";
|
|
||||||
if (isResponseBody) {
|
|
||||||
return DocResponseJson.failure(HttpConst.TOKEN_TIMEOUT, reason);
|
|
||||||
} else if (returnType.isAssignableFrom(ModelAndView.class)) {
|
|
||||||
HttpServletRequest request = ThreadLocalUtil.getHttpServletRequest();
|
|
||||||
StringBuffer requestURL = request.getRequestURL();
|
|
||||||
String requestURLStr = URLEncoder.encode(requestURL.toString(), "utf-8");
|
|
||||||
return new ModelAndView("redirect:./#/user/login?redirect=" + requestURLStr);
|
|
||||||
} else if (returnType.isAssignableFrom(Map.class)) {
|
|
||||||
return Maps.newHashMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 判断权限是否足够
|
|
||||||
boolean haveAuth = DocUserUtil.haveAuth(authMan.value());
|
|
||||||
if (haveAuth) {
|
|
||||||
return pjp.proceed();
|
|
||||||
}
|
|
||||||
String reasonStr = "没有操作权限,请联系管理员";
|
|
||||||
if (isResponseBody) {
|
|
||||||
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
|
|
||||||
if (method.getReturnType().equals(ResponseJson.class)) {
|
|
||||||
return DocResponseJson.warn(reasonStr);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return Class.forName(method.getReturnType().getName()).newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return authMan.authUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.zyplayer.doc.data.config;
|
|
||||||
|
|
||||||
import com.zyplayer.doc.core.json.HttpConst;
|
|
||||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录和跨域拦截器
|
|
||||||
* @author 暮光:城中城
|
|
||||||
* @since 2019年05月25日
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class DocLoginOriginInterceptor implements HandlerInterceptor {
|
|
||||||
|
|
||||||
@Value("${zyplayer.doc.manage.originDomainRegex:}")
|
|
||||||
private String originDomainRegex;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
|
|
||||||
// 清理用户信息
|
|
||||||
DocUserUtil.clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object haddler, ModelAndView modelAndView) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记录请求信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
|
|
||||||
// 指定域名可跨域访问
|
|
||||||
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格式标准输出、及编码
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 清理用户信息
|
|
||||||
DocUserUtil.clean();
|
|
||||||
// 设置token
|
|
||||||
String accessToken = getCookieValueByRequest(request, HttpConst.ACCESS_TOKEN);
|
|
||||||
DocUserUtil.setAccessToken(accessToken);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取cookie
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Cookie getCookieByRequest(HttpServletRequest request, String name) {
|
|
||||||
if (StringUtils.isEmpty(name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Cookie[] cookies = request.getCookies();
|
|
||||||
for (int i = 0; (cookies != null) && (i < cookies.length); i++) {
|
|
||||||
Cookie cookie = cookies[i];
|
|
||||||
if (name.equals(cookie.getName())) {
|
|
||||||
return cookie;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取cookie值
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String getCookieValueByRequest(HttpServletRequest request, String name) {
|
|
||||||
Cookie cookie = getCookieByRequest(request, name);
|
|
||||||
return cookie == null ? null : cookie.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package com.zyplayer.doc.data.utils;
|
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.Signature;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class BeanUtil {
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
public static <T extends Annotation> T getAnnotation(JoinPoint pjp, Class<T> t) throws Exception {
|
|
||||||
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
|
|
||||||
T annotation = method.getAnnotation(t);// 方法上定义的
|
|
||||||
if (annotation == null) {
|
|
||||||
annotation = (T) pjp.getSignature().getDeclaringType().getAnnotation(t);// 类上定义的
|
|
||||||
if (annotation == null) {
|
|
||||||
Object target = pjp.getTarget();
|
|
||||||
annotation = target.getClass().getAnnotation(t);// 实现类上定义的
|
|
||||||
if (annotation == null) {
|
|
||||||
Signature sig = pjp.getSignature();
|
|
||||||
if (sig instanceof MethodSignature) {
|
|
||||||
MethodSignature msig = (MethodSignature) sig;
|
|
||||||
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
|
|
||||||
annotation = currentMethod.getAnnotation(t);// 实现类的方法上定义的
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return annotation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,7 @@ package com.zyplayer.doc.manage.framework.config;
|
|||||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||||
import com.zyplayer.doc.data.config.DocLoginOriginInterceptor;
|
import com.zyplayer.doc.manage.framework.interceptor.UserLoginInterceptor;
|
||||||
import com.zyplayer.doc.manage.framework.interceptor.RequestInfoInterceptor;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.format.FormatterRegistry;
|
import org.springframework.format.FormatterRegistry;
|
||||||
@@ -13,11 +12,11 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
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 org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,12 +24,10 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebMvcConfig implements WebMvcConfigurer {
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
RequestInfoInterceptor requestInfoInterceptor;
|
UserLoginInterceptor userLoginInterceptor;
|
||||||
@Resource
|
|
||||||
DocLoginOriginInterceptor docLoginOriginInterceptor;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFormatters(FormatterRegistry registry) {
|
public void addFormatters(FormatterRegistry registry) {
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
@@ -40,12 +37,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
|||||||
dateFormatter.setLenient(true);
|
dateFormatter.setLenient(true);
|
||||||
registry.addFormatter(dateFormatter);
|
registry.addFormatter(dateFormatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
|
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
|
||||||
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
|
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
|
||||||
List<MediaType> supportedMediaTypes = new ArrayList<>();
|
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);
|
fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
|
||||||
FastJsonConfig fastJsonConfig = new FastJsonConfig();
|
FastJsonConfig fastJsonConfig = new FastJsonConfig();
|
||||||
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat);
|
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat);
|
||||||
@@ -57,12 +54,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
|||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
converters.add(0, fastJsonHttpMessageConverter());
|
converters.add(0, fastJsonHttpMessageConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(docLoginOriginInterceptor);
|
registry.addInterceptor(userLoginInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png", "/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
|
||||||
registry.addInterceptor(requestInfoInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png",
|
|
||||||
"/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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:{},总耗时:{}ms,URI:{}", 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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:{},总耗时:{}ms,URI:{}", 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import springfox.documentation.swagger.web.SwaggerResource;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -76,8 +77,13 @@ public class SwaggerDocumentController {
|
|||||||
String docUrl = SwaggerDocUtil.replaceSwaggerResources(swaggerDoc.getDocUrl());
|
String docUrl = SwaggerDocUtil.replaceSwaggerResources(swaggerDoc.getDocUrl());
|
||||||
if (SwaggerDocUtil.isSwaggerResources(docUrl)) {
|
if (SwaggerDocUtil.isSwaggerResources(docUrl)) {
|
||||||
String swaggerDomain = SwaggerDocUtil.getSwaggerResourceDomain(docUrl);
|
String swaggerDomain = SwaggerDocUtil.getSwaggerResourceDomain(docUrl);
|
||||||
String resourcesStr = swaggerHttpRequestService.requestSwaggerUrl(request, docUrl, swaggerDomain);
|
List<SwaggerResource> resourceList;
|
||||||
List<SwaggerResource> resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
try {
|
||||||
|
String resourcesStr = swaggerHttpRequestService.requestSwaggerUrl(request, docUrl, swaggerDomain);
|
||||||
|
resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return DocResponseJson.warn("解析文档地址失败:" + e.getMessage());
|
||||||
|
}
|
||||||
if (resourceList == null || resourceList.isEmpty()) {
|
if (resourceList == null || resourceList.isEmpty()) {
|
||||||
return DocResponseJson.warn("该地址未找到文档");
|
return DocResponseJson.warn("该地址未找到文档");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.zyplayer.doc.swaggerplus.controller;
|
|||||||
|
|
||||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||||
|
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||||
import com.zyplayer.doc.data.repository.manage.entity.SwaggerDoc;
|
import com.zyplayer.doc.data.repository.manage.entity.SwaggerDoc;
|
||||||
import com.zyplayer.doc.data.service.manage.SwaggerDocService;
|
import com.zyplayer.doc.data.service.manage.SwaggerDocService;
|
||||||
import com.zyplayer.doc.swaggerplus.controller.vo.SwaggerResourceVo;
|
import com.zyplayer.doc.swaggerplus.controller.vo.SwaggerResourceVo;
|
||||||
@@ -37,6 +38,7 @@ public class SwaggerProxyController {
|
|||||||
@Resource
|
@Resource
|
||||||
private SwaggerHttpRequestService swaggerHttpRequestService;
|
private SwaggerHttpRequestService swaggerHttpRequestService;
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
@RequestMapping("/swagger-resources")
|
@RequestMapping("/swagger-resources")
|
||||||
public List<SwaggerResourceVo> swaggerResources() {
|
public List<SwaggerResourceVo> swaggerResources() {
|
||||||
List<SwaggerResourceVo> resourceList = new LinkedList<>();
|
List<SwaggerResourceVo> resourceList = new LinkedList<>();
|
||||||
@@ -57,15 +59,19 @@ public class SwaggerProxyController {
|
|||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@RequestMapping(value = "/v2/api-docs", produces = {MimeTypeUtils.APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE})
|
@RequestMapping(value = "/v2/api-docs", produces = {MimeTypeUtils.APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE})
|
||||||
public ResponseEntity<Json> content(HttpServletRequest request, Long id) {
|
public ResponseEntity<Object> content(HttpServletRequest request, Long id) {
|
||||||
SwaggerDoc swaggerDoc = swaggerDocService.getById(id);
|
SwaggerDoc swaggerDoc = swaggerDocService.getById(id);
|
||||||
if (swaggerDoc == null) {
|
if (swaggerDoc == null) {
|
||||||
throw new ConfirmException("文档不存在");
|
throw new ConfirmException("文档不存在");
|
||||||
}
|
}
|
||||||
if (Objects.equals(swaggerDoc.getDocType(), 1)) {
|
if (Objects.equals(swaggerDoc.getDocType(), 1)) {
|
||||||
String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(swaggerDoc.getDocUrl());
|
try {
|
||||||
String contentStr = swaggerHttpRequestService.requestSwaggerUrl(request, swaggerDoc.getDocUrl(), docsDomain);
|
String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(swaggerDoc.getDocUrl());
|
||||||
return new ResponseEntity<>(new Json(contentStr), HttpStatus.OK);
|
String contentStr = swaggerHttpRequestService.requestSwaggerUrl(request, swaggerDoc.getDocUrl(), docsDomain);
|
||||||
|
return new ResponseEntity<>(new Json(contentStr), HttpStatus.OK);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new ResponseEntity<>(DocResponseJson.warn("请求文档失败"), HttpStatus.OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new ResponseEntity<>(new Json(swaggerDoc.getJsonContent()), HttpStatus.OK);
|
return new ResponseEntity<>(new Json(swaggerDoc.getJsonContent()), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user