Springboot使用filter对response内容进行加密方式

目录
  • 使用filter对response内容进行加密
    • 编写加密类(AES)
    • 编写Filter类
    • 写配置类
  • Springboot数据加密传输
    • 创建加解密注解注解
    • 创建request解密类
    • 创建response加密类
    • 创建AES加密工具类
    • 创建加解密Filter类
    • 定义过滤器的拦截路径

使用filter对response内容进行加密

编写加密类(AES)

/**
 * aes加密解密
 */
public class AesEncryptUtils {
    //参数分别代表 算法名称/加密模式/数据填充方式
    private static String algorithmstr = "AES/ECB/PKCS5Padding";
    public static String getAlgorithmstr() {
        return algorithmstr;
    }
    /**
     * 加密
     * @param content 加密的字符串
     * @param encryptKey key值
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(algorithmstr);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
        byte[] b = cipher.doFinal(content.getBytes("utf-8"));
        return Base64.encodeBase64String(b);
    }
    /**
     * 解密
     * @param encryptStr 解密的字符串
     * @param decryptKey 解密的key值
     * @return
     * @throws Exception
     */
    public static String decrypt(String encryptStr, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(algorithmstr);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
        byte[] encryptBytes = Base64.decodeBase64(encryptStr);
        byte[] decryptBytes = cipher.doFinal(encryptBytes);
        return new String(decryptBytes);
    }
    public static void main(String[] args) throws Exception{
        String str  = "pp2bQLjabobRWp2T5Ro5/GlqWCigmkwHYnrOK11VZkTkIA2hSwnEi1sijfTV6Ozd/";
        System.out.println(decrypt(str,"f8db034bda44rtkb"));
    }
}

编写Filter类

/**
 * 过滤器拦截请求,实现加密解密功能
 *
 * @Component 将此Filter交给Spring容器管理
 * @WebFilter 通过WebFilter进行Filter声明,这样容器在进行部署的时候就会处理该Filter
 *
 */
@Component
public class EncryptFilter implements Filter {
    Logger log = LoggerFactory.getLogger(this.getClass());
    @Value("${admin.encrypt.excludeUrl}")
    private String ignoreStr;
    private String[] ignoreArr;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }
    /**
     * 有错误相应返回-44
     *
     * @param response
     * @throws IOException
     */
    private void getFailResponse(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        out = response.getWriter();
//        out.write("{\n" +
//                "    \"status\":"+ Constant.ENCRYPT_FAIL +",\n" +
//                "    \"message\": null,\n" +
//                "    \"data\": []\n" +
//                "}");
        //加密后的错误消息
        out.write("+D+JO8tuwkrNbxnTTLdqStifmQceT+LlYETnIG/JZKrbAn+gIiqIp3VbzBV1y6R8B7aY53VM2xHa7cY3Osbnqw==");
        out.flush();
        out.close();
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        if(ignoreArr==null){
            ignoreArr = ignoreStr.split(",");
        }
        HttpServletRequest HttpRequest=(HttpServletRequest)request;
        HttpServletResponse HttpResponse=(HttpServletResponse)response;
        boolean flag=isIgnore(HttpRequest,ignoreArr);
        if(flag) {
            try {
                chain.doFilter(HttpRequest, HttpResponse);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ServletException e) {
                e.printStackTrace();
            }
        }else{
            try{
                //响应处理  包装响应对象 res 并缓存响应数据
                ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
                //执行业务逻辑 交给下一个过滤器或servlet处理
                chain.doFilter(request, responseWrapper);
                byte[] resData = responseWrapper.getResponseData();
                //设置响应内容格式,防止解析响应内容时出错
//            responseWrapper.setContentType("text/plain;charset=UTF-8");
                //加密响应报文并响应
                String encryptBASE64 = AesEncryptUtils.encrypt(new String(resData),Constant.ENCRYPT_STR);
                PrintWriter out = response.getWriter();
                out.print(encryptBASE64);
                out.flush();
                out.close();
            }catch(Exception e){
                try {
                    getFailResponse((HttpServletResponse)response);
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
                e.printStackTrace();
            }
        }
}
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    /**
     * 哪些路径不处理
     * @param request
     * @param strArr
     * @return
     */
    public boolean isIgnore(HttpServletRequest request,String[] strArr) {
        String path=request.getRequestURI();
        for(String ignore:strArr) {
            if(path.contains(ignore)) {
                return true;
            }
        }
        return false;
    }
}

