How to read Body of Request multiple times with Spring Boot + Spring Security

Introduction

In the Spring Security authorization process (voting class, etc.) I think there are cases where you have to refer to the Body of the Request. (For example, when updating the DB with POST or PUT, etc.

However, in the HttpServletRequest class Body is a stream and can only be read once.

So this time, I will introduce how to read Body multiple times.

Thing you want to do

① Hold the information read from Body (2) Replace the Body acquisition source with the information in (1)

Preparation of replacement class

Stream class Set as the return type when calling HttpServletRequest.getInputStream () Use byte array for initialization

BufferedServletInputStream.java


public class BufferedServletInputStream extends ServletInputStream {

	private ByteArrayInputStream inputStream;

	//Initialize with byte array
	public BufferedServletInputStream(byte[] buffer) {
		this.inputStream = new ByteArrayInputStream(buffer);
	}

	@Override
	public int available() throws IOException {
		return inputStream.available();
	}

	@Override
	public int read() throws IOException {
		return inputStream.read();
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		return inputStream.read(b, off, len);
	}

	@Override
	public boolean isFinished() {
		return false;
	}

	@Override
	public boolean isReady() {
		return false;
	}

	@Override
	public void setReadListener(ReadListener listener) {

	}
}

Wrapper class for HttpServletRequest

BufferedServletRequestWrapper.java


public class BufferedServletRequestWrapper extends HttpServletRequestWrapper {

	private byte[] buffer;

	public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);

		//Get Stream from Request Body
		InputStream is = request.getInputStream();

		//Convert Stream to byte array and keep it in instance variable
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte buff[] = new byte[1024];
		int read;
		while ((read = is.read(buff)) > 0) {
			baos.write(buff, 0, read);
		}

		this.buffer = baos.toByteArray();
	}

	//Replace the body acquisition source with this method
	@Override
	public ServletInputStream getInputStream() throws IOException {
		//Initialize Stream class and return
		return new BufferedServletInputStream(this.buffer);
	}
}

Actually replace

Filter class Replace by request by OncePerRequestFilter

MultipleReadEnableFilter.java


@Component
public class MultipleReadEnableFilter extends OncePerRequestFilter {

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

		//Initialize the wrapper class from HttpServletRequest
		HttpServletRequest wrappedRequest = new BufferedServletRequestWrapper((HttpServletRequest) request);
		filterChain.doFilter(wrappedRequest, response);
	}
}

Set the created Filter in the Spring Security setting class

//Wrap to read inputStream multiple times
http.addFilter(multipleReadEnableFilter);

reference

Yamaoku Tsushin Special Issue

Recommended Posts

How to read Body of Request multiple times with Spring Boot + Spring Security
Let's find out how to receive in Request Body with REST API of Spring Boot
How to boot by environment with Spring Boot of Maven
[Spring Boot] I investigated how to implement post-processing of the received request.
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
How to use built-in h2db with spring boot
[Introduction to Spring Boot] Authentication function with Spring Security
How to use CommandLineRunner in Spring Batch of Spring Boot
Extract SQL to property file with jdbcTemplate of spring boot
How to set Spring Boot + PostgreSQL
How to use the same Mapper class in multiple data sources with Spring Boot + MyBatis
How to use ModelMapper (Spring boot)
How to create your own Controller corresponding to / error with Spring Boot
How to realize huge file upload with Rest Template of Spring
How Spring Security works with Hello World
How to split Spring Boot message file
Achieve BASIC authentication with Spring Boot + Spring Security
How to access Socket directly with the TCP function of Spring Integration
How to bind request parameters in list format with bean property in Spring
Hash passwords with Spring Boot + Spring Security (with salt, with stretching)
How to save to multiple tables with one input
How to search multiple columns with gem ransack
How to make Spring Boot Docker Image smaller
How to use Spring Boot session attributes (@SessionAttributes)
The story of raising Spring Boot 1.5 series to 2.1 series
Try LDAP authentication with Spring Security (Spring Boot) + OpenLDAP
Try to implement login function with Spring Boot
How to create multiple pull-down menus with ActiveHash
How to add a classpath in Spring Boot
[Java / Spring Boot] Spring security ④ --Implementation of login process
[Java / Spring Boot] Spring security ⑤ --Implementation of logout processing
How to perform UT with Excel as test data with Spring Boot + JUnit5 + DBUnit
Get Body part of HttpResponse with Filter of Spring
How to bind to property file in Spring Boot
Try to automate migration with Spring Boot Flyway
[Java] Article to add validation with Spring Boot 2.3.1.
I wanted to gradle spring boot with multi-project
I tried to clone a web application full of bugs with Spring Boot
How to set environment variables in the properties file of Spring boot application
How to define multiple orm.xml in Spring4, JPA2.1
Part2 Part II. How to proceed with Getting Started Spring Boot Reference Guide Note ①
[Spring Boot] How to refer to the property file
Spring Boot --How to set session timeout time
Create Spring Cloud Config Server with security with Spring Boot 2.0
How to request by passing an array to the query with HTTP Client of Ruby
Short hand to read JSON body from ServerHttpRequest with self-made WebFilter etc. with Spring WebFlux
Settings for connecting to MySQL with Spring Boot + Spring JDBC
[Rails] How to search by multiple values ​​with LIKE
How to set Dependency Injection (DI) for Spring Boot
How to apply HandlerInterceptor to http inbound-gateway of Spring Integration
How to write a unit test for Spring Boot 2
Automatically map DTOs to entities with Spring Boot API
[Java] How to omit spring constructor injection with Lombok
A memorandum of addiction to Spring Boot2 x Doma2
Spring Security usage memo: Cooperation with Spring MVC and Boot
How to deal with No template for interactive request
Access the built-in h2db of spring boot with jdbcTemplate
05. I tried to stub the source of Spring Boot
How to create a Spring Boot project in IntelliJ
I tried to reduce the capacity of Spring Boot
[Spring Boot] How to create a project (for beginners)