[JAVA] Comment lire le corps de la requête plusieurs fois avec Spring Boot + Spring Security

introduction

Dans le processus d'autorisation Spring Security (classe de vote, etc.) Je pense qu'il y a des cas où vous devez vous référer au corps de la requête. (Par exemple, lors de la mise à jour de la base de données avec POST ou PUT, etc.

Cependant, dans la classe HttpServletRequest Le corps est un flux et ne peut être lu qu'une seule fois.

Donc, cette fois, je vais vous présenter comment lire Body plusieurs fois.

Chose que tu veux faire

① Tenez les informations lues sur Body (2) Remplacez la source d'acquisition du corps par les informations de (1)

Préparation de la classe de remplacement

Classe de flux Défini comme type de retour lors de l'appel de HttpServletRequest.getInputStream () Utiliser un tableau d'octets pour l'initialisation

BufferedServletInputStream.java


public class BufferedServletInputStream extends ServletInputStream {

	private ByteArrayInputStream inputStream;

	//Initialiser avec un tableau d'octets
	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) {

	}
}

Classe Wrapper pour HttpServletRequest

BufferedServletRequestWrapper.java


public class BufferedServletRequestWrapper extends HttpServletRequestWrapper {

	private byte[] buffer;

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

		//Obtenir le flux à partir du corps de la demande
		InputStream is = request.getInputStream();

		//Convertir Stream en tableau d'octets et le conserver dans la variable d'instance
		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();
	}

	//Remplacez la source d'acquisition du corps par cette méthode
	@Override
	public ServletInputStream getInputStream() throws IOException {
		//Initialiser la classe Stream et retourner
		return new BufferedServletInputStream(this.buffer);
	}
}

Remplacer en fait

Classe de filtre Remplacer par requête par OncePerRequestFilter

MultipleReadEnableFilter.java


@Component
public class MultipleReadEnableFilter extends OncePerRequestFilter {

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

		//Initialiser la classe wrapper à partir de HttpServletRequest
		HttpServletRequest wrappedRequest = new BufferedServletRequestWrapper((HttpServletRequest) request);
		filterChain.doFilter(wrappedRequest, response);
	}
}

Définir le filtre créé dans la classe de paramètres Spring Security

//Envelopper pour lire l'entréeStream plusieurs fois
http.addFilter(multipleReadEnableFilter);

référence

Numéro spécial de Yamaoku Tsushin

Recommended Posts

Comment lire le corps de la requête plusieurs fois avec Spring Boot + Spring Security
Découvrons comment recevoir avec Request Body avec l'API REST de Spring Boot
Comment démarrer par environnement avec Spring Boot de Maven
[Spring Boot] J'ai étudié comment implémenter le post-traitement de la demande reçue.
Comment utiliser MyBatis2 (iBatis) avec Spring Boot 1.4 (Spring 4)
Comment utiliser h2db intégré avec Spring Boot
[Introduction à Spring Boot] Fonction d'authentification avec Spring Security
Comment utiliser CommandLineRunner dans Spring Batch of Spring Boot
Découpez SQL en fichier de propriété avec jdbcTemplate of spring boot
Comment configurer Spring Boot + PostgreSQL
Comment utiliser la même classe Mapper dans plusieurs sources de données avec Spring Boot + MyBatis
Comment utiliser ModelMapper (Spring boot)
Comment créer votre propre contrôleur correspondant à / error avec Spring Boot
Comment réaliser un téléchargement de fichiers volumineux avec Rest Template of Spring
Comment Spring Security fonctionne avec Hello World
Comment diviser un fichier de message Spring Boot
Obtenez une authentification BASIC avec Spring Boot + Spring Security
Comment accéder directement à Socket avec la fonction TCP de Spring Integration
Comment les propriétés de bean lient les paramètres de requête de style liste dans Spring
Hash des mots de passe avec Spring Boot + Spring Security (avec sel, avec étirement)
Comment enregistrer dans plusieurs tables avec une seule entrée
Comment réduire l'image de Spring Boot Docker
Comment utiliser les attributs de session Spring Boot (@SessionAttributes)
L'histoire de la montée de la série Spring Boot 1.5 à la série 2.1
Essayez l'authentification LDAP avec Spring Security (Spring Boot) + OpenLDAP
Essayez d'implémenter la fonction de connexion avec Spring Boot
Comment créer plusieurs menus déroulants avec ActiveHash
Comment ajouter un chemin de classe dans Spring Boot
Comment effectuer UT avec Excel en tant que données de test avec Spring Boot + JUnit5 + DBUnit
Obtenez la partie Body de HttpResponse avec Spring Filter
Comment se lier avec un fichier de propriétés dans Spring Boot
Essayez d'automatiser la migration avec Spring Boot Flyway
[Java] Article pour ajouter une validation avec Spring Boot 2.3.1.
Je voulais classer la botte à ressort dans un multi-projet
J'ai essayé de cloner une application Web pleine de bugs avec Spring Boot
Comment définir des variables d'environnement dans le fichier de propriétés de l'application Spring Boot
Comment définir plusieurs orm.xml dans Spring4, JPA2.1
Partie 2 Partie II. Comment procéder avec la mise en route Guide de référence de Spring Boot Remarque ①
[Spring Boot] Comment se référer au fichier de propriétés
Spring Boot - Comment définir le délai d'expiration de la session
Créez un serveur Spring Cloud Config en toute sécurité avec Spring Boot 2.0
Comment demander en passant un tableau à une requête avec le client HTTP de Ruby
Une petite main qui lit un corps JSON à partir de ServerHttpRequest avec un WebFilter auto-créé, etc. avec Spring WebFlux
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Comment définir l'injection de dépendance Spring Boot (DI)
Comment appliquer HandlerInterceptor à la passerelle entrante http de Spring Integration
Comment écrire un test unitaire pour Spring Boot 2
Mappez automatiquement DTO aux entités avec l'API Spring Boot
[Java] Comment omettre l'injection de constructeur de ressort avec Lombok
Un mémorandum de dépendance à Spring Boot2 x Doma2
Mémo d'utilisation de Spring Security: coopération avec Spring MVC et Boot
Comment traiter Aucun modèle de demande interactive
Accédez au h2db intégré de Spring Boot avec jdbcTemplate
05. J'ai essayé de supprimer la source de Spring Boot
Comment créer un projet Spring Boot dans IntelliJ
J'ai essayé de réduire la capacité de Spring Boot
[Spring Boot] Comment créer un projet (pour les débutants)