下图是对应的application.properties中的配置

其中用到了两个工具类

RequestWrapper

/**
 * @Description: 请求包装类
 * @Date: 2020/5/26 16:29
 */
public class RequestWrapper extends HttpServletRequestWrapper {
    private String requestBody = null;
    //请求体
    private HttpServletRequest req = null;
    //    private final byte[] body;//保存流的字节数组
    private final Map<String, String> reqHeaders=new HashMap<>();
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.req = request;
//        this.reqHeaders = new HashMap<String, String>();
//        String sessionStream = getRequestBodyStr(request);//读取流中的参数
//        body = sessionStream.getBytes(Charset.forName("UTF-8"));
    }
    public RequestWrapper(HttpServletRequest request, String requestBody) {
        super(request);
        this.requestBody = requestBody;
        this.req = request;
//        this.reqHeaders = request.get;
    }
    /**
     * @Description: 获取请求body
     * @Date: 2020/5/26 10:31
     * @Param: [request]
     * @Return: java.lang.String
     */
    public String getRequestBodyStr(final ServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (reader != null) {
                reader.close();
            }
        }
        return sb.toString();
    }
    /**
     * @Description: 复制输入流
     * @Param: [inputStream]
     * @Return: java.io.InputStream
     */
    public InputStream cloneInputStream(ServletInputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) > -1) {
            byteArrayOutputStream.write(buffer, 0, len);
        }
        byteArrayOutputStream.flush();
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(req.getCharacterEncoding()));
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }
    /**
     * 添加header的名称和值
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        reqHeaders.put(name, value);
    }
    @Override
    public String getHeader(String name) {
//        log.info("getHeader --->{}", name);
        String headerValue = super.getHeader(name);
        if (reqHeaders.containsKey(name)) {
            headerValue = reqHeaders.get(name);
        }
        return headerValue;
    }
    /**
     * 得到headers的名称
     */
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : reqHeaders.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }
    @Override
    public Enumeration<String> getHeaders(String name) {
//        log.info("getHeaders name --->>>>>>{}", name);
        List<String> values = Collections.list(super.getHeaders(name));
//        log.info("getHeaders value --->>>>>>{}", values);
        if (reqHeaders.containsKey(name)) {
            values = Arrays.asList(reqHeaders.get(name));
        }
        return Collections.enumeration(values);
    }
}

ResponseWrapper

/**
 * @Description: 响应包装类
 * @Date: 2020/5/26 16:29
 */
public class ResponseWrapper extends HttpServletResponseWrapper {
    private ByteArrayOutputStream buffer = null;
    private ServletOutputStream out = null;
    private PrintWriter writer = null;
    public ResponseWrapper(HttpServletResponse response) throws IOException {
        super(response);
        buffer = new ByteArrayOutputStream();// 真正存储数据的流
        out = new WapperedOutputStream(buffer);
        writer = new PrintWriter(new OutputStreamWriter(buffer,this.getCharacterEncoding()));
    }
    /** 重载父类获取outputstream的方法 */
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }
    /** 重载父类获取writer的方法 */
    @Override
    public PrintWriter getWriter() throws UnsupportedEncodingException {
        return writer;
    }
    /** 重载父类获取flushBuffer的方法 */
    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
        if (writer != null) {
            writer.flush();
        }
    }
    @Override
    public void reset() {
        buffer.reset();
    }
    /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
    public byte[] getResponseData() throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }
    /** 内部类,对ServletOutputStream进行包装 */
    private class WapperedOutputStream extends ServletOutputStream {
        private ByteArrayOutputStream bos = null;
        public WapperedOutputStream(ByteArrayOutputStream stream)
                throws IOException {
            bos = stream;
        }
        @Override
        public void write(int b) throws IOException {
            bos.write(b);
        }
        @Override
        public void write(byte[] b) throws IOException {
            bos.write(b, 0, b.length);
        }
        @Override
        public boolean isReady() {
            return false;
        }
        @Override
        public void setWriteListener(WriteListener writeListener) {
        }
    }
}

