Spring全局加解密

来源:互联网 发布:双面羊绒缝合机 淘宝 编辑:程序博客网 时间:2024/06/05 07:00

需求:基于APP+后端服务(Spring框架),提供传输加密机制。

方案:采用AES加密,密钥的保护策略此处暂不讨论。这里主要讨论后端服务基于Spring下,如何方便的实现加解密。

方案一:APP端传输密文到后端接口,在每个具体的接口中实现参数解密,并在返回前加密结果。

优势:方案简单粗暴

劣势:当然这个方案是最LOW,也最繁琐的。如果是已有代码,涉及到大量接口修改,风险比较大。

方案二:在Filter过滤器实现,也是本文采用的。

基本思路:在Filter中可以获取到Request、Response对象,在Request中获取密文入参,解密再填充回去。在Response返回到客户端前,拦截明文再加密返回。

优势:1. 与业务代码解耦

   2. 统一处理,避免大量修改

   3. Filter支持路径匹配,可针对部分请求加解密。比如只针对APP传输加密,WEB请求不加密。

代码实现:(附件压缩包,上传了相关代码)

public class DecryptFilterProxy extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {// TODO Auto-generated method stubMap<String, String[]> m = new HashMap<String, String[]>(request.getParameterMap());ObjectMapper mapper = new ObjectMapper();// 获取加密数据String encryptData = (String) request.getParameter("data");if (!StringUtils.isEmpty(encryptData)) {String data = "";try {// 解密data = AesEncryptHelper.decrypt(encryptData);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return;}// 解析解密JSON字符串JsonNode node = mapper.readTree(data);Iterator<String> iter = node.fieldNames();// 重写Request参数while (iter.hasNext()) {String fieldName = iter.next();JsonNode j = node.get(fieldName);if (!j.isNull()) {String value = node.get(fieldName).asText();m.put(fieldName, new String[] { value });}}}// 利用包装类替换原request、responseHttpServletRequest req = new ParameterRequestWrapper((HttpServletRequest) request, m);ParameterResponseWrapper resp = new ParameterResponseWrapper((HttpServletResponse) response);super.doFilter(req, resp, filterChain);// 获取返回值内容String result = resp.getContent();JSONObject obj = JSONObject.fromObject(result);try {String encryptModel = AesEncryptHelper.encrypt(obj.getString("model"));obj.put("model", encryptModel);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();obj.put("message", "数据加密发生异常" + e.getMessage());}String encryptRespData = obj.toString();response.setContentLength(-1);PrintWriter out = response.getWriter();out.write(encryptRespData);out.flush();out.close();}


0 0
原创粉丝点击