spring boot 加入jsp自定义标签对get请求参数加密

spring boot JSP自定义标签的开发和使用


1、自定义一个加解密工具类AesUtils

/**
 * 加密请求参数
 * @author: Alan Fu
 */
public class AesUtils {
	private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
	/**加密方式*/
	private static final String KEY_ALGORITHM = "AES";
	/**字符编码*/
	private static final String ENCODING = "utf-8";
	/**密钥*/
	private static final String KEY = "$1$jXJ0a/At$BJy.";
	
	private static Logger LOGGER = LoggerFactory.getLogger(AesUtils.class);
	
	
	/**
	 * 加密
	 * @param content
	 * @return
	 */
	public static String valueEncrypt(String value) {
		try {
			return URLEncoder.encode(AesUtils.encrypt(value), ENCODING);
		} catch (Exception e) {
			return value;
		}
	}
	
	
	/**
	 * 解密
	 * @param content
	 * @return
	 */
	public static String valueDecrypt(String content) {
		try {
			String text = decrypt(content);
			return StringUtils.isEmpty(text) ? content : text;
		} catch (Exception e) {
			return content;
		}
	}
	
	
	/** 
     * 加密方式--这种加密方式有两种限制 
     * 1、密钥必须是16位的 
     * 2、待加密内容的长度必须是16的倍数,如果不是16的倍数,就会出现异常 
     */  
	public static String encrypt(String content) {
		SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), KEY_ALGORITHM);
		Cipher cipher;
		try {
			//Cipher对象实际完成解密操作
			cipher = Cipher.getInstance(CIPHER_ALGORITHM);
			//用密钥加密明文(plainText),生成密文(cipherText)
			cipher.init(Cipher.ENCRYPT_MODE, keySpec);// 初始化
			//得到加密后的字节数组
			byte[] result = cipher.doFinal(content.getBytes(ENCODING));
			return Hex.encodeHexString(result);//转16进制
		} catch (Exception e) {
			LOGGER.error("加密 "+content+" 失败!!!", e);
			throw new RuntimeException("加密失败" + content, e);
		}
	}
	
	/**
	 * 解密参数
	 * @param content
	 * @return
	 */
	public static String decrypt(String content) {
		SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), KEY_ALGORITHM);
		Cipher cipher;
		try {
			cipher = Cipher.getInstance(CIPHER_ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, keySpec);// 初始化
			byte[] result = cipher.doFinal(Hex.decodeHex(content.toCharArray()));
			return new String(result);
		} catch (Exception e) {
			LOGGER.error("解密 " + content + " 失败!!!", e);
			throw new RuntimeException("参数解密失败" + content, e);
		}
	}
}


2、自定义一个过滤器拦截过滤get请求参数(spring boot 过滤器只需加上注解即可生效),这里通过过滤器+装饰模式自动解密参数。

/**
 * 自定义过滤器解密get请求参数
 * 一次请求只通过一次filter,而不需要重复执行。
 * @author: Alan Fu
 */
@Component
public class ParameterDecodeFilter extends OncePerRequestFilter {
	
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		if ("GET".equals(request.getMethod()) || StringUtils.isNotEmpty(request.getQueryString())) {
			super.doFilter(new RequestDecodeWrapper(request), response, filterChain);
		} else {
			super.doFilter(request, response, filterChain);
		}
	}
}

/**
 * 拦截设置包装请求参数(装饰模式)
 * @author: fuhongxing
 */
class RequestDecodeWrapper extends HttpServletRequestWrapper {
	private final static Logger LOGGER = LoggerFactory.getLogger(ParameterDecodeFilter.class);
	
	public RequestDecodeWrapper(HttpServletRequest request) {
		super(request);
	}

	@Override
	public Map<String, String[]> getParameterMap() {
		return super.getParameterMap();
	}

	@Override
	public Enumeration<String> getParameterNames() {
		return super.getParameterNames();
	}

	@Override
	public String[] getParameterValues(String name) {
		String[] values = super.getParameterValues(name);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				LOGGER.info("解密前=="+values[i]);
				values[i] = AesUtils.valueDecrypt(values[i]);
				LOGGER.info("解密后=="+values[i]);
			}
			LOGGER.info("encrypt 请求参数集:"+Arrays.toString(values));
		}
		
		return values;
	}
	
	@Override
	public String getParameter(String name) {
		if(super.getParameter(name)==null){
			return super.getParameter(name);
		}
		String value = AesUtils.valueDecrypt(super.getParameter(name));
		LOGGER.info("decrypt param="+value);
		return value;
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		return super.getInputStream();
	}
}




3、编写一个class继承TagSupport

/**
 * 自定义标签:加密get请求参数
 */
@Configuration
public class ValueEncrypt extends TagSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 944551876433969468L;
	private String var;
	
	@Override
	public int doStartTag() throws JspException {
		try {
			pageContext.getOut().write(AesUtils.valueEncrypt(var));
		} catch (IOException e) {
		}
		return EVAL_BODY_INCLUDE;
	}

	public String getVar() {
		return var;
	}

	public void setVar(String var) {
		this.var = var;
	}

}

4、编写tld文件对标签处理器类进行描述

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"    
    "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
	<tlib-version>1.0</tlib-version><!-- 标签库版本 -->
	<jsp-version>1.2</jsp-version>  <!-- 标签库要求的JSP规范版本 -->
	<short-name>encrypt</short-name>   <!-- JSP页面编写工具可以用来创建助记名的可选名字 -->
	<!-- 
         为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/gacl ,
         在Jsp页面中引用标签库时,需要通过uri找到标签库
         在Jsp页面中就要这样引入标签库:
		 <%@taglib uri="/security/encrypt" prefix="encrypt"%>
     -->
    <!-- <uri>/security/encrypt</uri> -->
	<tag>
		<name>value</name>
		<tag-class>com.security.tags.ValueEncrypt</tag-class>
		<body-content>JSP</body-content>
		<attribute>
			<name>var</name>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>  


5、jsp页面中使用标签

<!DOCTYPE HTML>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="encrypt" uri="/WEB-INF/tlds/encrypt.tld"%>
<html>
<head>
	<meta charset="UTF-8"/>
	<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <span style="white-space:pre">	</span><title>OAuth2 Login</title>
</head>
<body>
<h2 class="page-header">OAuth Login</h2>
<a href='/api?name=<encrypt:value var="1234"/>' />参数加密</a>
</body>
</html>


GET请求自动解密打印结果:

2016-08-25 13:52:03,063 [http-nio-8888-exec-3] INFO  [com.security.filter.ParameterDecodeFilter] - 解密前==fb454281dfdca6e42f2464434d326930
2016-08-25 13:52:03,070 [http-nio-8888-exec-3] INFO  [com.security.filter.ParameterDecodeFilter] - 解密后==1234
2016-08-25 13:52:03,070 [http-nio-8888-exec-3] INFO  [com.security.filter.ParameterDecodeFilter] - encrypt 请求参数集:[1234]



展开阅读全文

没有更多推荐了,返回首页