写配置类

@Configuration
public class WebConfiguration {
    @Autowired
    private EncryptFilter encryptFilter;
    @Bean
    public FilterRegistrationBean registFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(encryptFilter);
        registration.addUrlPatterns("/*");
        registration.setName("EncryptFilter");
        registration.setOrder(1);
//        registration.setEnabled(false);
        return registration;
    }

    //做跨域处理,跟这个filter没关系
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("*")
                        .allowCredentials(true)
                        .allowedMethods("*")
                        .allowedHeaders("*")
                        .maxAge(3600);
            }
        };
    }
}

Springboot数据加密传输

创建加解密注解注解

对于拦截路径上全部采用数据加解密处理,如果有部分接口不需要加解密处理的话,在方法上或者类上加上此注解即可不做加解密处理

package com.hars.common.infrastructure.validation.security;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 加解密注解
 *
 * @author Huangbigao
 * @date 2020/8/29 11:02
 */
@Documented
@Target({ElementType.METHOD, ElementType.TYPE,})
@Retention(RetentionPolicy.RUNTIME)
public @interface CryptoDecryptionSecurity {
    /**
     * 是否加解密,默认加解密
     *
     * @return
     */
    boolean cryptoDecryption() default true;
    /**
     * 是否进行request 解密,默认进行解密
     *
     * @return
     */
    boolean requestDecryption() default true;
    /**
     * 是否对输出结果进行加密,默认进行加密
     *
     * @return
     */
    boolean responseCrypto() default true;
}

ps:注解使用

 	@CryptoDecryptionSecurity(responseCrypto = false)
    @ApiOperation(value = "微信公众号验证业务处理接口")
    @GetMapping(value = "/handle/{appid}", produces = "text/plain;charset=utf-8")
    public String authHandle(@PathVariable String appid,
                             @RequestParam(name = "signature", required = false) String signature,
                             @RequestParam(name = "timestamp", required = false) String timestamp,
                             @RequestParam(name = "nonce", required = false) String nonce,
                             @RequestParam(name = "echostr", required = false) String echostr,
                             HttpServletRequest request) {
        return weChatMpService.authHandle(appid, signature, timestamp, nonce, echostr, request);
    }

创建request解密类

package com.hars.common.infrastructure.utils.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hars.common.infrastructure.utils.aes.AesUtil;
import com.hars.common.infrastructure.utils.http.HttpContextUtil;
import com.hars.common.infrastructure.utils.string.StringUtil;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.Assert;
/**
 * @author Huangbigao
 * @date 2020/8/29 10:12
 */
