Disable XMLHttpRequest for formLogin entry point

Previously the following:

http http://localhost:8080/user \
  "X-Requested-With:XMLHttpRequest" "Accept:text/plain"

Produced a 302 instead of a 401

Fixes gh-3887
This commit is contained in:
Rob Winch 2016-06-20 15:30:00 -05:00
parent 2a73f3cdf7
commit 66858e22ad
2 changed files with 26 additions and 4 deletions

View File

@ -15,6 +15,7 @@
*/
package org.springframework.security.config.annotation.web.configurers;
import java.util.Arrays;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
@ -37,7 +38,10 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.security.web.util.matcher.AndRequestMatcher;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
@ -243,10 +247,17 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(
MediaTypeRequestMatcher mediaMatcher = new MediaTypeRequestMatcher(
contentNegotiationStrategy, MediaType.APPLICATION_XHTML_XML,
new MediaType("image", "*"), MediaType.TEXT_HTML, MediaType.TEXT_PLAIN);
preferredMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
mediaMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
RequestMatcher preferredMatcher = new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher));
exceptionHandling.defaultAuthenticationEntryPointFor(
postProcess(authenticationEntryPoint), preferredMatcher);
}

View File

@ -93,7 +93,18 @@ class ExceptionHandlingConfigurerTests extends BaseSpringSpec {
then:
def entryPoints = delegateEntryPoint.entryPoints.keySet() as List
entryPoints[0].requestMatchers[1].contentNegotiationStrategy.class == HeaderContentNegotiationStrategy
entryPoints[1].contentNegotiationStrategy.class == HeaderContentNegotiationStrategy
entryPoints[1].requestMatchers[1].contentNegotiationStrategy.class == HeaderContentNegotiationStrategy
}
def "401 for text/plain and X-Requested-With:XMLHttpRequest"() {
setup:
loadConfig(HttpBasicAndFormLoginEntryPointsConfig)
when:
request.addHeader("Accept", MediaType.TEXT_PLAIN_VALUE)
request.addHeader("X-Requested-With", "XMLHttpRequest")
springSecurityFilterChain.doFilter(request,response,chain)
then:
response.status == HttpServletResponse.SC_UNAUTHORIZED
}
@EnableWebSecurity
@ -126,7 +137,7 @@ class ExceptionHandlingConfigurerTests extends BaseSpringSpec {
DelegatingAuthenticationEntryPoint delegateEntryPoint = findFilter(ExceptionTranslationFilter).authenticationEntryPoint
then:
def entryPoints = delegateEntryPoint.entryPoints.keySet() as List
entryPoints[0].contentNegotiationStrategy == OverrideContentNegotiationStrategySharedObjectConfig.CNS
entryPoints[0].requestMatchers[1].contentNegotiationStrategy == OverrideContentNegotiationStrategySharedObjectConfig.CNS
entryPoints[1].requestMatchers[1].contentNegotiationStrategy == OverrideContentNegotiationStrategySharedObjectConfig.CNS
}