[JAVA] Les en-têtes de réponse peuvent ne pas être affichés correctement dans Spring Security 4.1

introduction

Depuis le 22 septembre 2017, la version de Spring Security est 4.2.3, donc ce problème ne se produit pas: sueur:.

** PostScript 2018/9/12: ** ** Dans Spring Security 4.2.5, 5.0.2, l'ordre de l'application de filtre → écriture de l'en-tête est à nouveau modifié, donc le même problème se produit. De plus, il y a un rapport de suivi dans issue couvert dans l'article, et c'est `vider que le comportement diffère selon le serveur AP. Cela ressemble à la différence entre la taille du tampon et la taille du commit. ** **

Cependant, il semble que Spring Security hésite sur la spécification correcte, alors soyez prudent lors de la mise à niveau.

Environnement de confirmation

Spring Security
4.1.4.RELEASE (avec TERASOLUNA Server Framework for Java (5.3.0.RELEASE))
serveur AP
JBoss EAP 7.0.0

Pour sortir l'en-tête Cache-Control avec Spring Security en premier lieu

Lors de la sortie avec TERASOLUNA, décrivez l'élément headers de Spring Security dans spring-security.xml.

L'exemple suivant désactive les en-têtes appliqués par défaut et enregistre uniquement les composants qui ne génèrent que les en-têtes "Cache-Control" et "X-Content-Type-Options".

spring-security.xml


<sec:http>
	<sec:headers defaults-disabled="true">
		<sec:cache-control />
		<sec:content-type-options />
	</sec:headers>

Pourquoi l'en-tête de réponse n'est-il pas affiché uniquement pour 4.1?

Différence dans la procédure de processus d'écriture d'en-tête

La classe qui écrit l'en-tête est ʻorg.springframework.security.web.header.HeaderWriterFilter, qui est traitée par la méthode doFilterInternal`, mais l'implémentation a changé dans Spring Security 4.1.0 RC1.

Problème connexe: SEC-2728: Only write cache related headers if no other cache headers found #2953

↓ 4.0.1. Méthode doFilterInternal à RELEASE

HeaderWriterFilter.java


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

	for (HeaderWriter factory : headerWriters) {
		factory.writeHeaders(request, response);
	}
	filterChain.doFilter(request, response);
}

↓ 4.1.0 Méthode doFilterInternal sur RC1

HeaderWriterFilter.java


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

		HeaderWriterResponse headerWriterResponse = new HeaderWriterResponse(request,
				response, this.headerWriters);
		try {
			filterChain.doFilter(request, headerWriterResponse);
		}
		finally {
			headerWriterResponse.writeHeaders();
		}
	}

En 4.0.1, le traitement se fait dans l'ordre d'écriture d'en-tête → application de filtre, mais en 4.1.0, il est dans l'ordre d'application de filtre → d'écriture d'en-tête.

Qu'est-ce qui ne va pas?

En utilisant try-finally, l'en-tête est écrit même si une exception se produit dans le processus d'application de filtre, mais si le flux http est vidé dans le processus d'application de filtre, même si l'en-tête est écrit, il sera écrit côté client. Ne sera pas envoyé. (Je ne pouvais pas comprendre exactement quel était le problème lorsque j'ai appelé le problème de rapport de bogue: craintif :) Voici les problèmes cibles, veuillez donc vous reporter ici pour plus de détails.

Spring Security not writing http headers when the http stream was flushed by a participant of the filterChain. #3975

De quel type de réponse avez-vous besoin?

Élevons la version de Spring Security: smiley: Si vous ne pouvez pas facilement mettre à jour la version, remplacez le HeaderWriterFilter. Dans le numéro de rapport de bogue de ↑, le changement de HeaderWriterFilter est Revert, donc`HeaderWriter 4.1. Ce n'est pas grave si vous utilisez.

Comment remplacer HeaderWriterFilter

Si vous placez un HeaderWriterFilter autre que Spring Security 4.1 dans com.neriudon.sample.filter et que vous le nommez CustomizedHeaderWriterFilter, ce sera comme suit.

spring-security.xml


	<bean id="secureCacheControlHeadersWriter"
		class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
		<constructor-arg>
			<bean
				class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
				<constructor-arg value="/**" />
			</bean>
		</constructor-arg>
		<constructor-arg>
			<bean
				class="org.springframework.security.web.header.writers.CacheControlHeadersWriter" />
		</constructor-arg>
	</bean>

	<bean id="customizedHeaderWriterFilter" class="com.neriudon.sample.filter.CustomizedHeaderWriterFilter">
		<constructor-arg ref="secureCacheControlHeadersWriter" />
	</bean>

	<sec:http>
		<sec:headers disabled="true" />
		<sec:custom-filter position="HEADERS_FILTER"
			ref="customizedHeaderWriterFilter" />

Le point est

 <sec:headers disabled="true" />
        <sec:custom-filter position="HEADERS_FILTER"
            ref="customizedHeaderWriterFilter" />

C'est la partie de. Vous pouvez utiliser position pour le remplacer par votre propre filtre, mais vous devez définir headers disabled =" true " car il entre en conflit avec les filtres existants. Par conséquent, l'en-tête à envoyer au filtre à remplacer est spécifié. Cette partie est citée de Sortie de l'en-tête de sécurité pour chaque modèle de requête dans les directives TERASOLUNA. Fait.

Comment j'ai posté cet article

Quand j'ai augmenté la version de TERASOLUNA, l'en-tête n'était plus affiché. Il y a un commentaire que le comportement est différent dans Tomcat / JBoss même dans le problème du rapport de bogue, mais ... C'est profond: déçu_relieved:

Recommended Posts

Les en-têtes de réponse peuvent ne pas être affichés correctement dans Spring Security 4.1
En-tête de réponse de mémo d'utilisation de Spring Security
Sortie des journaux de demande et de réponse avec Spring Boot
[Résolu dans 5.2.1] Spring Security 5.2.0.RELEASE présente des incompatibilités non mentionnées dans la note de publication
JSESSIONID n'a pas pu être attribué à l'URL lors de l'utilisation de Spring Security
Sortie du journal Spring Boot au format json
Pour écrire des données de réponse directement dans Spring
Bean de sortie au format JSON au printemps