public class DecryptionRequestUtil extends HttpServletRequestWrapper {
    private static final String APPLICATION_JSON = "application/json";
    /**
     * 所有参数的Map集合
     */
    private Map<String, String[]> parameterMap;
    /**
     * 输入流
     */
    private InputStream inputStream;
    private final boolean valueValid = true;
    public DecryptionRequestUtil(HttpServletRequest request, String password) {
        super(request);
        String encrypt;
        String contentType = request.getHeader("Content-Type");
        if (contentType != null && contentType.contains(APPLICATION_JSON)) {
            //json
            String bodyStr = HttpContextUtil.getBodyString(request);
            if (StringUtil.isBlank(bodyStr)){
                return;
            }
            encrypt = (String) JSON.parseObject(bodyStr).get("encrypt");
        } else {
            // url
            encrypt = request.getParameter("encrypt");
        }
        String jsonData = AesUtil.decrypt(encrypt, password);
        if (StringUtil.isBlank(jsonData)){
            return;
        }
        if (contentType != null && contentType.contains(APPLICATION_JSON)) {
            if (this.inputStream == null) {
                this.inputStream = new DecryptionInputStream(new ByteArrayInputStream(jsonData.getBytes()));
            }
        }
        parameterMap = buildParams(jsonData);
    }
    private Map<String, String[]> buildParams(String src) {
        Map<String, String[]> map = new HashMap<>();
        Map<String, String> params = JSONObject.parseObject(src, new TypeReference<Map<String, String>>() {
        });
        for (String key : params.keySet()) {
            map.put(key, new String[]{params.get(key)});
        }
        return map;
    }
    @Override
    public String getParameter(String name) {
        String[] values = getParameterMap().get(name);
        if (valueValid){
            if (values != null) {
                return (values.length > 0 ? values[0] : null);
            }
            return super.getParameter(name);
        }else {
            return (values.length > 0 ? values[0] : null);
        }
    }
    @Override
    public String[] getParameterValues(String name) {
        String[] values = getParameterMap().get(name);
        if (valueValid){
            if (values != null) {
                return values;
            }
            return super.getParameterValues(name);
        }else {
            return values;
        }
    }
    @Override
    public Enumeration<String> getParameterNames() {
        Map<String, String[]> multipartParameters = getParameterMap();
        if (valueValid){
            if (multipartParameters.isEmpty()) {
                return super.getParameterNames();
            }
        }else {
            if (multipartParameters.isEmpty()) {
                return null;
            }
        }
        Set<String> paramNames = new LinkedHashSet<>();
        Enumeration<String> paramEnum = super.getParameterNames();
        while (paramEnum.hasMoreElements()) {
            paramNames.add(paramEnum.nextElement());
        }
        paramNames.addAll(multipartParameters.keySet());
        return Collections.enumeration(paramNames);
    }
    @Override
    public Map<String, String[]> getParameterMap() {
        if (valueValid){
            return parameterMap == null ? super.getParameterMap() : parameterMap;
        }else {
            return parameterMap == null ? new HashMap<>() : parameterMap;
        }
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (valueValid){
            return this.inputStream == null ? super.getInputStream() : (ServletInputStream) this.inputStream;
        }else {
            return this.inputStream == null ? null : (ServletInputStream) this.inputStream;
        }
    }
    /**
     * 自定义ServletInputStream
     */
    private class DecryptionInputStream extends ServletInputStream {
        private final InputStream sourceStream;
        /**
         * Create a DelegatingServletInputStream for the given source stream.
         *
         * @param sourceStream the source stream (never {@code null})
         */
        public DecryptionInputStream(InputStream sourceStream) {
            Assert.notNull(sourceStream, "Source InputStream must not be null");
            this.sourceStream = sourceStream;
        }
        @Override
        public int read() throws IOException {
            return this.sourceStream.read();
        }
        @Override
        public void close() throws IOException {
            super.close();
            this.sourceStream.close();
        }
        @Override
        public boolean isFinished() {
            return false;
        }
        @Override
        public boolean isReady() {
            return false;
        }
        @Override
        public void setReadListener(ReadListener readListener) {
        }
    }
}

创建response加密类

package com.hars.common.infrastructure.utils.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
 * @author Huangbigao
 * @date 2020/8/29 13:11
 */
public class ResponseWrapperUtil extends HttpServletResponseWrapper {
    private ByteArrayOutputStream buffer;
    private ServletOutputStream out;
    public ResponseWrapperUtil(HttpServletResponse httpServletResponse) {
        super(httpServletResponse);
        buffer = new ByteArrayOutputStream();
        out = new WrapperOutputStream(buffer);
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }
    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
    }
    public byte[] getContent() throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }
    private static class WrapperOutputStream extends ServletOutputStream {
        private ByteArrayOutputStream bos;
        WrapperOutputStream(ByteArrayOutputStream bos) {
            this.bos = bos;
        }
        @Override
        public void write(int b)
                throws IOException {
            bos.write(b);
        }
        @Override
        public boolean isReady() {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public void setWriteListener(WriteListener arg0) {
            // TODO Auto-generated method stub
        }
    }
}

