|
@@ -1,403 +1,403 @@
|
|
package com.txz.project.filter;
|
|
package com.txz.project.filter;
|
|
|
|
|
|
-import cn.hutool.core.date.DateUtil;
|
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
|
-import com.txz.cif.dto.UserDTO;
|
|
|
|
-import com.txz.operating.dto.InterfacesDTO;
|
|
|
|
-import com.txz.operating.result.Result;
|
|
|
|
-import com.txz.project.dubbo.client.OperatingInterfacesDubboServiceClient;
|
|
|
|
-import com.txz.project.dubbo.client.UserDubboServiceClient;
|
|
|
|
-import com.netflix.zuul.ZuulFilter;
|
|
|
|
-import com.netflix.zuul.context.RequestContext;
|
|
|
|
-import io.jsonwebtoken.Claims;
|
|
|
|
-import io.jsonwebtoken.ExpiredJwtException;
|
|
|
|
-import io.jsonwebtoken.Jwts;
|
|
|
|
-import org.apache.commons.codec.digest.DigestUtils;
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.apache.commons.lang3.tuple.ImmutableTriple;
|
|
|
|
-import org.apache.commons.lang3.tuple.Triple;
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
|
-
|
|
|
|
-import javax.annotation.Resource;
|
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Collections;
|
|
|
|
-import java.util.List;
|
|
|
|
-
|
|
|
|
-@Component
|
|
|
|
-public class AccessFilter extends ZuulFilter {
|
|
|
|
-
|
|
|
|
- private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
|
|
|
|
-
|
|
|
|
- private static final String X_CLIENT_TOKEN_USERID = "x-client-token-userId";
|
|
|
|
- private static final String X_CLIENT_TOKEN_OPERATORID = "x-client-token-operatorId";
|
|
|
|
-
|
|
|
|
- private static final String BEARER = "Bearer ";
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * jwt token 密钥,主要用于token解析,签名验证
|
|
|
|
- */
|
|
|
|
- @Value("${spring.security.oauth2.jwt.signingKey}")
|
|
|
|
- private static String signingKey = "txz123456";
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- @Value("${signature}")
|
|
|
|
- private String signature; // 是否启用签名
|
|
|
|
-
|
|
|
|
- @Value("${pub.secret}")
|
|
|
|
- private String pubSecret;
|
|
|
|
-
|
|
|
|
- @Value("${interfaces.switch}")
|
|
|
|
- private String interfacesSwitch;
|
|
|
|
-
|
|
|
|
- @Resource
|
|
|
|
- private UserDubboServiceClient userDubboServiceClient;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- @Resource
|
|
|
|
- private OperatingInterfacesDubboServiceClient operatingInterfacesDubboServiceClient;
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public String filterType() {
|
|
|
|
- return "pre";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public int filterOrder() {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean shouldFilter() {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|
|
|
-// HttpServletRequest req = (HttpServletRequest) request;
|
|
|
|
-// HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req); //获得请求参数中的token值
|
|
|
|
-// String token = request.getParamter("token");
|
|
|
|
-// if(!StringUtils.isEntry(token)){ //如果请求中带有这个参数,则进行过滤加一个header头
|
|
|
|
-// requestWrapper.addHeader("tokenr", token);
|
|
|
|
-// chain.doFilter(requestWrapper, response); // Goes to default servlet.
|
|
|
|
-// }
|
|
|
|
-// chain.doFilter(request, response); // Goes to default servlet.
|
|
|
|
-// }
|
|
|
|
- @Override
|
|
|
|
- public Object run() {
|
|
|
|
- RequestContext ctx = RequestContext.getCurrentContext();
|
|
|
|
- HttpServletRequest request = ctx.getRequest();
|
|
|
|
- String token = request.getHeader("token");
|
|
|
|
- String servicePath = request.getRequestURI();
|
|
|
|
- try {
|
|
|
|
- if (StrUtil.endWith(servicePath,"/v2/api-docs")){
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- if (StrUtil.equals("off",interfacesSwitch)){
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- Result<InterfacesDTO> interfacesDTOResult = operatingInterfacesDubboServiceClient.detailForGateway(servicePath);
|
|
|
|
- if (!StringUtils.equals("200", interfacesDTOResult.getCode())) {
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"512\",\"message\":\"zuul Access Filter - unknown interfaces :"+servicePath+"\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- InterfacesDTO interfacesDTO = interfacesDTOResult.getData();
|
|
|
|
- if (interfacesDTO.getStatus() != 1) {
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"513\",\"message\":\"zuul Access Filter - interfaces status is error\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (interfacesDTO.getAuthorizeType() == 1) {
|
|
|
|
- // 登录拦截
|
|
|
|
- Triple<Boolean, String, String> tripleUser = getUserIdFromToken(token,request);
|
|
|
|
- if(tripleUser.getLeft() == false) {
|
|
|
|
- log.warn("登录认证失败,请求接口:{},请求IP:{},请求token:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
- getIpAddress(request), request.getHeader("token"), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
- // responseResult(response, result);
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"598\",\"message\":\"zuul Access Filter - login validate is false\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- UserDTO user = userDubboServiceClient.getUser(Long.parseLong(tripleUser.getMiddle()));
|
|
|
|
- if (user == null){
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"597\",\"message\":\"zuul Access Filter - user is null\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if (user.getStatus() != 1){
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"596\",\"message\":\"zuul Access Filter - user status is error\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- ctx.addZuulRequestHeader(X_CLIENT_TOKEN_USERID, tripleUser.getMiddle());
|
|
|
|
- ctx.addZuulRequestHeader(X_CLIENT_TOKEN_OPERATORID, tripleUser.getRight());
|
|
|
|
- try{
|
|
|
|
- userDubboServiceClient.updateLastTime(Long.parseLong(tripleUser.getMiddle()));
|
|
|
|
- }catch (Exception e){
|
|
|
|
- log.error("更新最后请求时间异常",e);
|
|
|
|
- }
|
|
|
|
-// boolean pass = validateLogin(request);
|
|
|
|
-// if (!pass) {
|
|
|
|
-// log.warn("登录认证失败,请求接口:{},请求IP:{},请求token:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
-// getIpAddress(request), request.getHeader("token"), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
-// // responseResult(response, result);
|
|
|
|
-// ctx.setSendZuulResponse(false);
|
|
|
|
-// ctx.setResponseStatusCode(200);
|
|
|
|
-// ctx.setResponseBody("{\"code\":\"598\",\"message\":\"zuul Access Filter - login validate is false\"}");
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-// if (StringUtils.equals("true", signature)) {
|
|
|
|
-// // 验证签名
|
|
|
|
-// boolean pass = validateSign(request, (String) merchant.get("secret"));
|
|
|
|
-// if (!pass) {
|
|
|
|
-// log.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
-// getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
-//
|
|
|
|
-// Result result = new Result();
|
|
|
|
-// result.setCode(ResultCode.UNAUTHORIZED).setMessage("签名认证失败");
|
|
|
|
-// // responseResult(response, result);
|
|
|
|
-// ctx.setSendZuulResponse(false);
|
|
|
|
-// ctx.setResponseStatusCode(200);
|
|
|
|
-// ctx.setResponseBody("{\"code\":\"597\",\"message\":\"zuul Access Filter - sign validate is false\"}");
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
-// if (StringUtils.equals("1", i.getMerchantAuthorizeType())) {
|
|
|
|
-// // 商户授权
|
|
|
|
-// boolean pass = validateMerchantAuthorize(i.getId(),merchantCode);
|
|
|
|
-// if (!pass) {
|
|
|
|
-// log.warn("商户认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
-// getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
-//
|
|
|
|
-// Result result = new Result();
|
|
|
|
-// result.setCode(ResultCode.UNAUTHORIZED).setMessage("商户认证失败");
|
|
|
|
-// // responseResult(response, result);
|
|
|
|
-// ctx.setSendZuulResponse(false);
|
|
|
|
-// ctx.setResponseStatusCode(200);
|
|
|
|
-// ctx.setResponseBody("{\"code\":\"596\",\"message\":\"zuul Access Filter - merchant validate is false\"}");
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
- if (interfacesDTO.getReturnCodeTranslate() != null) {
|
|
|
|
- if (interfacesDTO.getReturnCodeTranslate() == 1) {
|
|
|
|
- request.setAttribute("returnCodeTranslate", 1);
|
|
|
|
- } else {
|
|
|
|
- request.setAttribute("returnCodeTranslate", 0);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- request.setAttribute("returnCodeTranslate", 0);
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.error("异常e:{}", e);
|
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
|
- ctx.setResponseStatusCode(200);
|
|
|
|
- ctx.setResponseBody("{\"code\":\"599\",\"message\":\"zuul Access Filter - gateway has error\"}");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 提取jwt token中的数据,获取用户id
|
|
|
|
- *
|
|
|
|
- * @param authentication
|
|
|
|
- * @param request
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private Triple<Boolean, String, String> getUserIdFromToken(String authentication,
|
|
|
|
- HttpServletRequest request) {
|
|
|
|
- try {
|
|
|
|
- final Claims claims = this.getJwt(authentication);
|
|
|
|
- // claims.getExpiration();
|
|
|
|
- // checkt expiration
|
|
|
|
- boolean pass = DateUtil.compare(DateUtil.date(),claims.getExpiration()) < 0;
|
|
|
|
-// boolean pass = validateLogin(request);
|
|
|
|
- if (pass){
|
|
|
|
- String userId = claims.get("userId").toString();
|
|
|
|
-// String operatorId = claims.get("operatorId").toString();
|
|
|
|
- return new ImmutableTriple<Boolean, String, String>(true, userId , null);
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.error("get userId from token error:{}", e.getMessage());
|
|
|
|
- }
|
|
|
|
- return new ImmutableTriple<Boolean, String, String>(false,null,null);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- private static Claims getJwt(String jwtToken) {
|
|
|
|
- if (jwtToken.startsWith(BEARER)) {
|
|
|
|
- jwtToken = StringUtils.substring(jwtToken, BEARER.length());
|
|
|
|
- }
|
|
|
|
- Claims claims;
|
|
|
|
- try {
|
|
|
|
- claims = Jwts.parser() //得到DefaultJwtParser
|
|
|
|
- .setSigningKey(signingKey.getBytes()) //设置签名的秘钥
|
|
|
|
- .parseClaimsJws(jwtToken).getBody();
|
|
|
|
- } catch(ExpiredJwtException e) {
|
|
|
|
- claims = e.getClaims();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return claims;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- public static void main(String[] args) {
|
|
|
|
- System.out.printf(getJwt("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzYXdhIiwiZXhwIjoxNjgxMzY2NTg4LCJ1c2VySWQiOjEyLCJvcGVyYXRvcklkIjo5LCJpYXQiOjE2Nzg3NzQ1ODgsImp0aSI6ImQ1ZjM3MmQ4LWM0YzEtNGZkMy05NmNlLTg3MzEyOWM3MDZjNSJ9.XP4ukA_VuOka_Siwe_DRbaYb1jh5TT4XFdz9TvEUBRs")
|
|
|
|
- .get("userId").toString());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 检验入参(命中否决)
|
|
|
|
- *
|
|
|
|
- * @param i
|
|
|
|
- * @param request
|
|
|
|
- * @return 返回false 为命中 返回true 为未命中
|
|
|
|
- */
|
|
|
|
- private boolean validateParameterAuthorize(InterfacesDTO i, HttpServletRequest request) {
|
|
|
|
-// if (i == null) {
|
|
|
|
-// return true;
|
|
|
|
-// }
|
|
|
|
-// List<InterfacePmtDTO> pmts = i.getInPmts();
|
|
|
|
-// if (pmts == null || pmts.isEmpty()) {
|
|
|
|
-// return true;
|
|
|
|
-// }
|
|
|
|
-// InterfacePmt jsonPmt = null;
|
|
|
|
-// for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
-// if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
-// if (interfacePmt.getDataType() == 5) {
|
|
|
|
-// jsonPmt = interfacePmt;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// if (jsonPmt == null) {
|
|
|
|
-// for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
-// if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
-// if (StringUtils.equals(interfacePmt.getIsnull(), "1")) {
|
|
|
|
-// if (StringUtils.isBlank(request.getParameter(interfacePmt.getParam()))) {
|
|
|
|
-// log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
-// request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// } else {
|
|
|
|
-// JSONObject json = null;
|
|
|
|
-// try {
|
|
|
|
-// json = JSONObject.parseObject(request.getParameter(jsonPmt.getParam()));
|
|
|
|
-// } catch (Exception e) {
|
|
|
|
-// log.error("接口入参验证失败,json解析失败e:{}",e);
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
-// if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
-// if (StringUtils.equals(interfacePmt.getIsnull(), "1")) {
|
|
|
|
-// if (StringUtils.startsWith(interfacePmt.getParam(),jsonPmt.getParam()+".")) {
|
|
|
|
-// String pmtName = interfacePmt.getParam().substring(jsonPmt.getParam().length()+1, interfacePmt.getParam().length());
|
|
|
|
-// if (json.get(pmtName) == null) {
|
|
|
|
-// log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
-// request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// } else {
|
|
|
|
-// if (StringUtils.isBlank(request.getParameter(interfacePmt.getParam()))) {
|
|
|
|
-// log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
-// request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean validateMerchantAuthorize(Integer id, String merchantCode) {
|
|
|
|
-// Result findByCode = commonClient.findByCode(id, merchantCode);
|
|
|
|
-// if (StringUtils.equals("200", findByCode.getCode())) {
|
|
|
|
-// if (findByCode.getData()!= null) {
|
|
|
|
-// return true;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 一个简单的登录认证
|
|
|
|
- */
|
|
|
|
- private boolean validateLogin(HttpServletRequest request) {
|
|
|
|
- String token = request.getHeader("token");
|
|
|
|
- if (StringUtils.isBlank(token)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- UserDTO booleanResult = userDubboServiceClient.validateLogin(token);
|
|
|
|
- return booleanResult != null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 一个简单的签名认证,规则: 1. 将请求参数按ascii码排序 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
|
|
|
|
- * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
|
|
|
|
- */
|
|
|
|
- private boolean validateSign(HttpServletRequest request, String secret) {
|
|
|
|
- String requestSign = request.getParameter("sign");// 获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
|
|
|
|
- if (StringUtils.isEmpty(requestSign)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
|
|
|
|
- keys.remove("sign");// 排除sign参数
|
|
|
|
- Collections.sort(keys);// 排序
|
|
|
|
-
|
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
|
- for (String key : keys) {
|
|
|
|
- sb.append(key).append("=").append(request.getParameter(key)).append("&");// 拼接字符串
|
|
|
|
- }
|
|
|
|
- String linkString = sb.toString();
|
|
|
|
- linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);// 去除最后一个'&'
|
|
|
|
-
|
|
|
|
- String sign = DigestUtils.md5Hex(linkString + secret + pubSecret);// 混合密钥md5
|
|
|
|
-
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
|
|
+// import cn.hutool.core.date.DateUtil;
|
|
|
|
+// import cn.hutool.core.util.StrUtil;
|
|
|
|
+// import com.alibaba.fastjson.JSON;
|
|
|
|
+// import com.txz.cif.dto.UserDTO;
|
|
|
|
+// import com.txz.operating.dto.InterfacesDTO;
|
|
|
|
+// import com.txz.operating.result.Result;
|
|
|
|
+// import com.txz.project.dubbo.client.OperatingInterfacesDubboServiceClient;
|
|
|
|
+// import com.txz.project.dubbo.client.UserDubboServiceClient;
|
|
|
|
+// import com.netflix.zuul.ZuulFilter;
|
|
|
|
+// import com.netflix.zuul.context.RequestContext;
|
|
|
|
+// import io.jsonwebtoken.Claims;
|
|
|
|
+// import io.jsonwebtoken.ExpiredJwtException;
|
|
|
|
+// import io.jsonwebtoken.Jwts;
|
|
|
|
+// import org.apache.commons.codec.digest.DigestUtils;
|
|
|
|
+// import org.apache.commons.lang3.StringUtils;
|
|
|
|
+// import org.apache.commons.lang3.tuple.ImmutableTriple;
|
|
|
|
+// import org.apache.commons.lang3.tuple.Triple;
|
|
|
|
+// import org.slf4j.Logger;
|
|
|
|
+// import org.slf4j.LoggerFactory;
|
|
|
|
+// import org.springframework.beans.factory.annotation.Value;
|
|
|
|
+// import org.springframework.stereotype.Component;
|
|
|
|
+//
|
|
|
|
+// import javax.annotation.Resource;
|
|
|
|
+// import javax.servlet.http.HttpServletRequest;
|
|
|
|
+// import java.util.ArrayList;
|
|
|
|
+// import java.util.Collections;
|
|
|
|
+// import java.util.List;
|
|
|
|
+//
|
|
|
|
+// @Component
|
|
|
|
+// public class AccessFilter extends ZuulFilter {
|
|
|
|
+//
|
|
|
|
+// private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
|
|
|
|
+//
|
|
|
|
+// private static final String X_CLIENT_TOKEN_USERID = "x-client-token-userId";
|
|
|
|
+// private static final String X_CLIENT_TOKEN_OPERATORID = "x-client-token-operatorId";
|
|
|
|
+//
|
|
|
|
+// private static final String BEARER = "Bearer ";
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * jwt token 密钥,主要用于token解析,签名验证
|
|
|
|
+// */
|
|
|
|
+// @Value("${spring.security.oauth2.jwt.signingKey}")
|
|
|
|
+// private static String signingKey = "txz123456";
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// @Value("${signature}")
|
|
|
|
+// private String signature; // 是否启用签名
|
|
|
|
+//
|
|
|
|
+// @Value("${pub.secret}")
|
|
|
|
+// private String pubSecret;
|
|
|
|
+//
|
|
|
|
+// @Value("${interfaces.switch}")
|
|
|
|
+// private String interfacesSwitch;
|
|
|
|
+//
|
|
|
|
+// @Resource
|
|
|
|
+// private UserDubboServiceClient userDubboServiceClient;
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// @Resource
|
|
|
|
+// private OperatingInterfacesDubboServiceClient operatingInterfacesDubboServiceClient;
|
|
|
|
+//
|
|
|
|
+// @Override
|
|
|
|
+// public String filterType() {
|
|
|
|
+// return "pre";
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// @Override
|
|
|
|
+// public int filterOrder() {
|
|
|
|
+// return 0;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// @Override
|
|
|
|
+// public boolean shouldFilter() {
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// // @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|
|
|
+// // HttpServletRequest req = (HttpServletRequest) request;
|
|
|
|
+// // HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req); //获得请求参数中的token值
|
|
|
|
+// // String token = request.getParamter("token");
|
|
|
|
+// // if(!StringUtils.isEntry(token)){ //如果请求中带有这个参数,则进行过滤加一个header头
|
|
|
|
+// // requestWrapper.addHeader("tokenr", token);
|
|
|
|
+// // chain.doFilter(requestWrapper, response); // Goes to default servlet.
|
|
|
|
+// // }
|
|
|
|
+// // chain.doFilter(request, response); // Goes to default servlet.
|
|
|
|
+// // }
|
|
|
|
+// @Override
|
|
|
|
+// public Object run() {
|
|
|
|
+// RequestContext ctx = RequestContext.getCurrentContext();
|
|
|
|
+// HttpServletRequest request = ctx.getRequest();
|
|
|
|
+// String token = request.getHeader("token");
|
|
|
|
+// String servicePath = request.getRequestURI();
|
|
|
|
+// try {
|
|
|
|
+// if (StrUtil.endWith(servicePath,"/v3/api-docs")){
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+// if (StrUtil.equals("off",interfacesSwitch)){
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+// Result<InterfacesDTO> interfacesDTOResult = operatingInterfacesDubboServiceClient.detailForGateway(servicePath);
|
|
|
|
+// if (!StringUtils.equals("200", interfacesDTOResult.getCode())) {
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"512\",\"message\":\"zuul Access Filter - unknown interfaces :"+servicePath+"\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// InterfacesDTO interfacesDTO = interfacesDTOResult.getData();
|
|
|
|
+// if (interfacesDTO.getStatus() != 1) {
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"513\",\"message\":\"zuul Access Filter - interfaces status is error\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// if (interfacesDTO.getAuthorizeType() == 1) {
|
|
|
|
+// // 登录拦截
|
|
|
|
+// Triple<Boolean, String, String> tripleUser = getUserIdFromToken(token,request);
|
|
|
|
+// if(tripleUser.getLeft() == false) {
|
|
|
|
+// log.warn("登录认证失败,请求接口:{},请求IP:{},请求token:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
+// getIpAddress(request), request.getHeader("token"), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
+// // responseResult(response, result);
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"598\",\"message\":\"zuul Access Filter - login validate is false\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// UserDTO user = userDubboServiceClient.getUser(Long.parseLong(tripleUser.getMiddle()));
|
|
|
|
+// if (user == null){
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"597\",\"message\":\"zuul Access Filter - user is null\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// if (user.getStatus() != 1){
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"596\",\"message\":\"zuul Access Filter - user status is error\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// ctx.addZuulRequestHeader(X_CLIENT_TOKEN_USERID, tripleUser.getMiddle());
|
|
|
|
+// ctx.addZuulRequestHeader(X_CLIENT_TOKEN_OPERATORID, tripleUser.getRight());
|
|
|
|
+// try{
|
|
|
|
+// userDubboServiceClient.updateLastTime(Long.parseLong(tripleUser.getMiddle()));
|
|
|
|
+// }catch (Exception e){
|
|
|
|
+// log.error("更新最后请求时间异常",e);
|
|
|
|
+// }
|
|
|
|
+// // boolean pass = validateLogin(request);
|
|
|
|
+// // if (!pass) {
|
|
|
|
+// // log.warn("登录认证失败,请求接口:{},请求IP:{},请求token:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
+// // getIpAddress(request), request.getHeader("token"), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
+// // // responseResult(response, result);
|
|
|
|
+// // ctx.setSendZuulResponse(false);
|
|
|
|
+// // ctx.setResponseStatusCode(200);
|
|
|
|
+// // ctx.setResponseBody("{\"code\":\"598\",\"message\":\"zuul Access Filter - login validate is false\"}");
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // if (StringUtils.equals("true", signature)) {
|
|
|
|
+// // // 验证签名
|
|
|
|
+// // boolean pass = validateSign(request, (String) merchant.get("secret"));
|
|
|
|
+// // if (!pass) {
|
|
|
|
+// // log.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
+// // getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
+// //
|
|
|
|
+// // Result result = new Result();
|
|
|
|
+// // result.setCode(ResultCode.UNAUTHORIZED).setMessage("签名认证失败");
|
|
|
|
+// // // responseResult(response, result);
|
|
|
|
+// // ctx.setSendZuulResponse(false);
|
|
|
|
+// // ctx.setResponseStatusCode(200);
|
|
|
|
+// // ctx.setResponseBody("{\"code\":\"597\",\"message\":\"zuul Access Filter - sign validate is false\"}");
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+//
|
|
|
|
+// // if (StringUtils.equals("1", i.getMerchantAuthorizeType())) {
|
|
|
|
+// // // 商户授权
|
|
|
|
+// // boolean pass = validateMerchantAuthorize(i.getId(),merchantCode);
|
|
|
|
+// // if (!pass) {
|
|
|
|
+// // log.warn("商户认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
|
|
|
|
+// // getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
|
|
|
|
+// //
|
|
|
|
+// // Result result = new Result();
|
|
|
|
+// // result.setCode(ResultCode.UNAUTHORIZED).setMessage("商户认证失败");
|
|
|
|
+// // // responseResult(response, result);
|
|
|
|
+// // ctx.setSendZuulResponse(false);
|
|
|
|
+// // ctx.setResponseStatusCode(200);
|
|
|
|
+// // ctx.setResponseBody("{\"code\":\"596\",\"message\":\"zuul Access Filter - merchant validate is false\"}");
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// if (interfacesDTO.getReturnCodeTranslate() != null) {
|
|
|
|
+// if (interfacesDTO.getReturnCodeTranslate() == 1) {
|
|
|
|
+// request.setAttribute("returnCodeTranslate", 1);
|
|
|
|
+// } else {
|
|
|
|
+// request.setAttribute("returnCodeTranslate", 0);
|
|
|
|
+// }
|
|
|
|
+// } else {
|
|
|
|
+// request.setAttribute("returnCodeTranslate", 0);
|
|
|
|
+// }
|
|
|
|
+// } catch (Exception e) {
|
|
|
|
+// log.error("异常e:{}", e);
|
|
|
|
+// ctx.setSendZuulResponse(false);
|
|
|
|
+// ctx.setResponseStatusCode(200);
|
|
|
|
+// ctx.setResponseBody("{\"code\":\"599\",\"message\":\"zuul Access Filter - gateway has error\"}");
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 提取jwt token中的数据,获取用户id
|
|
|
|
+// *
|
|
|
|
+// * @param authentication
|
|
|
|
+// * @param request
|
|
|
|
+// * @return
|
|
|
|
+// */
|
|
|
|
+// private Triple<Boolean, String, String> getUserIdFromToken(String authentication,
|
|
|
|
+// HttpServletRequest request) {
|
|
|
|
+// try {
|
|
|
|
+// final Claims claims = this.getJwt(authentication);
|
|
|
|
+// // claims.getExpiration();
|
|
|
|
+// // checkt expiration
|
|
|
|
+// boolean pass = DateUtil.compare(DateUtil.date(),claims.getExpiration()) < 0;
|
|
|
|
+// // boolean pass = validateLogin(request);
|
|
|
|
+// if (pass){
|
|
|
|
+// String userId = claims.get("userId").toString();
|
|
|
|
+// // String operatorId = claims.get("operatorId").toString();
|
|
|
|
+// return new ImmutableTriple<Boolean, String, String>(true, userId , null);
|
|
|
|
+// }
|
|
|
|
+// } catch (Exception e) {
|
|
|
|
+// log.error("get userId from token error:{}", e.getMessage());
|
|
|
|
+// }
|
|
|
|
+// return new ImmutableTriple<Boolean, String, String>(false,null,null);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// private static Claims getJwt(String jwtToken) {
|
|
|
|
+// if (jwtToken.startsWith(BEARER)) {
|
|
|
|
+// jwtToken = StringUtils.substring(jwtToken, BEARER.length());
|
|
|
|
+// }
|
|
|
|
+// Claims claims;
|
|
|
|
+// try {
|
|
|
|
+// claims = Jwts.parser() //得到DefaultJwtParser
|
|
|
|
+// .setSigningKey(signingKey.getBytes()) //设置签名的秘钥
|
|
|
|
+// .parseClaimsJws(jwtToken).getBody();
|
|
|
|
+// } catch(ExpiredJwtException e) {
|
|
|
|
+// claims = e.getClaims();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return claims;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// public static void main(String[] args) {
|
|
|
|
+// System.out.printf(getJwt("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzYXdhIiwiZXhwIjoxNjgxMzY2NTg4LCJ1c2VySWQiOjEyLCJvcGVyYXRvcklkIjo5LCJpYXQiOjE2Nzg3NzQ1ODgsImp0aSI6ImQ1ZjM3MmQ4LWM0YzEtNGZkMy05NmNlLTg3MzEyOWM3MDZjNSJ9.XP4ukA_VuOka_Siwe_DRbaYb1jh5TT4XFdz9TvEUBRs")
|
|
|
|
+// .get("userId").toString());
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 检验入参(命中否决)
|
|
|
|
+// *
|
|
|
|
+// * @param i
|
|
|
|
+// * @param request
|
|
|
|
+// * @return 返回false 为命中 返回true 为未命中
|
|
|
|
+// */
|
|
|
|
+// private boolean validateParameterAuthorize(InterfacesDTO i, HttpServletRequest request) {
|
|
|
|
+// // if (i == null) {
|
|
|
|
+// // return true;
|
|
|
|
+// // }
|
|
|
|
+// // List<InterfacePmtDTO> pmts = i.getInPmts();
|
|
|
|
+// // if (pmts == null || pmts.isEmpty()) {
|
|
|
|
+// // return true;
|
|
|
|
+// // }
|
|
|
|
+// // InterfacePmt jsonPmt = null;
|
|
|
|
+// // for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
+// // if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
+// // if (interfacePmt.getDataType() == 5) {
|
|
|
|
+// // jsonPmt = interfacePmt;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // if (jsonPmt == null) {
|
|
|
|
+// // for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
+// // if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
+// // if (StringUtils.equals(interfacePmt.getIsnull(), "1")) {
|
|
|
|
+// // if (StringUtils.isBlank(request.getParameter(interfacePmt.getParam()))) {
|
|
|
|
+// // log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
+// // request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // } else {
|
|
|
|
+// // JSONObject json = null;
|
|
|
|
+// // try {
|
|
|
|
+// // json = JSONObject.parseObject(request.getParameter(jsonPmt.getParam()));
|
|
|
|
+// // } catch (Exception e) {
|
|
|
|
+// // log.error("接口入参验证失败,json解析失败e:{}",e);
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // for (InterfacePmt interfacePmt : pmts) {
|
|
|
|
+// // if (interfacePmt.getIsEnable() != null && interfacePmt.getIsEnable() == 0) {
|
|
|
|
+// // if (StringUtils.equals(interfacePmt.getIsnull(), "1")) {
|
|
|
|
+// // if (StringUtils.startsWith(interfacePmt.getParam(),jsonPmt.getParam()+".")) {
|
|
|
|
+// // String pmtName = interfacePmt.getParam().substring(jsonPmt.getParam().length()+1, interfacePmt.getParam().length());
|
|
|
|
+// // if (json.get(pmtName) == null) {
|
|
|
|
+// // log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
+// // request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // } else {
|
|
|
|
+// // if (StringUtils.isBlank(request.getParameter(interfacePmt.getParam()))) {
|
|
|
|
+// // log.info("接口入参验证失败:"+interfacePmt.getParam()+"不能为空");
|
|
|
|
+// // request.setAttribute("errorMsg", interfacePmt.getParam());
|
|
|
|
+// // return false;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// private boolean validateMerchantAuthorize(Integer id, String merchantCode) {
|
|
|
|
+// // Result findByCode = commonClient.findByCode(id, merchantCode);
|
|
|
|
+// // if (StringUtils.equals("200", findByCode.getCode())) {
|
|
|
|
+// // if (findByCode.getData()!= null) {
|
|
|
|
+// // return true;
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 一个简单的登录认证
|
|
|
|
+// */
|
|
|
|
+// private boolean validateLogin(HttpServletRequest request) {
|
|
|
|
+// String token = request.getHeader("token");
|
|
|
|
+// if (StringUtils.isBlank(token)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// UserDTO booleanResult = userDubboServiceClient.validateLogin(token);
|
|
|
|
+// return booleanResult != null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 一个简单的签名认证,规则: 1. 将请求参数按ascii码排序 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
|
|
|
|
+// * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
|
|
|
|
+// */
|
|
|
|
+// private boolean validateSign(HttpServletRequest request, String secret) {
|
|
|
|
+// String requestSign = request.getParameter("sign");// 获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
|
|
|
|
+// if (StringUtils.isEmpty(requestSign)) {
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+// List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
|
|
|
|
+// keys.remove("sign");// 排除sign参数
|
|
|
|
+// Collections.sort(keys);// 排序
|
|
|
|
+//
|
|
|
|
+// StringBuilder sb = new StringBuilder();
|
|
|
|
+// for (String key : keys) {
|
|
|
|
+// sb.append(key).append("=").append(request.getParameter(key)).append("&");// 拼接字符串
|
|
|
|
+// }
|
|
|
|
+// String linkString = sb.toString();
|
|
|
|
+// linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);// 去除最后一个'&'
|
|
|
|
+//
|
|
|
|
+// String sign = DigestUtils.md5Hex(linkString + secret + pubSecret);// 混合密钥md5
|
|
|
|
+//
|
|
|
|
+// 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;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// }
|