From f03a12e936b50842292c8926a3770c38acb51786 Mon Sep 17 00:00:00 2001 From: lihengming <89921218@qq.com> Date: Tue, 27 Jun 2017 16:59:37 +0800 Subject: [PATCH] add > simple api sign auth --- .../project/configurer/WebMvcConfigurer.java | 95 +++++++++++++++++-- 1 file changed, 89 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/company/project/configurer/WebMvcConfigurer.java b/src/main/java/com/company/project/configurer/WebMvcConfigurer.java index 1492b70..d3c45fa 100644 --- a/src/main/java/com/company/project/configurer/WebMvcConfigurer.java +++ b/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.ResultCode; 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.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; 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.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -33,6 +39,8 @@ import java.util.List; public class WebMvcConfigurer extends WebMvcConfigurerAdapter { private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); + @Value("${spring.profiles.active}") + private String env;//当前激活的配置文件 //使用阿里 FastJson 作为JSON MessageConverter @Override @@ -48,7 +56,6 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { } - //统一异常处理 @Override public void configureHandlerExceptionResolvers(List exceptionResolvers) { @@ -85,15 +92,37 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { }); } + //解决跨域问题 @Override - public void addInterceptors(InterceptorRegistry registry) { - //添加拦截器 + public void addCorsMappings(CorsRegistry registry) { + //registry.addMapping("/**"); } + //添加拦截器 @Override - public void addCorsMappings(CorsRegistry registry) { - //解决跨域问题 - //registry.addMapping("/**"); + public void addInterceptors(InterceptorRegistry registry) { + //接口签名认证拦截器,该签名认证比较简单,实际项目中建议使用Json Web Token代替。 + 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) { @@ -106,4 +135,58 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter { logger.error(ex.getMessage()); } } + + /** + * 一个简单的签名认证,规则:请求参数按ASCII码排序后,拼接为a=value&b=value...这样的字符串后进行MD5 + * + * @param request + * @param requestSign + * @return + */ + private boolean validateSign(HttpServletRequest request, String requestSign) { + List keys = new ArrayList(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; + } }