创建AES加密工具类

package com.hars.common.infrastructure.utils.aes;
import com.hars.common.infrastructure.utils.string.StringUtil;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;
/**
 * AES 加解密 工具类
 *
 * @author Huangbigao
 * @date 2020/8/28 15:17
 */
@Slf4j
public class AesUtil {
    /**
     * AES解密
     *
     * @param content  密文
     * @param password 秘钥,必须为16个字符组成
     * @return 明文
     */
    public static String decrypt(String content, String password) {
        try {
            if (StringUtil.isBlank(content) || StringUtil.isBlank(password)) {
                return null;
            }
            byte[] encryptByte = Base64.getDecoder().decode(content);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password.getBytes(), "AES"));
            byte[] decryptBytes = cipher.doFinal(encryptByte);
            return new String(decryptBytes);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }
    /**
     * AES加密
     *
     * @param content  明文
     * @param password 秘钥,必须为16个字符组成
     * @return 密文
     */
    public static String encrypt(String content, String password) {
        try {
            if (StringUtil.isBlank(content) || StringUtil.isBlank(password)) {
                return null;
            }
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password.getBytes(), "AES"));
            byte[] encryptStr = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptStr);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

创建加解密Filter类

package com.hars.user.infrastructure.filter;
import com.alibaba.fastjson.JSON;
import com.hars.common.infrastructure.utils.aes.AesUtil;
import com.hars.common.infrastructure.utils.filter.DecryptionRequestUtil;
import com.hars.common.infrastructure.utils.filter.ResponseWrapperUtil;
import com.hars.common.infrastructure.validation.security.CryptoDecryptionSecurity;
import com.hars.result.infrastructure.advice.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
/**
 * @author Huangbigao
 * @date 2020/8/28 16:26
 */
public class CryptoDecryptionFilter implements Filter {
    //方法映射集
    private List<HandlerMapping> handlerMappings;
    public CryptoDecryptionFilter(ApplicationContext applicationContext) {
        Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext,
                HandlerMapping.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.handlerMappings = new ArrayList<>(matchingBeans.values());
            AnnotationAwareOrderComparator.sort(this.handlerMappings);
        }
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        //判断方法上是否存在注解,如果不存在,默认加解密
        //类上的注解
        CryptoDecryptionSecurity classFlag = null;
        //方法上的注解
        CryptoDecryptionSecurity methodFlag = null;
        try {
            HandlerExecutionChain handlerExecutionChain = getHandler(httpServletRequest);
            Object handler = handlerExecutionChain != null ? handlerExecutionChain.getHandler() : null;
            if (handler instanceof HandlerMethod) {
                HandlerMethod method = (HandlerMethod) handler;
                classFlag = method.getBeanType().getAnnotation(CryptoDecryptionSecurity.class);
                methodFlag = method.getMethodAnnotation(CryptoDecryptionSecurity.class);
                //如果方法注解存在,且不加密,则直接返回
                if (methodFlag != null && !methodFlag.cryptoDecryption()) {
                    chain.doFilter(request, response);
                    return;
                }
                //如果类注解存在,且不加密,则直接返回
                if (classFlag != null && !classFlag.cryptoDecryption()) {
                    chain.doFilter(request, response);
                    return;
                }
            }
        } catch (Exception e) {
            response.setContentType("application/json; charset=UTF-8");
            response.getWriter().write(JSON.toJSONString(Response.error("该请求无效", 601)));
            return;
        }
        CryptoDecryptionSecurity currentFlag = null;
        if (methodFlag != null) {
            currentFlag = methodFlag;
        } else if (classFlag != null) {
            currentFlag = classFlag;
        }
        //加解密密码
        String password = "Hbg584782648!@hb";
        ResponseWrapperUtil responseWrapper = null;
        //加解密处理
        if (currentFlag == null || (currentFlag.requestDecryption() && currentFlag.responseCrypto())) {
            ServletRequest requestWrapper = new DecryptionRequestUtil(httpServletRequest, password);
            responseWrapper = new ResponseWrapperUtil(httpServletResponse);
            chain.doFilter(requestWrapper, responseWrapper);
        } else if (currentFlag.requestDecryption() && !currentFlag.responseCrypto()) {
            ServletRequest requestWrapper = new DecryptionRequestUtil(httpServletRequest, password);
            chain.doFilter(requestWrapper, response);
        } else if (!currentFlag.requestDecryption() && currentFlag.responseCrypto()) {
            responseWrapper = new ResponseWrapperUtil(httpServletResponse);
            chain.doFilter(request, responseWrapper);
        } else {
            chain.doFilter(request, response);
        }
        if (responseWrapper != null) {
            byte[] content = responseWrapper.getContent();//获取返回值
            //判断是否有值
            if (content.length > 0) {
                String result = new String(content, "UTF-8");
                //加密
                String encryptStr = AesUtil.encrypt(result, password);
                //把返回值输出到客户端
                ServletOutputStream out = response.getOutputStream();
                out.write(encryptStr.getBytes());
                out.flush();
            }
        }
    }
    /**
     * 获取访问目标方法
     *
     * @param request
     * @return HandlerExecutionChain
     * @throws Exception
     */
    private HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        if (this.handlerMappings != null) {
            for (HandlerMapping hm : this.handlerMappings) {
                HandlerExecutionChain handler = hm.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }
        return null;
    }
}

