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
+14
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -41,6 +41,8 @@ public final class CsrfAuthenticationStrategy implements SessionAuthenticationSt
|
||||
|
||||
private final CsrfTokenRepository csrfTokenRepository;
|
||||
|
||||
private CsrfTokenRequestAttributeHandler requestAttributeHandler = new CsrfTokenRequestProcessor();
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
* @param csrfTokenRepository the {@link CsrfTokenRepository} to use
|
||||
@@ -50,6 +52,16 @@ public final class CsrfAuthenticationStrategy implements SessionAuthenticationSt
|
||||
this.csrfTokenRepository = csrfTokenRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a {@link CsrfTokenRequestAttributeHandler} to use for making the
|
||||
* {@code CsrfToken} available as a request attribute.
|
||||
* @param requestAttributeHandler the {@link CsrfTokenRequestAttributeHandler} to use
|
||||
*/
|
||||
public void setRequestAttributeHandler(CsrfTokenRequestAttributeHandler requestAttributeHandler) {
|
||||
Assert.notNull(requestAttributeHandler, "requestAttributeHandler cannot be null");
|
||||
this.requestAttributeHandler = requestAttributeHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthentication(Authentication authentication, HttpServletRequest request,
|
||||
HttpServletResponse response) throws SessionAuthenticationException {
|
||||
@@ -58,8 +70,7 @@ public final class CsrfAuthenticationStrategy implements SessionAuthenticationSt
|
||||
this.csrfTokenRepository.saveToken(null, request, response);
|
||||
CsrfToken newToken = this.csrfTokenRepository.generateToken(request);
|
||||
this.csrfTokenRepository.saveToken(newToken, request, response);
|
||||
request.setAttribute(CsrfToken.class.getName(), newToken);
|
||||
request.setAttribute(newToken.getParameterName(), newToken);
|
||||
this.requestAttributeHandler.handle(request, response, () -> newToken);
|
||||
this.logger.debug("Replaced CSRF Token");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -58,6 +58,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
* </p>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Steve Riesenberg
|
||||
* @since 3.2
|
||||
*/
|
||||
public final class CsrfFilter extends OncePerRequestFilter {
|
||||
@@ -87,11 +88,16 @@ public final class CsrfFilter extends OncePerRequestFilter {
|
||||
|
||||
private AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl();
|
||||
|
||||
private String csrfRequestAttributeName;
|
||||
private CsrfTokenRequestAttributeHandler requestAttributeHandler;
|
||||
|
||||
private CsrfTokenRequestResolver requestResolver;
|
||||
|
||||
public CsrfFilter(CsrfTokenRepository csrfTokenRepository) {
|
||||
Assert.notNull(csrfTokenRepository, "csrfTokenRepository cannot be null");
|
||||
this.tokenRepository = csrfTokenRepository;
|
||||
CsrfTokenRequestProcessor csrfTokenRequestProcessor = new CsrfTokenRequestProcessor();
|
||||
this.requestAttributeHandler = csrfTokenRequestProcessor;
|
||||
this.requestResolver = csrfTokenRequestProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,10 +115,8 @@ public final class CsrfFilter extends OncePerRequestFilter {
|
||||
csrfToken = this.tokenRepository.generateToken(request);
|
||||
this.tokenRepository.saveToken(csrfToken, request, response);
|
||||
}
|
||||
request.setAttribute(CsrfToken.class.getName(), csrfToken);
|
||||
String csrfAttrName = (this.csrfRequestAttributeName != null) ? this.csrfRequestAttributeName
|
||||
: csrfToken.getParameterName();
|
||||
request.setAttribute(csrfAttrName, csrfToken);
|
||||
final CsrfToken finalCsrfToken = csrfToken;
|
||||
this.requestAttributeHandler.handle(request, response, () -> finalCsrfToken);
|
||||
if (!this.requireCsrfProtectionMatcher.matches(request)) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace("Did not protect against CSRF since request did not match "
|
||||
@@ -121,10 +125,7 @@ public final class CsrfFilter extends OncePerRequestFilter {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
String actualToken = request.getHeader(csrfToken.getHeaderName());
|
||||
if (actualToken == null) {
|
||||
actualToken = request.getParameter(csrfToken.getParameterName());
|
||||
}
|
||||
String actualToken = this.requestResolver.resolveCsrfTokenValue(request, csrfToken);
|
||||
if (!equalsConstantTime(csrfToken.getToken(), actualToken)) {
|
||||
this.logger.debug(
|
||||
LogMessage.of(() -> "Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)));
|
||||
@@ -172,15 +173,33 @@ public final class CsrfFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link CsrfToken} is available as a request attribute named
|
||||
* {@code CsrfToken.class.getName()}. By default, an additional request attribute that
|
||||
* is the same as {@link CsrfToken#getParameterName()} is set. This attribute allows
|
||||
* overriding the additional attribute.
|
||||
* @param csrfRequestAttributeName the name of an additional request attribute with
|
||||
* the value of the CsrfToken. Default is {@link CsrfToken#getParameterName()}
|
||||
* Specifies a {@link CsrfTokenRequestAttributeHandler} that is used to make the
|
||||
* {@link CsrfToken} available as a request attribute.
|
||||
*
|
||||
* <p>
|
||||
* The default is {@link CsrfTokenRequestProcessor}.
|
||||
* </p>
|
||||
* @param requestAttributeHandler the {@link CsrfTokenRequestAttributeHandler} to use
|
||||
* @since 5.8
|
||||
*/
|
||||
public void setCsrfRequestAttributeName(String csrfRequestAttributeName) {
|
||||
this.csrfRequestAttributeName = csrfRequestAttributeName;
|
||||
public void setRequestAttributeHandler(CsrfTokenRequestAttributeHandler requestAttributeHandler) {
|
||||
Assert.notNull(requestAttributeHandler, "requestAttributeHandler cannot be null");
|
||||
this.requestAttributeHandler = requestAttributeHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a {@link CsrfTokenRequestResolver} that is used to resolve the token
|
||||
* value from the request.
|
||||
*
|
||||
* <p>
|
||||
* The default is {@link CsrfTokenRequestProcessor}.
|
||||
* </p>
|
||||
* @param requestResolver the {@link CsrfTokenRequestResolver} to use
|
||||
* @since 5.8
|
||||
*/
|
||||
public void setRequestResolver(CsrfTokenRequestResolver requestResolver) {
|
||||
Assert.notNull(requestResolver, "requestResolver cannot be null");
|
||||
this.requestResolver = requestResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.web.csrf;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* A callback interface that is used to make the {@link CsrfToken} created by the
|
||||
* {@link CsrfTokenRepository} available as a request attribute. Implementations of this
|
||||
* interface may choose to perform additional tasks or customize how the token is made
|
||||
* available to the application through request attributes.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @since 5.8
|
||||
* @see CsrfTokenRequestProcessor
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CsrfTokenRequestAttributeHandler {
|
||||
|
||||
/**
|
||||
* Handles a request using a {@link CsrfToken}.
|
||||
* @param request the {@code HttpServletRequest} being handled
|
||||
* @param response the {@code HttpServletResponse} being handled
|
||||
* @param csrfToken the {@link CsrfToken} created by the {@link CsrfTokenRepository}
|
||||
*/
|
||||
void handle(HttpServletRequest request, HttpServletResponse response, Supplier<CsrfToken> csrfToken);
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.web.csrf;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link CsrfTokenRequestAttributeHandler} and
|
||||
* {@link CsrfTokenRequestResolver} interfaces that is capable of making the
|
||||
* {@link CsrfToken} available as a request attribute and resolving the token value as
|
||||
* either a header or parameter value of the request.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @since 5.8
|
||||
*/
|
||||
public class CsrfTokenRequestProcessor implements CsrfTokenRequestAttributeHandler, CsrfTokenRequestResolver {
|
||||
|
||||
private String csrfRequestAttributeName;
|
||||
|
||||
/**
|
||||
* The {@link CsrfToken} is available as a request attribute named
|
||||
* {@code CsrfToken.class.getName()}. By default, an additional request attribute that
|
||||
* is the same as {@link CsrfToken#getParameterName()} is set. This attribute allows
|
||||
* overriding the additional attribute.
|
||||
* @param csrfRequestAttributeName the name of an additional request attribute with
|
||||
* the value of the CsrfToken. Default is {@link CsrfToken#getParameterName()}
|
||||
*/
|
||||
public final void setCsrfRequestAttributeName(String csrfRequestAttributeName) {
|
||||
this.csrfRequestAttributeName = csrfRequestAttributeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, Supplier<CsrfToken> csrfToken) {
|
||||
Assert.notNull(request, "request cannot be null");
|
||||
Assert.notNull(response, "response cannot be null");
|
||||
Assert.notNull(csrfToken, "csrfToken supplier cannot be null");
|
||||
CsrfToken actualCsrfToken = csrfToken.get();
|
||||
Assert.notNull(actualCsrfToken, "csrfToken cannot be null");
|
||||
request.setAttribute(CsrfToken.class.getName(), actualCsrfToken);
|
||||
String csrfAttrName = (this.csrfRequestAttributeName != null) ? this.csrfRequestAttributeName
|
||||
: actualCsrfToken.getParameterName();
|
||||
request.setAttribute(csrfAttrName, actualCsrfToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) {
|
||||
Assert.notNull(request, "request cannot be null");
|
||||
Assert.notNull(csrfToken, "csrfToken cannot be null");
|
||||
String actualToken = request.getHeader(csrfToken.getHeaderName());
|
||||
if (actualToken == null) {
|
||||
actualToken = request.getParameter(csrfToken.getParameterName());
|
||||
}
|
||||
return actualToken;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.web.csrf;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Implementations of this interface are capable of resolving the token value of a
|
||||
* {@link CsrfToken} from the provided {@code HttpServletRequest}. Used by the
|
||||
* {@link CsrfFilter}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @since 5.8
|
||||
* @see CsrfTokenRequestProcessor
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CsrfTokenRequestResolver {
|
||||
|
||||
/**
|
||||
* Returns the token value resolved from the provided {@code HttpServletRequest} and
|
||||
* {@link CsrfToken} or {@code null} if not available.
|
||||
* @param request the {@code HttpServletRequest} being processed
|
||||
* @param csrfToken the {@link CsrfToken} created by the {@link CsrfTokenRepository}
|
||||
* @return the token value resolved from the request
|
||||
*/
|
||||
String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken);
|
||||
|
||||
}
|
||||
+21
@@ -34,8 +34,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
@@ -72,6 +74,25 @@ public class CsrfAuthenticationStrategyTests {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new CsrfAuthenticationStrategy(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRequestAttributeHandlerWhenNullThenIllegalStateException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.strategy.setRequestAttributeHandler(null))
|
||||
.withMessage("requestAttributeHandler cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAuthenticationWhenCustomRequestAttributeHandlerThenUsed() {
|
||||
given(this.csrfTokenRepository.loadToken(this.request)).willReturn(this.existingToken);
|
||||
given(this.csrfTokenRepository.generateToken(this.request)).willReturn(this.generatedToken);
|
||||
|
||||
CsrfTokenRequestAttributeHandler requestAttributeHandler = mock(CsrfTokenRequestAttributeHandler.class);
|
||||
this.strategy.setRequestAttributeHandler(requestAttributeHandler);
|
||||
this.strategy.onAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"), this.request,
|
||||
this.response);
|
||||
verify(requestAttributeHandler).handle(eq(this.request), eq(this.response), any());
|
||||
verifyNoMoreInteractions(requestAttributeHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logoutRemovesCsrfTokenAndSavesNew() {
|
||||
given(this.csrfTokenRepository.loadToken(this.request)).willReturn(this.existingToken);
|
||||
|
||||
@@ -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.
|
||||
@@ -335,6 +335,30 @@ public class CsrfFilterTests {
|
||||
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenRequestAttributeHandlerThenUsed() throws Exception {
|
||||
given(this.requestMatcher.matches(this.request)).willReturn(true);
|
||||
given(this.tokenRepository.loadToken(this.request)).willReturn(this.token);
|
||||
CsrfTokenRequestAttributeHandler requestAttributeHandler = mock(CsrfTokenRequestAttributeHandler.class);
|
||||
this.filter.setRequestAttributeHandler(requestAttributeHandler);
|
||||
this.request.setParameter(this.token.getParameterName(), this.token.getToken());
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
verify(requestAttributeHandler).handle(eq(this.request), eq(this.response), any());
|
||||
verify(this.filterChain).doFilter(this.request, this.response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenRequestResolverThenUsed() throws Exception {
|
||||
given(this.requestMatcher.matches(this.request)).willReturn(true);
|
||||
given(this.tokenRepository.loadToken(this.request)).willReturn(this.token);
|
||||
CsrfTokenRequestResolver requestResolver = mock(CsrfTokenRequestResolver.class);
|
||||
given(requestResolver.resolveCsrfTokenValue(this.request, this.token)).willReturn(this.token.getToken());
|
||||
this.filter.setRequestResolver(requestResolver);
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
verify(requestResolver).resolveCsrfTokenValue(this.request, this.token);
|
||||
verify(this.filterChain).doFilter(this.request, this.response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRequireCsrfProtectionMatcherNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.filter.setRequireCsrfProtectionMatcher(null));
|
||||
@@ -351,7 +375,9 @@ public class CsrfFilterTests {
|
||||
throws ServletException, IOException {
|
||||
CsrfFilter filter = createCsrfFilter(this.tokenRepository);
|
||||
String csrfAttrName = "_csrf";
|
||||
filter.setCsrfRequestAttributeName(csrfAttrName);
|
||||
CsrfTokenRequestProcessor csrfTokenRequestProcessor = new CsrfTokenRequestProcessor();
|
||||
csrfTokenRequestProcessor.setCsrfRequestAttributeName(csrfAttrName);
|
||||
filter.setRequestAttributeHandler(csrfTokenRequestProcessor);
|
||||
CsrfToken expectedCsrfToken = mock(CsrfToken.class);
|
||||
given(this.tokenRepository.loadToken(this.request)).willReturn(expectedCsrfToken);
|
||||
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.web.csrf;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link CsrfTokenRequestProcessor}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @since 5.8
|
||||
*/
|
||||
public class CsrfTokenRequestProcessorTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
private CsrfToken token;
|
||||
|
||||
private CsrfTokenRequestProcessor processor;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
this.token = new DefaultCsrfToken("headerName", "paramName", "csrfTokenValue");
|
||||
this.processor = new CsrfTokenRequestProcessor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenRequestIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.processor.handle(null, this.response, () -> this.token))
|
||||
.withMessage("request cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenResponseIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.processor.handle(this.request, null, () -> this.token))
|
||||
.withMessage("response cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenCsrfTokenSupplierIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.processor.handle(this.request, this.response, null))
|
||||
.withMessage("csrfToken supplier cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenCsrfTokenIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.processor.handle(this.request, this.response, () -> null))
|
||||
.withMessage("csrfToken cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenCsrfRequestAttributeSetThenUsed() {
|
||||
this.processor.setCsrfRequestAttributeName("_csrf");
|
||||
this.processor.handle(this.request, this.response, () -> this.token);
|
||||
assertThat(this.request.getAttribute(CsrfToken.class.getName())).isEqualTo(this.token);
|
||||
assertThat(this.request.getAttribute("_csrf")).isEqualTo(this.token);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleWhenValidParametersThenRequestAttributesSet() {
|
||||
this.processor.handle(this.request, this.response, () -> this.token);
|
||||
assertThat(this.request.getAttribute(CsrfToken.class.getName())).isEqualTo(this.token);
|
||||
assertThat(this.request.getAttribute(this.token.getParameterName())).isEqualTo(this.token);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenRequestIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.processor.resolveCsrfTokenValue(null, this.token))
|
||||
.withMessage("request cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenCsrfTokenIsNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.processor.resolveCsrfTokenValue(this.request, null))
|
||||
.withMessage("csrfToken cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenTokenNotSetThenReturnsNull() {
|
||||
String tokenValue = this.processor.resolveCsrfTokenValue(this.request, this.token);
|
||||
assertThat(tokenValue).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenParameterSetThenReturnsTokenValue() {
|
||||
this.request.setParameter(this.token.getParameterName(), this.token.getToken());
|
||||
String tokenValue = this.processor.resolveCsrfTokenValue(this.request, this.token);
|
||||
assertThat(tokenValue).isEqualTo(this.token.getToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenHeaderSetThenReturnsTokenValue() {
|
||||
this.request.addHeader(this.token.getHeaderName(), this.token.getToken());
|
||||
String tokenValue = this.processor.resolveCsrfTokenValue(this.request, this.token);
|
||||
assertThat(tokenValue).isEqualTo(this.token.getToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCsrfTokenValueWhenHeaderAndParameterSetThenHeaderIsPreferred() {
|
||||
this.request.addHeader(this.token.getHeaderName(), "header");
|
||||
this.request.setParameter(this.token.getParameterName(), "parameter");
|
||||
String tokenValue = this.processor.resolveCsrfTokenValue(this.request, this.token);
|
||||
assertThat(tokenValue).isEqualTo("header");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user