下面是“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技术站