add > simple api sign auth

master
lihengming 8 years ago
parent 8f0db07bec
commit f03a12e936
  1. 95
      src/main/java/com/company/project/configurer/WebMvcConfigurer.java

@ -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;
}
} }

Loading…
Cancel
Save