|
|
@ -8,8 +8,11 @@ import com.alibaba.fastjson.support.spring.FastJsonpHttpMessageConverter4; |
|
|
|
import com.company.project.core.Result; |
|
|
|
import com.company.project.core.Result; |
|
|
|
import com.company.project.core.ResultCode; |
|
|
|
import com.company.project.core.ResultCode; |
|
|
|
import com.company.project.core.ServiceException; |
|
|
|
import com.company.project.core.ServiceException; |
|
|
|
|
|
|
|
import org.apache.commons.codec.digest.DigestUtils; |
|
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
import org.springframework.http.converter.HttpMessageConverter; |
|
|
|
import org.springframework.http.converter.HttpMessageConverter; |
|
|
|
import org.springframework.web.method.HandlerMethod; |
|
|
|
import org.springframework.web.method.HandlerMethod; |
|
|
@ -19,11 +22,14 @@ import org.springframework.web.servlet.NoHandlerFoundException; |
|
|
|
import org.springframework.web.servlet.config.annotation.CorsRegistry; |
|
|
|
import org.springframework.web.servlet.config.annotation.CorsRegistry; |
|
|
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
|
|
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; |
|
|
|
|
|
|
|
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
|
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -33,6 +39,8 @@ import java.util.List; |
|
|
|
public class WebMvcConfigurer extends WebMvcConfigurerAdapter { |
|
|
|
public class WebMvcConfigurer extends WebMvcConfigurerAdapter { |
|
|
|
|
|
|
|
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); |
|
|
|
private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); |
|
|
|
|
|
|
|
@Value("${spring.profiles.active}") |
|
|
|
|
|
|
|
private String env;//当前激活的配置文件
|
|
|
|
|
|
|
|
|
|
|
|
//使用阿里 FastJson 作为JSON MessageConverter
|
|
|
|
//使用阿里 FastJson 作为JSON MessageConverter
|
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -48,7 +56,6 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//统一异常处理
|
|
|
|
//统一异常处理
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { |
|
|
|
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { |
|
|
@ -85,15 +92,37 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//解决跨域问题
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addInterceptors(InterceptorRegistry registry) { |
|
|
|
public void addCorsMappings(CorsRegistry registry) { |
|
|
|
//添加拦截器
|
|
|
|
//registry.addMapping("/**");
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//添加拦截器
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addCorsMappings(CorsRegistry registry) { |
|
|
|
public void addInterceptors(InterceptorRegistry registry) { |
|
|
|
//解决跨域问题
|
|
|
|
//接口签名认证拦截器,该签名认证比较简单,实际项目中建议使用Json Web Token代替。
|
|
|
|
//registry.addMapping("/**");
|
|
|
|
if (!StringUtils.contains(env, "dev")) { //开发环境忽略签名认证
|
|
|
|
|
|
|
|
registry.addInterceptor(new HandlerInterceptorAdapter() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
|
|
|
|
|
|
|
String sign = request.getParameter("sign"); |
|
|
|
|
|
|
|
//验证签名
|
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(sign) && validateSign(request, sign)) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", |
|
|
|
|
|
|
|
request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap())); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Result result = new Result(); |
|
|
|
|
|
|
|
result.setCode(ResultCode.UNAUTHORIZED).setMessage("签名认证失败"); |
|
|
|
|
|
|
|
responseResult(response, result); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void responseResult(HttpServletResponse response, Result result) { |
|
|
|
private void responseResult(HttpServletResponse response, Result result) { |
|
|
@ -106,4 +135,58 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { |
|
|
|
logger.error(ex.getMessage()); |
|
|
|
logger.error(ex.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 一个简单的签名认证,规则:请求参数按ASCII码排序后,拼接为a=value&b=value...这样的字符串后进行MD5 |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param request |
|
|
|
|
|
|
|
* @param requestSign |
|
|
|
|
|
|
|
* @return |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private boolean validateSign(HttpServletRequest request, String requestSign) { |
|
|
|
|
|
|
|
List<String> keys = new ArrayList<String>(request.getParameterMap().keySet()); |
|
|
|
|
|
|
|
Collections.sort(keys); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String linkString = ""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (String key : keys) { |
|
|
|
|
|
|
|
if (!"sign".equals(key)) { |
|
|
|
|
|
|
|
linkString += key + "=" + request.getParameter(key) + "&"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isEmpty(linkString)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
linkString = linkString.substring(0, linkString.length() - 1); |
|
|
|
|
|
|
|
String key = "Potato";//自己修改
|
|
|
|
|
|
|
|
String sign = DigestUtils.md5Hex(linkString + key); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return StringUtils.equals(sign, requestSign); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String getIpAddress(HttpServletRequest request) { |
|
|
|
|
|
|
|
String ip = request.getHeader("x-forwarded-for"); |
|
|
|
|
|
|
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
|
|
|
|
|
|
|
ip = request.getHeader("Proxy-Client-IP"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
|
|
|
|
|
|
|
ip = request.getHeader("WL-Proxy-Client-IP"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
|
|
|
|
|
|
|
ip = request.getHeader("HTTP_CLIENT_IP"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
|
|
|
|
|
|
|
ip = request.getHeader("HTTP_X_FORWARDED_FOR"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
|
|
|
|
|
|
|
ip = request.getRemoteAddr(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 如果是多级代理,那么取第一个ip为客户ip
|
|
|
|
|
|
|
|
if (ip != null && ip.indexOf(",") != -1) { |
|
|
|
|
|
|
|
ip = ip.substring(0, ip.indexOf(",")).trim(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ip; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|