diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java index d90b568bb1..a1d042fbd4 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java @@ -169,13 +169,16 @@ public final class HttpBasicConfigurer> extends MediaType.MULTIPART_FORM_DATA, MediaType.TEXT_XML); restMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); + MediaTypeRequestMatcher allMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy, MediaType.ALL); + allMatcher.setUseEquals(true); + RequestMatcher notHtmlMatcher = new NegatedRequestMatcher( new MediaTypeRequestMatcher(contentNegotiationStrategy, MediaType.TEXT_HTML)); RequestMatcher restNotHtmlMatcher = new AndRequestMatcher( Arrays.asList(notHtmlMatcher, restMatcher)); - RequestMatcher preferredMatcher = new OrRequestMatcher(Arrays.asList(X_REQUESTED_WITH, restNotHtmlMatcher)); + RequestMatcher preferredMatcher = new OrRequestMatcher(Arrays.asList(X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher)); registerDefaultEntryPoint(http, preferredMatcher); registerDefaultLogoutSuccessHandler(http, preferredMatcher); @@ -218,4 +221,4 @@ public final class HttpBasicConfigurer> extends basicAuthenticationFilter = postProcess(basicAuthenticationFilter); http.addFilter(basicAuthenticationFilter); } -} \ No newline at end of file +} diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerTests.groovy index 12c9ab4b26..aad5e4242f 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerTests.groovy @@ -15,6 +15,9 @@ */ package org.springframework.security.config.annotation.web.configurers +import org.springframework.security.core.userdetails.User +import org.springframework.security.provisioning.InMemoryUserDetailsManager + import javax.servlet.http.HttpServletResponse import org.springframework.context.annotation.Bean; @@ -86,6 +89,17 @@ class ExceptionHandlingConfigurerTests extends BaseSpringSpec { MediaType.TEXT_XML_VALUE | HttpServletResponse.SC_UNAUTHORIZED } + // gh-4831 + def "Accept */* is Basic by default"() { + setup: + loadConfig(DefaultSecurityConfig) + when: + request.addHeader("Accept", MediaType.ALL_VALUE) + springSecurityFilterChain.doFilter(request,response,chain) + then: + response.status == HttpServletResponse.SC_UNAUTHORIZED + } + def "ContentNegotiationStrategy defaults to HeaderContentNegotiationStrategy"() { when: loadConfig(HttpBasicAndFormLoginEntryPointsConfig) @@ -107,6 +121,20 @@ class ExceptionHandlingConfigurerTests extends BaseSpringSpec { response.status == HttpServletResponse.SC_UNAUTHORIZED } + @EnableWebSecurity + static class DefaultSecurityConfig { + + @Bean + public InMemoryUserDetailsManager userDetailsManager() { + return new InMemoryUserDetailsManager(User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build() + ); + } + } + @EnableWebSecurity static class HttpBasicAndFormLoginEntryPointsConfig extends WebSecurityConfigurerAdapter { diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/LogoutConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/LogoutConfigurerTests.groovy index 3ca43f1040..69168d509a 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/LogoutConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/LogoutConfigurerTests.groovy @@ -16,6 +16,7 @@ package org.springframework.security.config.annotation.web.configurers import org.springframework.http.HttpStatus +import org.springframework.http.MediaType import org.springframework.security.config.annotation.AnyObjectPostProcessor import org.springframework.security.config.annotation.BaseSpringSpec import org.springframework.security.config.annotation.web.builders.HttpSecurity @@ -212,6 +213,20 @@ class LogoutConfigurerTests extends BaseSpringSpec { response.status == 204 } + // gh-4831 + def "LogoutConfigurer content negotiation all 201"() { + setup: + loadConfig(LogoutHandlerContentNegotiation) + when: + login() + request.method = 'POST' + request.servletPath = '/logout' + request.addHeader('Accept', MediaType.ALL_VALUE) + springSecurityFilterChain.doFilter(request,response,chain) + then: + response.status == 204 + } + @EnableWebSecurity static class LogoutHandlerContentNegotiation extends WebSecurityConfigurerAdapter { } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java index 89de5271a2..1831ac5811 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java @@ -26,6 +26,7 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.http.MediaType; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.test.SpringTestRule; import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration; @@ -87,6 +88,23 @@ public class EnableWebFluxSecurityTests { .expectBody().isEmpty(); } + // gh-4831 + @Test + public void defaultMediaAllThenUnAuthorized() { + this.spring.register(Config.class).autowire(); + + WebTestClient client = WebTestClientBuilder + .bindToWebFilters(this.springSecurityFilterChain) + .build(); + + client.get() + .uri("/") + .accept(MediaType.ALL) + .exchange() + .expectStatus().isUnauthorized() + .expectBody().isEmpty(); + } + @Test public void authenticateWhenBasicThenNoSession() { this.spring.register(Config.class).autowire();