定义过滤器的拦截路径

	@Autowired
    private ApplicationContext applicationContext;

	/**
     * 添加加解密过滤器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean encryptionDataFilterRegistration() {
        FilterRegistrationBean<CryptoDecryptionFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CryptoDecryptionFilter(applicationContext));
        registration.addUrlPatterns("/*");
        registration.setName("cryptoDecryptionFilter");
        registration.setOrder(2);
        return registration;
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot中使用com.alibaba.druid.filter.config.ConfigTools对数据库密码加密的方法

    SpringBoot中使用com.alibaba.druid.filter.config.ConfigTools对数据库密码加密 1.在本地Maven仓库中打开Powershell2.输入命令,然后点击回车3.将生成公钥和加密的数据库密码配置到SpringBoot项目中的yml配置文件中druid的pom版本 1.在本地Maven仓库中打开Powershell 2.输入命令,然后点击回车 scotttiger为未加密的数据库密码 privateKey为生成的私钥 publicKey为生成的公钥

  • Spring Boot的filter(过滤器)简单使用实例详解

    过滤器(Filter)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public FilterRegistrationBean indexFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(new IndexFilter()); registration.addUrlPatterns("/&quo

  • springboot中filter的用法详解

    一.在spring的应用中我们存在两种过滤的用法,一种是拦截器.另外一种当然是过滤器.我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别. 二.filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter

  • SpringBoot拦截器Filter的使用方法详解

    前言: 最新Servlet 3.0拦截器的使用 1.pom.xml添加需要使用的依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/x

  • Springboot使用filter对response内容进行加密方式

    目录 使用filter对response内容进行加密 编写加密类(AES) 编写Filter类 写配置类 Springboot数据加密传输 创建加解密注解注解 创建request解密类 创建response加密类 创建AES加密工具类 创建加解密Filter类 定义过滤器的拦截路径 使用filter对response内容进行加密 编写加密类(AES) /** * aes加密解密 */ public class AesEncryptUtils { //参数分别代表 算法名称/加密模式/数据填充方式

  • php加密之discuz内容经典加密方式实例详解

    本文实例讲述了php加密之discuz内容经典加密方式.分享给大家供大家参考,具体如下: 导读:有的时候,我们希望对表里的某些敏感字段进行加密,想了好长时间没有比较好的解决方案,后台在网上查了查,放心discuz论坛的这种方案对这种情况解决的不错,特copy过来,给大家分享一下,代码如下: header ( "Content-type:text/html;charset=UTF-8" ); echo $string='花园路888号'; echo '<hr/>加密有效期10

  • Spring Security如何实现升级密码加密方式详解

    目录 本章内容 密码加密方式怎么升级? 升级方案源码 实战 第一种方式: Spring Bean 他是怎么自动升级到BCrypt加密方式的? 第二种方式: 多继承接口方式 第三种方式: HttpSecurity直接添加 本章内容 密码加密方式怎么升级? spring security底层怎么实现的密码加密方式升级? 密码加密方式怎么升级? 前面我们学过DelegatingPasswordEncoder类,但是不清楚他到底是做什么的,我也没讲的很清楚.所以呢,我们就重新再讲一讲它的另一个实际应用.

  • SpringBoot使用Filter实现签名认证鉴权的示例代码

    情景说明 鉴权,有很多方案,如:SpringSecurity.Shiro.拦截器.过滤器等等.如果只是对一些URL进行认证鉴权的话,我们完 全没必要引入SpringSecurity或Shiro等框架,使用拦截器或过滤器就足以实现需求.         本文介绍如何使用过滤器Filter实现URL签名认证鉴权. 本人测试软硬件环境:Windows10.Eclipse.SpringBoot.JDK1.8 准备工作 第一步:在pom.xml中引入相关依赖 <dependencies> <dep

  • SpringBoot注册Filter的两种实现方式

    springboot版本:2.2.5 一.filter注册 springboot中添加filter有两种方式: 1.实现方法一 package com.example.demo.filter1; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.Servl

  • springboot中request和response的加解密实现代码

    目录 1.新建一个springboot工程,pom依赖如下 2.自定义加密.解密的注解 3.加密算法 4.对请求数据进行解密处理 5.对响应数据进行加密处理 6.加解密的key的配置类,从配置文件中读取 7.测试 在系统开发中,需要对请求和响应分别拦截下来进行解密和加密处理,在springboot中提供了RequestBodyAdviceAdapter和ResponseBodyAdvice,利用这两个工具可以非常方便的对请求和响应进行预处理. 1.新建一个springboot工程,pom依赖如下

  • SpringBoot 过滤器 Filter使用实例详解

    目录 简介 用法 功能 实现 简介 过滤器是AOP(面向切面编程)思想的具体实现.可以过滤浏览器发出的请求,并且决定放行请求还是中断请求. 在浏览器对服务器发起请求或者服务器对浏览器响应,都会经过过滤器. 基于过滤器的机制,我们可以在过滤器中对请求和响应做一些处理,可以在过滤器中决定是否放行,例如:校验请求中有没有敏感字符串,校验有没有Session,实现URL级别的权限控制.压缩响应信息.编码格式等. 用法 在spring的应用中我们存在两种过滤的用法,一种是拦截器.另外一种当然是过滤器.我们

  • SpringBoot实现Mysql使用MD5进行密码加密的示例

    项目开发中为了保护用户隐私安全,一般都会用MD5进行密码加密 以下就简单举例SpringBoot 实现Mysql使用MD5进行密码加密做一个简单的例子 看下数据库,这边简单做了用户表进行测试 pom.xml添加依赖引用 <!--MD5加密 对注册的密码进行加密操作--> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId>

  • springboot使用filter获取自定义请求头的实现代码

    有个钱包项目,本来用的是微服务这一套,后来感觉没必要,重构成了简单的springboot项目,但是token校验重构完之后出问题了,之前写filter走的是springgateway,基于GatewayFilter实现,重构了之后基于filter,然后当请求进入过滤器的时候,发现不能获取到请求的自定义请求头. String token = request.getHeader("token"); // null String id = request.getHeader("id

  • Springboot整合Shiro之加盐MD5加密的方法

    1.自定义realm,在Shiro的配置类中加入以下bean /** * 身份认证 realm */ @Bean public MyShiroRealm myShiroRealm(){ MyShiroRealm myShiroRealm = new MyShiroRealm(); System.out.println("myShiroRealm 注入成功"); return myShiroRealm; } 2.重写方法 // 身份认证 @Override protected Authe

随机推荐