Add new interfaces for CSRF request processing
Issue gh-4001 Issue gh-11456
This commit is contained in:
committed by
Steve Riesenberg
parent
ff6fd78d64
commit
86fbb8db07
+36
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,6 +36,8 @@ import org.springframework.security.web.csrf.CsrfAuthenticationStrategy;
|
||||
import org.springframework.security.web.csrf.CsrfFilter;
|
||||
import org.springframework.security.web.csrf.CsrfLogoutHandler;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRequestResolver;
|
||||
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.MissingCsrfTokenException;
|
||||
@@ -89,7 +91,9 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
|
||||
private SessionAuthenticationStrategy sessionAuthenticationStrategy;
|
||||
|
||||
private String csrfRequestAttributeName;
|
||||
private CsrfTokenRequestAttributeHandler requestAttributeHandler;
|
||||
|
||||
private CsrfTokenRequestResolver requestResolver;
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
@@ -127,12 +131,25 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link CsrfFilter#setCsrfRequestAttributeName(String)}
|
||||
* @param csrfRequestAttributeName the attribute name to set the CsrfToken on.
|
||||
* @return the {@link CsrfConfigurer} for further customizations.
|
||||
* Specify a {@link CsrfTokenRequestAttributeHandler} to use for making the
|
||||
* {@code CsrfToken} available as a request attribute.
|
||||
* @param requestAttributeHandler the {@link CsrfTokenRequestAttributeHandler} to use
|
||||
* @return the {@link CsrfConfigurer} for further customizations
|
||||
*/
|
||||
public CsrfConfigurer<H> csrfRequestAttributeName(String csrfRequestAttributeName) {
|
||||
this.csrfRequestAttributeName = csrfRequestAttributeName;
|
||||
public CsrfConfigurer<H> csrfTokenRequestAttributeHandler(
|
||||
CsrfTokenRequestAttributeHandler requestAttributeHandler) {
|
||||
this.requestAttributeHandler = requestAttributeHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a {@link CsrfTokenRequestResolver} to use for resolving the token value
|
||||
* from the request.
|
||||
* @param requestResolver the {@link CsrfTokenRequestResolver} to use
|
||||
* @return the {@link CsrfConfigurer} for further customizations
|
||||
*/
|
||||
public CsrfConfigurer<H> csrfTokenRequestResolver(CsrfTokenRequestResolver requestResolver) {
|
||||
this.requestResolver = requestResolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -214,9 +231,6 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
@Override
|
||||
public void configure(H http) {
|
||||
CsrfFilter filter = new CsrfFilter(this.csrfTokenRepository);
|
||||
if (this.csrfRequestAttributeName != null) {
|
||||
filter.setCsrfRequestAttributeName(this.csrfRequestAttributeName);
|
||||
}
|
||||
RequestMatcher requireCsrfProtectionMatcher = getRequireCsrfProtectionMatcher();
|
||||
if (requireCsrfProtectionMatcher != null) {
|
||||
filter.setRequireCsrfProtectionMatcher(requireCsrfProtectionMatcher);
|
||||
@@ -233,6 +247,12 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
if (sessionConfigurer != null) {
|
||||
sessionConfigurer.addSessionAuthenticationStrategy(getSessionAuthenticationStrategy());
|
||||
}
|
||||
if (this.requestAttributeHandler != null) {
|
||||
filter.setRequestAttributeHandler(this.requestAttributeHandler);
|
||||
}
|
||||
if (this.requestResolver != null) {
|
||||
filter.setRequestResolver(this.requestResolver);
|
||||
}
|
||||
filter = postProcess(filter);
|
||||
http.addFilter(filter);
|
||||
}
|
||||
@@ -321,7 +341,12 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
if (this.sessionAuthenticationStrategy != null) {
|
||||
return this.sessionAuthenticationStrategy;
|
||||
}
|
||||
return new CsrfAuthenticationStrategy(this.csrfTokenRepository);
|
||||
CsrfAuthenticationStrategy csrfAuthenticationStrategy = new CsrfAuthenticationStrategy(
|
||||
this.csrfTokenRepository);
|
||||
if (this.requestAttributeHandler != null) {
|
||||
csrfAuthenticationStrategy.setRequestAttributeHandler(this.requestAttributeHandler);
|
||||
}
|
||||
return csrfAuthenticationStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-6
@@ -67,13 +67,13 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String DISPATCHER_SERVLET_CLASS_NAME = "org.springframework.web.servlet.DispatcherServlet";
|
||||
|
||||
private static final String ATT_REQUEST_ATTRIBUTE_NAME = "request-attribute-name";
|
||||
|
||||
private static final String ATT_MATCHER = "request-matcher-ref";
|
||||
|
||||
private static final String ATT_REPOSITORY = "token-repository-ref";
|
||||
|
||||
private String requestAttributeName;
|
||||
private static final String ATT_REQUEST_ATTRIBUTE_HANDLER = "request-attribute-handler-ref";
|
||||
|
||||
private static final String ATT_REQUEST_RESOLVER = "request-resolver-ref";
|
||||
|
||||
private String csrfRepositoryRef;
|
||||
|
||||
@@ -81,6 +81,10 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
private String requestMatcherRef;
|
||||
|
||||
private String requestAttributeHandlerRef;
|
||||
|
||||
private String requestResolverRef;
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext pc) {
|
||||
boolean disabled = element != null && "true".equals(element.getAttribute("disabled"));
|
||||
@@ -98,8 +102,9 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
if (element != null) {
|
||||
this.csrfRepositoryRef = element.getAttribute(ATT_REPOSITORY);
|
||||
this.requestAttributeName = element.getAttribute(ATT_REQUEST_ATTRIBUTE_NAME);
|
||||
this.requestMatcherRef = element.getAttribute(ATT_MATCHER);
|
||||
this.requestAttributeHandlerRef = element.getAttribute(ATT_REQUEST_ATTRIBUTE_HANDLER);
|
||||
this.requestResolverRef = element.getAttribute(ATT_REQUEST_RESOLVER);
|
||||
}
|
||||
if (!StringUtils.hasText(this.csrfRepositoryRef)) {
|
||||
RootBeanDefinition csrfTokenRepository = new RootBeanDefinition(HttpSessionCsrfTokenRepository.class);
|
||||
@@ -115,8 +120,11 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
|
||||
if (StringUtils.hasText(this.requestMatcherRef)) {
|
||||
builder.addPropertyReference("requireCsrfProtectionMatcher", this.requestMatcherRef);
|
||||
}
|
||||
if (StringUtils.hasText(this.requestAttributeName)) {
|
||||
builder.addPropertyValue("csrfRequestAttributeName", this.requestAttributeName);
|
||||
if (StringUtils.hasText(this.requestAttributeHandlerRef)) {
|
||||
builder.addPropertyReference("requestAttributeHandler", this.requestAttributeHandlerRef);
|
||||
}
|
||||
if (StringUtils.hasText(this.requestResolverRef)) {
|
||||
builder.addPropertyReference("requestResolver", this.requestResolverRef);
|
||||
}
|
||||
this.csrfFilter = builder.getBeanDefinition();
|
||||
return this.csrfFilter;
|
||||
|
||||
+6
-3
@@ -1142,15 +1142,18 @@ csrf =
|
||||
csrf-options.attlist &=
|
||||
## Specifies if csrf protection should be disabled. Default false (i.e. CSRF protection is enabled).
|
||||
attribute disabled {xsd:boolean}?
|
||||
csrf-options.attlist &=
|
||||
## The request attribute name the CsrfToken is set on. Default is to set to CsrfToken.parameterName
|
||||
attribute request-attribute-name { xsd:token }?
|
||||
csrf-options.attlist &=
|
||||
## The RequestMatcher instance to be used to determine if CSRF should be applied. Default is any HTTP method except "GET", "TRACE", "HEAD", "OPTIONS"
|
||||
attribute request-matcher-ref { xsd:token }?
|
||||
csrf-options.attlist &=
|
||||
## The CsrfTokenRepository to use. The default is HttpSessionCsrfTokenRepository wrapped by LazyCsrfTokenRepository.
|
||||
attribute token-repository-ref { xsd:token }?
|
||||
csrf-options.attlist &=
|
||||
## The CsrfTokenRequestAttributeHandler to use. The default is CsrfTokenRequestProcessor.
|
||||
attribute request-attribute-handler-ref { xsd:token }?
|
||||
csrf-options.attlist &=
|
||||
## The CsrfTokenRequestResolver to use. The default is CsrfTokenRequestProcessor.
|
||||
attribute request-resolver-ref { xsd:token }?
|
||||
|
||||
headers =
|
||||
## Element for configuration of the HeaderWritersFilter. Enables easy setting for the X-Frame-Options, X-XSS-Protection and X-Content-Type-Options headers.
|
||||
|
||||
+12
-7
@@ -3235,13 +3235,6 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="request-attribute-name" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The request attribute name the CsrfToken is set on. Default is to set to
|
||||
CsrfToken.parameterName
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="request-matcher-ref" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The RequestMatcher instance to be used to determine if CSRF should be applied. Default is
|
||||
@@ -3256,6 +3249,18 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="request-attribute-handler-ref" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The CsrfTokenRequestAttributeHandler to use. The default is CsrfTokenRequestProcessor.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="request-resolver-ref" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The CsrfTokenRequestResolver to use. The default is CsrfTokenRequestProcessor.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="headers">
|
||||
<xs:annotation>
|
||||
|
||||
+4
-1
@@ -33,6 +33,7 @@ import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRequestProcessor;
|
||||
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
@@ -84,6 +85,8 @@ public class DeferHttpSessionJavaConfigTests {
|
||||
csrfRepository.setDeferLoadToken(true);
|
||||
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
|
||||
requestCache.setMatchingRequestParameterName("continue");
|
||||
CsrfTokenRequestProcessor requestAttributeHandler = new CsrfTokenRequestProcessor();
|
||||
requestAttributeHandler.setCsrfRequestAttributeName("_csrf");
|
||||
// @formatter:off
|
||||
http
|
||||
.requestCache((cache) -> cache
|
||||
@@ -99,7 +102,7 @@ public class DeferHttpSessionJavaConfigTests {
|
||||
.requireExplicitAuthenticationStrategy(true)
|
||||
)
|
||||
.csrf((csrf) -> csrf
|
||||
.csrfRequestAttributeName("_csrf")
|
||||
.csrfTokenRequestAttributeHandler(requestAttributeHandler)
|
||||
.csrfTokenRepository(csrfRepository)
|
||||
);
|
||||
// @formatter:on
|
||||
|
||||
+89
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
@@ -38,9 +39,12 @@ import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.PasswordEncodedUser;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.csrf.CsrfToken;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRequestProcessor;
|
||||
import org.springframework.security.web.csrf.DefaultCsrfToken;
|
||||
import org.springframework.security.web.firewall.StrictHttpFirewall;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
@@ -55,12 +59,16 @@ import org.springframework.web.servlet.support.RequestDataValueProcessor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
@@ -74,6 +82,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@@ -84,6 +93,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @author Eleftheria Stein
|
||||
* @author Michael Vitz
|
||||
* @author Sam Simmons
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
@ExtendWith(SpringTestContextExtension.class)
|
||||
public class CsrfConfigurerTests {
|
||||
@@ -407,6 +417,47 @@ public class CsrfConfigurerTests {
|
||||
any(HttpServletRequest.class), any(HttpServletResponse.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLoginWhenCsrfTokenRequestProcessorSetThenRespondsWithNormalCsrfToken() throws Exception {
|
||||
CsrfTokenRepository csrfTokenRepository = mock(CsrfTokenRepository.class);
|
||||
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token");
|
||||
given(csrfTokenRepository.generateToken(any(HttpServletRequest.class))).willReturn(csrfToken);
|
||||
CsrfTokenRequestProcessorConfig.REPO = csrfTokenRepository;
|
||||
CsrfTokenRequestProcessorConfig.PROCESSOR = new CsrfTokenRequestProcessor();
|
||||
this.spring.register(CsrfTokenRequestProcessorConfig.class, BasicController.class).autowire();
|
||||
this.mvc.perform(get("/login")).andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(csrfToken.getToken())));
|
||||
verify(csrfTokenRepository).loadToken(any(HttpServletRequest.class));
|
||||
verify(csrfTokenRepository).generateToken(any(HttpServletRequest.class));
|
||||
verify(csrfTokenRepository).saveToken(eq(csrfToken), any(HttpServletRequest.class),
|
||||
any(HttpServletResponse.class));
|
||||
verifyNoMoreInteractions(csrfTokenRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginWhenCsrfTokenRequestProcessorSetAndNormalCsrfTokenThenSuccess() throws Exception {
|
||||
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token");
|
||||
CsrfTokenRepository csrfTokenRepository = mock(CsrfTokenRepository.class);
|
||||
given(csrfTokenRepository.loadToken(any(HttpServletRequest.class))).willReturn(csrfToken);
|
||||
given(csrfTokenRepository.generateToken(any(HttpServletRequest.class))).willReturn(csrfToken);
|
||||
CsrfTokenRequestProcessorConfig.REPO = csrfTokenRepository;
|
||||
CsrfTokenRequestProcessorConfig.PROCESSOR = new CsrfTokenRequestProcessor();
|
||||
this.spring.register(CsrfTokenRequestProcessorConfig.class, BasicController.class).autowire();
|
||||
// @formatter:off
|
||||
MockHttpServletRequestBuilder loginRequest = post("/login")
|
||||
.header(csrfToken.getHeaderName(), csrfToken.getToken())
|
||||
.param("username", "user")
|
||||
.param("password", "password");
|
||||
// @formatter:on
|
||||
this.mvc.perform(loginRequest).andExpect(redirectedUrl("/"));
|
||||
verify(csrfTokenRepository, times(2)).loadToken(any(HttpServletRequest.class));
|
||||
verify(csrfTokenRepository).saveToken(isNull(), any(HttpServletRequest.class), any(HttpServletResponse.class));
|
||||
verify(csrfTokenRepository).generateToken(any(HttpServletRequest.class));
|
||||
verify(csrfTokenRepository).saveToken(eq(csrfToken), any(HttpServletRequest.class),
|
||||
any(HttpServletResponse.class));
|
||||
verifyNoMoreInteractions(csrfTokenRepository);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class AllowHttpMethodsFirewallConfig {
|
||||
|
||||
@@ -748,6 +799,43 @@ public class CsrfConfigurerTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
static class CsrfTokenRequestProcessorConfig {
|
||||
|
||||
static CsrfTokenRepository REPO;
|
||||
|
||||
static CsrfTokenRequestProcessor PROCESSOR;
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeHttpRequests((authorize) -> authorize
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.formLogin(Customizer.withDefaults())
|
||||
.csrf((csrf) -> csrf
|
||||
.csrfTokenRepository(REPO)
|
||||
.csrfTokenRequestAttributeHandler(PROCESSOR)
|
||||
.csrfTokenRequestResolver(PROCESSOR)
|
||||
);
|
||||
// @formatter:on
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// @formatter:off
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser(PasswordEncodedUser.user());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
static class BasicController {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
+4
-1
@@ -16,14 +16,17 @@
|
||||
-->
|
||||
|
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<http auto-config="true">
|
||||
<csrf request-attribute-name="csrf-attribute-name"/>
|
||||
<csrf request-attribute-handler-ref="requestAttributeHandler"/>
|
||||
</http>
|
||||
|
||||
<b:bean id="requestAttributeHandler" class="org.springframework.security.web.csrf.CsrfTokenRequestProcessor"
|
||||
p:csrfRequestAttributeName="csrf-attribute-name"/>
|
||||
<b:import resource="CsrfConfigTests-shared-userservice.xml"/>
|
||||
</b:beans>
|
||||
|
||||
+3
-1
@@ -30,7 +30,7 @@
|
||||
security-context-explicit-save="true"
|
||||
use-authorization-manager="true">
|
||||
<intercept-url pattern="/**" access="permitAll"/>
|
||||
<csrf request-attribute-name="_csrf"
|
||||
<csrf request-attribute-handler-ref="requestAttributeHandler"
|
||||
token-repository-ref="csrfRepository"/>
|
||||
<request-cache ref="requestCache"/>
|
||||
<session-management authentication-strategy-explicit-invocation="true"/>
|
||||
@@ -42,5 +42,7 @@
|
||||
<b:bean id="csrfRepository" class="org.springframework.security.web.csrf.LazyCsrfTokenRepository"
|
||||
c:delegate-ref="httpSessionCsrfRepository"
|
||||
p:deferLoadToken="true"/>
|
||||
<b:bean id="requestAttributeHandler" class="org.springframework.security.web.csrf.CsrfTokenRequestProcessor"
|
||||
p:csrfRequestAttributeName="_csrf"/>
|
||||
<b:import resource="CsrfConfigTests-shared-userservice.xml"/>
|
||||
</b:beans>
|
||||
|
||||
Reference in New Issue
Block a user