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

下面是“Springboot使用filter对response内容进行加密方式”的完整攻略:

一、添加依赖

在pom.xml文件中添加以下依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-crypto</artifactId>
</dependency>

二、编写Filter

新建一个类(例如:EncryptFilter),继承OncePerRequestFilter,并重写doFilterInternal方法,实现对response内容的加密:

import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.crypto.encrypt.BytesEncryptor;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Base64Utils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class EncryptFilter extends OncePerRequestFilter {

    private TextEncryptor encryptor;
    private RequestMatcher requestMatcher;

    public EncryptFilter(byte[] salt, String password, RequestMatcher requestMatcher) {
        BytesEncryptor bytesEncryptor = Encryptors.standard(password, new String(Hex.encode(salt)));
        encryptor = new BinaryEncryptor(bytesEncryptor);
        this.requestMatcher = requestMatcher;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if (requestMatcher.matches(request)) {
            EncryptResponseWrapper wrappedResponse = new EncryptResponseWrapper(response, encryptor);
            filterChain.doFilter(request, wrappedResponse);

            byte[] encryptedBytes = wrappedResponse.getEncryptBytes();
            response.setHeader("Content-Type", "application/octet-stream");
            response.setHeader("Content-Encoding", "encrypt");
            response.getOutputStream().write(Base64Utils.encode(encryptedBytes));
        } else {
            filterChain.doFilter(request, response);
        }
    }

    private static class EncryptResponseWrapper extends ServletOutputStream {

        private final ServletOutputStream delegate;
        private final TextEncryptor encryptor;
        private final byte[] buffer = new byte[8192];
        private int count = 0;

        EncryptResponseWrapper(HttpServletResponse response, TextEncryptor encryptor) throws IOException {
            delegate = response.getOutputStream();
            this.encryptor = encryptor;
        }

        @Override
        public void write(int b) throws IOException {
            if (count == buffer.length) {
                flush();
            }
            buffer[count++] = (byte) b;
        }

        public byte[] getEncryptBytes() {
             flush();
             return encryptor.encrypt(Arrays.copyOf(buffer, count)).getBytes();
        }

        @Override
        public void flush() throws IOException {
             if (count > 0) {
                 byte[] encryptedBytes = encryptor.encrypt(Arrays.copyOf(buffer, count)).getBytes();
                 delegate.write(encryptedBytes);
                 count = 0;
             }
        }
    }
}

三、配置Filter

在Springboot启动类中添加Filter:

@Configuration
public class AppConfig {

    @Bean
    public Filter encryptFilter() {
        byte[] salt = new byte[] {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
        String password = "password";
        RequestMatcher urlMatcher = new AntPathRequestMatcher("/api/**");  // 过滤/api/开头的URL
        return new EncryptFilter(salt, password, urlMatcher);
    }
}

四、进行测试

启动Springboot后,访问http://localhost:8080/api/test,可以看到Response内容被加密了。

另外一个示例:

假设要加密的内容不是字符串,而是一个POJO(如Person),可以修改EncryptFilter中的doFilterInternal方法:

if (requestMatcher.matches(request)) {
    EncryptResponseWrapper wrappedResponse = new EncryptResponseWrapper(response, encryptor);
    filterChain.doFilter(request, wrappedResponse);

    Gson gson = new Gson();
    byte[] encryptedBytes = encryptor.encrypt(gson.toJson(wrappedResponse.getEntity()).getBytes("UTF-8")).getBytes("UTF-8");
    response.setHeader("Content-Type", "application/octet-stream");
    response.setHeader("Content-Encoding", "encrypt");
    response.getOutputStream().write(Base64Utils.encode(encryptedBytes));
} else {
    filterChain.doFilter(request, response);
}

这样,我们就可以加密Person对象了。

以上就是“Springboot使用filter对response内容进行加密方式”的完整攻略。希望能对你有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot使用filter对response内容进行加密方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 详解Java Streams 中的异常处理

    详解Java Streams 中的异常处理 在 Java 8 中引入了 java.util.stream.Stream 对象,它为我们提供了一种基于lambda表达式的函数式编程方式,方便我们对集合、数组等数据进行快速处理。但是在使用 Stream 进行数据处理的过程中,我们也需要考虑一些异常问题,本文将详细讲解 Java Streams 中的异常处理方案。…

    Java 2023年5月27日
    00
  • Java8中 LocalDate和java.sql.Date的相互转换操作

    Java 8中提供了新的日期时间API,其中非常重要的一部分是LocalDate类。在某些情况下需要将LocalDate转换为java.sql.Date,或者将java.sql.Date转换为LocalDate。接下来,我们来详细讲解Java 8中LocalDate和java.sql.Date的相互转换操作。 1. 将LocalDate转换为java.sql…

    Java 2023年6月1日
    00
  • SpringBoot进行参数校验的方法详解

    SpringBoot进行参数校验的方法详解 一、为什么需要参数校验? 在实际开发中,我们常常需要对一些参数进行校验,防止参数不合法导致程序出错。比如在登录界面中,用户名和密码不能为空,当用户输入的用户名密码为空时,我们需要提示用户输入正确的用户名和密码。如果没有对参数进行校验,程序会直接抛出空指针异常,这是非常不可取的。 二、SpringBoot参数校验的方…

    Java 2023年5月19日
    00
  • SpringBoot 整合mybatis+mybatis-plus的详细步骤

    下面是 “SpringBoot整合MyBatis和MyBatis-Plus的详细步骤”。 1. 添加依赖 首先,在 pom.xml 中添加以下依赖: <!– SpringBoot 整合 MyBatis 依赖 –> <dependency> <groupId>org.mybatis.spring.boot</gro…

    Java 2023年5月20日
    00
  • Java lambda表达式与泛型整理总结

    本文主要介绍Java lambda表达式与泛型的相关概念,包括基本语法、使用场景和示例。使用Markdown语法进行排版,方便阅读。 Java lambda表达式 基本语法 Lambda表达式是JDK 1.8中引入的新特性,简化了编写匿名内部类的过程。其基本语法如下: (parameters) -> expression 或 (parameters) …

    Java 2023年5月26日
    00
  • Java输出链表倒数第k个节点

    下面是Java输出链表倒数第k个节点的完整攻略: 理解题意意义:输入一个链表,输出该链表中倒数第k个节点的值。 考虑边界条件:输入的链表为空或k不能大于链表长度。 定义两个指针,分别指向链表头部。让其中一个从0开始,先走k步,另一个开始走。然后两个指针同步走,直到其中一个到达链表尾部。另一个指针此时就是链表倒数第k个节点。 编写代码: public List…

    Java 2023年5月26日
    00
  • java导出json格式文件的示例代码

    下面是“Java导出JSON格式文件的示例代码”的完整攻略。 1. 简介 在Java程序设计中,我们常常需要将数据导出为JSON格式的文件。JSON格式文件可以被用于数据的持久化、传输和共享等场景。本篇攻略将介绍Java导出JSON格式文件的基本实现方法,并提供两条示例代码供您参考。 2. Jackson库的介绍 在Java中,Jackson是一个流行的JS…

    Java 2023年5月20日
    00
  • Java生成压缩文件的实例代码

    生成压缩文件是编程中常见的功能之一,Java在java.util.zip包下提供了ZipOutputStream和ZipEntry类,可以方便地生成zip压缩文件。本文分享Java生成压缩文件的实例代码。 1. 导入相关类 import java.io.File; import java.io.FileInputStream; import java.io.…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部