Accept */* triggers 401 by Default

Fixes gh-4831
This commit is contained in:
Rob Winch 2017-11-16 09:58:29 -06:00
parent 64ad08e96d
commit 3e7e80a836
4 changed files with 66 additions and 2 deletions

View File

@ -169,13 +169,16 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>> 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.<RequestMatcher>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<B extends HttpSecurityBuilder<B>> extends
basicAuthenticationFilter = postProcess(basicAuthenticationFilter);
http.addFilter(basicAuthenticationFilter);
}
}
}

View File

@ -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 {

View File

@ -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 {
}

View File

@ -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();