mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-25 11:43:29 +00:00
Configure ContentNegotiationStrategy in HttpSecurityConfiguration
Closes gh-11916
This commit is contained in:
parent
506e50bfd0
commit
cf3349f31a
@ -38,6 +38,8 @@ import org.springframework.security.config.annotation.web.configurers.DefaultLog
|
|||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
||||||
|
import org.springframework.web.accept.ContentNegotiationStrategy;
|
||||||
|
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
|
||||||
|
|
||||||
import static org.springframework.security.config.Customizer.withDefaults;
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
|
|
||||||
@ -65,6 +67,8 @@ class HttpSecurityConfiguration {
|
|||||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||||
.getContextHolderStrategy();
|
.getContextHolderStrategy();
|
||||||
|
|
||||||
|
private ContentNegotiationStrategy contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
||||||
this.objectPostProcessor = objectPostProcessor;
|
this.objectPostProcessor = objectPostProcessor;
|
||||||
@ -89,6 +93,11 @@ class HttpSecurityConfiguration {
|
|||||||
this.securityContextHolderStrategy = securityContextHolderStrategy;
|
this.securityContextHolderStrategy = securityContextHolderStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
void setContentNegotiationStrategy(ContentNegotiationStrategy contentNegotiationStrategy) {
|
||||||
|
this.contentNegotiationStrategy = contentNegotiationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(HTTPSECURITY_BEAN_NAME)
|
@Bean(HTTPSECURITY_BEAN_NAME)
|
||||||
@Scope("prototype")
|
@Scope("prototype")
|
||||||
HttpSecurity httpSecurity() throws Exception {
|
HttpSecurity httpSecurity() throws Exception {
|
||||||
@ -143,6 +152,7 @@ class HttpSecurityConfiguration {
|
|||||||
private Map<Class<?>, Object> createSharedObjects() {
|
private Map<Class<?>, Object> createSharedObjects() {
|
||||||
Map<Class<?>, Object> sharedObjects = new HashMap<>();
|
Map<Class<?>, Object> sharedObjects = new HashMap<>();
|
||||||
sharedObjects.put(ApplicationContext.class, this.context);
|
sharedObjects.put(ApplicationContext.class, this.context);
|
||||||
|
sharedObjects.put(ContentNegotiationStrategy.class, this.contentNegotiationStrategy);
|
||||||
return sharedObjects;
|
return sharedObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +60,16 @@ import org.springframework.security.web.header.writers.frameoptions.XFrameOption
|
|||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
import org.springframework.web.accept.ContentNegotiationStrategy;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.springframework.security.config.Customizer.withDefaults;
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||||
@ -311,6 +315,14 @@ public class HttpSecurityConfigurationTests {
|
|||||||
assertThat(configurer.configure).isTrue();
|
assertThat(configurer.configure).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWhenCustomContentNegotiationStrategyThenUses() throws Exception {
|
||||||
|
this.spring.register(CustomContentNegotiationStrategyConfig.class).autowire();
|
||||||
|
this.mockMvc.perform(get("/"));
|
||||||
|
verify(CustomContentNegotiationStrategyConfig.CNS, atLeastOnce())
|
||||||
|
.resolveMediaTypes(any(NativeWebRequest.class));
|
||||||
|
}
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
static class NameController {
|
static class NameController {
|
||||||
|
|
||||||
@ -489,6 +501,30 @@ public class HttpSecurityConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class CustomContentNegotiationStrategyConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.authorizeHttpRequests((requests) -> requests
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
);
|
||||||
|
// @formatter:on
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ContentNegotiationStrategy CNS = mock(ContentNegotiationStrategy.class);
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
static ContentNegotiationStrategy cns() {
|
||||||
|
return CNS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class DefaultConfigurer extends AbstractHttpConfigurer<DefaultConfigurer, HttpSecurity> {
|
static class DefaultConfigurer extends AbstractHttpConfigurer<DefaultConfigurer, HttpSecurity> {
|
||||||
|
|
||||||
boolean init;
|
boolean init;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user