日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第三方调用安全校验

發布時間:2025/7/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第三方调用安全校验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 攔截器代碼

/*** @Description 添加請求是否合法驗證攔截器* @author 田林(lin.tian@mljr.com)* @date 2017年12月1日 下午4:20:38*/ @Component("signature") public class SignatureFilter implements Filter {private Logger logger = LoggerFactory.getLogger(SignatureFilter.class);@Value("${rsaKey}")private String rsaKey;public final static String JSON_PARAMS_TYPE="application/json";public final static String FORM_PARAMS_TYPE="application/x-www-form-urlencoded";@Override public void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {Map<String,String> singleValueMap = Maps.newHashMap();HttpServletRequest httpRequest=(HttpServletRequest)request;String password = httpRequest.getHeader("password");// 是否通過驗證boolean flag = false;//時間戳String timestamp = httpRequest.getHeader("timestamp");String serverPath = httpRequest.getServletPath();if("/".equals(serverPath)||serverPath.contains("/fe-che-union/static")){chain.doFilter(request,response);}else{HttpServletResponse httpResponse= (HttpServletResponse) response;String contentType = httpRequest.getContentType();if(!StringUtils.isEmpty(contentType)&&contentType.contains(JSON_PARAMS_TYPE)){//如果是json請求方式SignatureRequestWrapper requestWrapper = new SignatureRequestWrapper(httpRequest);String body = HttpHelper.getBodyString(requestWrapper);if (StringUtils.isEmpty(body)) {logger.error("非法請求, 無參數");OutWriterUtil.write(httpResponse, JSONObject.toJSONString(RespDTO.fail("無參數")));return;}Map<String, Object> parameters = JSONObject.parseObject(body);Set<String> keySet = parameters.keySet();for(String key:keySet){singleValueMap.put(key, JSONObject.toJSONString(parameters.get(key)));}request=requestWrapper;}else if(!StringUtils.isEmpty(contentType)&&contentType.contains(FORM_PARAMS_TYPE)){Map<String,String[]> parameterMap = request.getParameterMap();for(String key : parameterMap.keySet()){String[] valueArray = parameterMap.get(key);if(valueArray!=null&&valueArray.length>0){singleValueMap.put(key, valueArray[0]);}}} else {flag = true;}if(flag){chain.doFilter(request,response);}else{// 校驗參數合法性flag = SignatureUtils.checkSign(singleValueMap, rsaKey,password,timestamp);if(flag){chain.doFilter(request,response);}else{OutWriterUtil.write(httpResponse, JSONObject.toJSONString(RespDTO.fail("簽名錯誤必須存在")));return;}}}}private boolean checkSign(Map<String, Object> parameters) {Map<String, String> requestParams=new HashMap<>();SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");for (String key : parameters.keySet()) {String valueStr="";Object value = parameters.get(key);if (value ==null){continue;}if(BeanUtils.isSimpleValueType(value.getClass())){ //如果是簡單類型if(Date.class.isAssignableFrom(value.getClass())){//如果是時間類型valueStr = dateFormat.format(value);}else{valueStr=value.toString();}}else {//如果是復雜類型valueStr=JSONObject.toJSONString(value);}requestParams.put(key,valueStr);}return SignUtils.checkSign(requestParams,rsaKey);}private boolean checkParamIsExist(Map<String, Object> parameters, String... keys) {for (String key: keys) {if(parameters.get(key)==null){return false;}}return true;}@Overridepublic void destroy() {}}

?

2. 對輸入流進行封裝:

public class SignatureRequestWrapper extends HttpServletRequestWrapper {private HttpServletRequest original;private byte[] reqBytes;private boolean firstTime = true;public SignatureRequestWrapper(HttpServletRequest request) {super(request);reqBytes = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));}@Overridepublic BufferedReader getReader() throws IOException{InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(reqBytes));return new BufferedReader(isr);}@Overridepublic ServletInputStream getInputStream() throws IOException {ServletInputStream sis = new ServletInputStream() {@Override public boolean isFinished() {return false;}@Override public boolean isReady() {return false;}@Override public void setReadListener(ReadListener readListener) {}private int i;@Overridepublic int read() throws IOException {byte b;if(reqBytes.length > i){b = reqBytes[i++];}else{b = -1;}return b;}};return sis;}}

?

3. 校驗代碼

public class SignUtils {/*** 拼接鍵值對** @param key* @param value* @param isEncode* @return*/private static String buildKeyValue(String key, String value, boolean isEncode) {StringBuilder sb = new StringBuilder();sb.append(key);sb.append("=");if (isEncode) {try {sb.append(URLEncoder.encode(value, "UTF-8"));} catch (UnsupportedEncodingException e) {sb.append(value);}} else {sb.append(value);}return sb.toString();}/*** 對支付參數信息進行簽名** @param map* 待簽名授權信息** @return*/public static String sign(Map<String, String> map, String rsaKey) {StringBuilder sortStr = getSortStr(map);StringBuilder authInfo = getAuthInfo(rsaKey, sortStr);String sign = EncryptUtil.MD5(authInfo.toString());return sign;}private static StringBuilder getAuthInfo(String rsaKey, StringBuilder sortStr) {StringBuilder authInfo=new StringBuilder();authInfo.append(rsaKey);authInfo.append(sortStr);authInfo.append(rsaKey);return authInfo;}private static StringBuilder getSortStr(Map<String, String> map) {List<String> keys = new ArrayList<String>(map.keySet());// key排序 Collections.sort(keys);StringBuilder authInfo = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);authInfo.append(buildKeyValue(key, value, false));authInfo.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);authInfo.append(buildKeyValue(tailKey, tailValue, false));return authInfo;}/*** 要求外部訂單號必須唯一。* @return*/public static boolean checkSign(Map<String, String> map, String rsaKey) {String password=map.remove("password");StringBuilder sortStr = getSortStr(map);StringBuilder authInfo = getAuthInfo(rsaKey, sortStr);return EncryptUtil.checkPassWord(authInfo.toString(),password);}

?

4. Filter 無法直接通過 @Value 注入properties屬性 ,可以通過?DelegatingFilterProxy 來處理,將Filter 交給spring來管理。web.xml 配置:

<filter><filter-name>signature</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>signature</filter-name><url-pattern>/*</url-pattern></filter-mapping>

?

轉載于:https://www.cnblogs.com/Jtianlin/p/7922732.html

總結

以上是生活随笔為你收集整理的第三方调用安全校验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。