Java接口安全

Java接口安全

拦截器

package com.javasm.shirospringboot.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;




/**
 * api 拦截器
 * @author Cc
 *
 */
public class ApiInterceptor extends HandlerInterceptorAdapter {

	private static Logger logger = LoggerFactory.getLogger(ApiInterceptor.class);
	// 10分钟有效请求时间
	private static final long REQUEST_TIMEOUT_EXPIRE = 10 * 60 * 1000;
	private static final String UTF8 = "utf-8";
	private static final String CONTENT_TYPE = "application/json";
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		return true;
		// 签名比较
		String sign = request.getParameter("sign");
	    if(handler.getClass().isAssignableFrom(HandlerMethod.class)){
	    	AuthCheck authCheck = ((HandlerMethod) handler).getMethodAnnotation(AuthCheck.class);
            //没有声明需要权限,或者声明不验证权限
            if(authCheck == null || authCheck.validate() == false){
            	return true;
            }else{
            	String timestamp = request.getParameter("timestamp");
            	// 时间戳参数检查
        		if (StringUtils.isBlank(timestamp)) {
        			logger.error("签名参数timestamp'{}'为空 requestInfo:{}", timestamp, request.getServletPath());
        			responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}");
        			return false;
        		}
        		// 请求失效检查
        		long clientTimestamp = new Long(timestamp);
        		if (!(Math.abs(System.currentTimeMillis() - clientTimestamp) < REQUEST_TIMEOUT_EXPIRE)) {
        			logger.error("请求已过期 clientTimestampStr:{} requestInfo:{}", timestamp, request.getServletPath());
        			responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}");
        			return false;
        		}

        		// 服务端签名
        		String serverSign;
        	    // 服务端签名参数
        	 	Map<String, Object> paramMap = new HashMap<String, Object>();
        	    Map<String, String[]> parameterMap = request.getParameterMap();
        		for (String key : parameterMap.keySet()) {
        			paramMap.put(key, getParamValue(parameterMap.get(key)));
        		}
        		serverSign = SignUtil.getSign(paramMap);
                //在这里实现自己的权限验证逻辑
            	if (StringUtils.isBlank(serverSign) || !serverSign.equals(sign)) {//如果验证失败
        			logger.error("签名不一致 serverSign:{}    clientSign:{}    requestInfo:{}", new Object[] { serverSign, sign, request.getServletPath() });
        			responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}");
        			return false;
        		}else{ //校验成功
                    return true;
                }
            }
        }
        else
            return true;
     }

	/**
	 * 获取请求中的所有参数
	 * @param paramValues
	 * @return
	 */
	private String getParamValue(String[] paramValues) {
		if (paramValues == null) {
			return StringUtils.EMPTY;
		}
		String paramValue = null;
		if (paramValues.length == 1) {
			paramValue = paramValues[0];
		} else if (paramValues.length > 1) {
			paramValue = StringUtils.join(paramValues, ",");
		}
		return StringUtils.defaultString(paramValue);
	}

	public static void responseJson(HttpServletResponse response, String responseContent) throws IOException {
		if (response.isCommitted()) {
			logger.info("response.isCommitted()! responseContent:{"+responseContent+"}");
			return;
		}
		response.setCharacterEncoding(UTF8);
		response.setContentType(CONTENT_TYPE);
		PrintWriter printWriter = response.getWriter();
		printWriter.print(responseContent);
		printWriter.flush();
		printWriter.close();
	}

}

自定义权限注解

package com.javasm.shirospringboot.interceptor;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义鉴权注解
 * @author Wangshaocheng
 * 
 */
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
	boolean validate() default true;
}

加密辅助类

package com.javasm.shirospringboot.interceptor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

/**
 * 加密辅助类
 * @author wsc
 * @time 2016-2-25
 */
public class SignUtil {

	private static String key = "IXCfWBE5dRfyuIcFmhe2ANQ6VmoRZxRP";

	public static String getSign(Map<String,Object> map) throws Exception{
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            if(!entry.getValue().equals("")&& !entry.getKey().equals("sign")){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
		//先按照字符串长度取短的那个字符串的长度作为条件,然后循环判断两个字符串的第一个字符的ASCII码大小,做出递增排序,如果两个字符串第一个字符的ASCII码一致,则判断第二个字符,以此类推,通过这种方式将字符串通过首字母的ASCII码进行排序。
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + key;
        result = MD5Encrypt.encrypt(result).toUpperCase();
        return result;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值