mirror of https://github.com/apache/nifi.git
NIFI-10899 Added SameSite Policy to Application Cookies
- Added __Secure prefix to Application Cookie Names Signed-off-by: Nathan Gough <thenatog@gmail.com> This closes #6735.
This commit is contained in:
parent
3dc48f0894
commit
45a31c7286
|
@ -22,21 +22,35 @@ import org.apache.nifi.web.security.http.SecurityCookieName;
|
|||
* Application Cookie Names
|
||||
*/
|
||||
public enum ApplicationCookieName {
|
||||
AUTHORIZATION_BEARER(SecurityCookieName.AUTHORIZATION_BEARER.getName()),
|
||||
/** Authorization Bearer contains signed JSON Web Token and requires Strict Same Site handling */
|
||||
AUTHORIZATION_BEARER(SecurityCookieName.AUTHORIZATION_BEARER.getName(), SameSitePolicy.STRICT),
|
||||
|
||||
LOGOUT_REQUEST_IDENTIFIER("nifi-logout-request-identifier"),
|
||||
/** Cross-Site Request Forgery mitigation token requires Strict Same Site handling */
|
||||
REQUEST_TOKEN(SecurityCookieName.REQUEST_TOKEN.getName(), SameSitePolicy.STRICT),
|
||||
|
||||
OIDC_REQUEST_IDENTIFIER("nifi-oidc-request-identifier"),
|
||||
/** Logout Requests can interact with external identity providers requiring no Same Site restrictions */
|
||||
LOGOUT_REQUEST_IDENTIFIER("__Secure-Logout-Request-Identifier", SameSitePolicy.NONE),
|
||||
|
||||
SAML_REQUEST_IDENTIFIER("nifi-saml-request-identifier");
|
||||
/** OpenID Connect Requests use external identity providers requiring no Same Site restrictions */
|
||||
OIDC_REQUEST_IDENTIFIER("__Secure-OIDC-Request-Identifier", SameSitePolicy.NONE),
|
||||
|
||||
/** SAML Requests use external identity providers requiring no Same Site restrictions */
|
||||
SAML_REQUEST_IDENTIFIER("__Secure-SAML-Request-Identifier", SameSitePolicy.NONE);
|
||||
|
||||
private final String cookieName;
|
||||
|
||||
ApplicationCookieName(final String cookieName) {
|
||||
private final SameSitePolicy sameSitePolicy;
|
||||
|
||||
ApplicationCookieName(final String cookieName, final SameSitePolicy sameSitePolicy) {
|
||||
this.cookieName = cookieName;
|
||||
this.sameSitePolicy = sameSitePolicy;
|
||||
}
|
||||
|
||||
public String getCookieName() {
|
||||
return cookieName;
|
||||
}
|
||||
|
||||
public SameSitePolicy getSameSitePolicy() {
|
||||
return sameSitePolicy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://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.apache.nifi.web.security.cookie;
|
||||
|
||||
/**
|
||||
* Cookie SameSite attribute policy
|
||||
*/
|
||||
public enum SameSitePolicy {
|
||||
/** Instructs browsers to limit sending cookies to first-party-initiated requests */
|
||||
STRICT("Strict"),
|
||||
|
||||
/** Instructs browsers to send cookies for both first-party and cross-site requests */
|
||||
NONE("None");
|
||||
|
||||
private final String policy;
|
||||
|
||||
SameSitePolicy(final String policy) {
|
||||
this.policy = policy;
|
||||
}
|
||||
|
||||
public String getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
}
|
|
@ -43,8 +43,6 @@ public class StandardApplicationCookieService implements ApplicationCookieServic
|
|||
|
||||
private static final String DEFAULT_PATH = "/";
|
||||
|
||||
private static final String SAME_SITE_STRICT = "Strict";
|
||||
|
||||
private static final boolean SECURE_ENABLED = true;
|
||||
|
||||
private static final boolean HTTP_ONLY_ENABLED = true;
|
||||
|
@ -77,7 +75,6 @@ public class StandardApplicationCookieService implements ApplicationCookieServic
|
|||
@Override
|
||||
public void addSessionCookie(final URI resourceUri, final HttpServletResponse response, final ApplicationCookieName applicationCookieName, final String value) {
|
||||
final ResponseCookie.ResponseCookieBuilder responseCookieBuilder = getCookieBuilder(resourceUri, applicationCookieName, value, MAX_AGE_SESSION);
|
||||
responseCookieBuilder.sameSite(SAME_SITE_STRICT);
|
||||
setResponseCookie(response, responseCookieBuilder.build());
|
||||
logger.debug("Added Session Cookie [{}] URI [{}]", applicationCookieName.getCookieName(), resourceUri);
|
||||
}
|
||||
|
@ -110,15 +107,27 @@ public class StandardApplicationCookieService implements ApplicationCookieServic
|
|||
logger.debug("Removed Cookie [{}] URI [{}]", applicationCookieName.getCookieName(), resourceUri);
|
||||
}
|
||||
|
||||
private ResponseCookie.ResponseCookieBuilder getCookieBuilder(final URI resourceUri,
|
||||
/**
|
||||
* Get Response Cookie Builder with standard properties
|
||||
*
|
||||
* @param resourceUri Resource URI containing path and domain
|
||||
* @param applicationCookieName Application Cookie Name to be used
|
||||
* @param value Cookie value
|
||||
* @param maxAge Max Age
|
||||
* @return Response Cookie Builder
|
||||
*/
|
||||
protected ResponseCookie.ResponseCookieBuilder getCookieBuilder(final URI resourceUri,
|
||||
final ApplicationCookieName applicationCookieName,
|
||||
final String value,
|
||||
final Duration maxAge) {
|
||||
Objects.requireNonNull(resourceUri, "Resource URI required");
|
||||
Objects.requireNonNull(applicationCookieName, "Response Cookie Name required");
|
||||
|
||||
final SameSitePolicy sameSitePolicy = applicationCookieName.getSameSitePolicy();
|
||||
return ResponseCookie.from(applicationCookieName.getCookieName(), value)
|
||||
.path(getCookiePath(resourceUri))
|
||||
.domain(resourceUri.getHost())
|
||||
.sameSite(sameSitePolicy.getPolicy())
|
||||
.secure(SECURE_ENABLED)
|
||||
.httpOnly(HTTP_ONLY_ENABLED)
|
||||
.maxAge(maxAge);
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
*/
|
||||
package org.apache.nifi.web.security.csrf;
|
||||
|
||||
import org.apache.nifi.web.security.cookie.ApplicationCookieName;
|
||||
import org.apache.nifi.web.security.cookie.ApplicationCookieService;
|
||||
import org.apache.nifi.web.security.cookie.StandardApplicationCookieService;
|
||||
import org.apache.nifi.web.security.http.SecurityCookieName;
|
||||
import org.apache.nifi.web.security.http.SecurityHeader;
|
||||
import org.apache.nifi.web.util.RequestUriBuilder;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.security.web.csrf.CsrfToken;
|
||||
import org.springframework.security.web.csrf.CsrfTokenRepository;
|
||||
import org.springframework.security.web.csrf.DefaultCsrfToken;
|
||||
|
@ -29,6 +33,7 @@ import javax.servlet.http.Cookie;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -37,15 +42,7 @@ import java.util.UUID;
|
|||
public class StandardCookieCsrfTokenRepository implements CsrfTokenRepository {
|
||||
private static final String REQUEST_PARAMETER = "requestToken";
|
||||
|
||||
private static final String ROOT_PATH = "/";
|
||||
|
||||
private static final String EMPTY = "";
|
||||
|
||||
private static final boolean SECURE_ENABLED = true;
|
||||
|
||||
private static final int MAX_AGE_EXPIRED = 0;
|
||||
|
||||
private static final int MAX_AGE_SESSION = -1;
|
||||
private static final ApplicationCookieService applicationCookieService = new CsrfApplicationCookieService();
|
||||
|
||||
/**
|
||||
* Generate CSRF Token or return current Token when present in HTTP Servlet Request Cookie header
|
||||
|
@ -71,16 +68,13 @@ public class StandardCookieCsrfTokenRepository implements CsrfTokenRepository {
|
|||
*/
|
||||
@Override
|
||||
public void saveToken(final CsrfToken csrfToken, final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse) {
|
||||
final String token = csrfToken == null ? EMPTY : csrfToken.getToken();
|
||||
final int maxAge = csrfToken == null ? MAX_AGE_EXPIRED : MAX_AGE_SESSION;
|
||||
|
||||
final Cookie cookie = new Cookie(SecurityCookieName.REQUEST_TOKEN.getName(), token);
|
||||
cookie.setSecure(SECURE_ENABLED);
|
||||
cookie.setMaxAge(maxAge);
|
||||
|
||||
final String cookiePath = getCookiePath(httpServletRequest);
|
||||
cookie.setPath(cookiePath);
|
||||
httpServletResponse.addCookie(cookie);
|
||||
final URI uri = RequestUriBuilder.fromHttpServletRequest(httpServletRequest).build();
|
||||
if (csrfToken == null) {
|
||||
applicationCookieService.removeCookie(uri, httpServletResponse, ApplicationCookieName.REQUEST_TOKEN);
|
||||
} else {
|
||||
final String token = csrfToken.getToken();
|
||||
applicationCookieService.addSessionCookie(uri, httpServletResponse, ApplicationCookieName.REQUEST_TOKEN, token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,10 +98,26 @@ public class StandardCookieCsrfTokenRepository implements CsrfTokenRepository {
|
|||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private String getCookiePath(final HttpServletRequest httpServletRequest) {
|
||||
final RequestUriBuilder requestUriBuilder = RequestUriBuilder.fromHttpServletRequest(httpServletRequest);
|
||||
requestUriBuilder.path(ROOT_PATH);
|
||||
final URI uri = requestUriBuilder.build();
|
||||
return uri.getPath();
|
||||
private static class CsrfApplicationCookieService extends StandardApplicationCookieService {
|
||||
private static final boolean HTTP_ONLY_DISABLED = false;
|
||||
|
||||
/**
|
||||
* Get Response Cookie Builder with HttpOnly disabled allowing JavaScript to read value for subsequent requests
|
||||
*
|
||||
* @param resourceUri Resource URI containing path and domain
|
||||
* @param applicationCookieName Application Cookie Name to be used
|
||||
* @param value Cookie value
|
||||
* @param maxAge Max Age
|
||||
* @return Response Cookie Builder
|
||||
*/
|
||||
@Override
|
||||
protected ResponseCookie.ResponseCookieBuilder getCookieBuilder(final URI resourceUri,
|
||||
final ApplicationCookieName applicationCookieName,
|
||||
final String value,
|
||||
final Duration maxAge) {
|
||||
final ResponseCookie.ResponseCookieBuilder builder = super.getCookieBuilder(resourceUri, applicationCookieName, value, maxAge);
|
||||
builder.httpOnly(HTTP_ONLY_DISABLED);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
package org.apache.nifi.web.security.cookie;
|
||||
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockCookie;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
@ -34,14 +34,14 @@ import java.net.URI;
|
|||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class StandardApplicationCookieServiceTest {
|
||||
private static final String DOMAIN = "localhost.localdomain";
|
||||
|
||||
|
@ -59,7 +59,7 @@ public class StandardApplicationCookieServiceTest {
|
|||
|
||||
private static final int REMOVE_MAX_AGE = 0;
|
||||
|
||||
private static final String SAME_SITE_STRICT = "SameSite=Strict";
|
||||
private static final String SAME_SITE = "SameSite";
|
||||
|
||||
private static final String COOKIE_VALUE = UUID.randomUUID().toString();
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class StandardApplicationCookieServiceTest {
|
|||
@Captor
|
||||
private ArgumentCaptor<String> cookieArgumentCaptor;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setService() {
|
||||
service = new StandardApplicationCookieService();
|
||||
resourceUri = URI.create(RESOURCE_URI);
|
||||
|
@ -113,7 +113,6 @@ public class StandardApplicationCookieServiceTest {
|
|||
|
||||
final String setCookieHeader = cookieArgumentCaptor.getValue();
|
||||
assertAddCookieMatches(setCookieHeader, ROOT_PATH, SESSION_MAX_AGE);
|
||||
assertTrue("SameSite not found", setCookieHeader.endsWith(SAME_SITE_STRICT));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -124,7 +123,6 @@ public class StandardApplicationCookieServiceTest {
|
|||
|
||||
final String setCookieHeader = cookieArgumentCaptor.getValue();
|
||||
assertAddCookieMatches(setCookieHeader, CONTEXT_PATH, SESSION_MAX_AGE);
|
||||
assertTrue("SameSite not found", setCookieHeader.endsWith(SAME_SITE_STRICT));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -175,10 +173,11 @@ public class StandardApplicationCookieServiceTest {
|
|||
}
|
||||
|
||||
private void assertCookieMatches(final String setCookieHeader, final Cookie cookie, final String path) {
|
||||
assertEquals("Cookie Name not matched", COOKIE_NAME.getCookieName(), cookie.getName());
|
||||
assertEquals("Path not matched", path, cookie.getPath());
|
||||
assertEquals("Domain not matched", DOMAIN, cookie.getDomain());
|
||||
assertTrue("HTTP Only not matched", cookie.isHttpOnly());
|
||||
assertTrue("Secure not matched", cookie.getSecure());
|
||||
assertEquals(COOKIE_NAME.getCookieName(), cookie.getName(), "Cookie Name not matched");
|
||||
assertEquals(path, cookie.getPath(), "Path not matched");
|
||||
assertEquals(DOMAIN, cookie.getDomain(), "Domain not matched");
|
||||
assertTrue(cookie.isHttpOnly(), "HTTP Only not matched");
|
||||
assertTrue(cookie.getSecure(), "Secure not matched");
|
||||
assertTrue(setCookieHeader.contains(SAME_SITE), "SameSite not found");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,30 +20,20 @@ import org.apache.nifi.web.security.http.SecurityCookieName;
|
|||
import org.apache.nifi.web.util.WebUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.security.web.csrf.CsrfToken;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class StandardCookieCsrfTokenRepositoryTest {
|
||||
private static final String ALLOWED_CONTEXT_PATHS_PARAMETER = "allowedContextPaths";
|
||||
|
||||
|
@ -55,8 +45,6 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
|
||||
private static final String CONTEXT_PATH = "/context-path";
|
||||
|
||||
private static final String COOKIE_CONTEXT_PATH = CONTEXT_PATH + ROOT_PATH;
|
||||
|
||||
private static final String HTTPS = "https";
|
||||
|
||||
private static final String HOST = "localhost";
|
||||
|
@ -65,23 +53,21 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
|
||||
private static final String EMPTY = "";
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
private static final String SET_COOKIE_HEADER = "Set-Cookie";
|
||||
|
||||
@Mock
|
||||
private HttpServletResponse response;
|
||||
private static final String SAME_SITE = "SameSite";
|
||||
|
||||
@Mock
|
||||
private ServletContext servletContext;
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Cookie> cookieArgumentCaptor;
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
private StandardCookieCsrfTokenRepository repository;
|
||||
|
||||
@BeforeEach
|
||||
public void setRepository() {
|
||||
this.repository = new StandardCookieCsrfTokenRepository();
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -95,7 +81,7 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
public void testGenerateTokenCookieFound() {
|
||||
final String token = UUID.randomUUID().toString();
|
||||
final Cookie cookie = new Cookie(SecurityCookieName.REQUEST_TOKEN.getName(), token);
|
||||
when(request.getCookies()).thenReturn(new Cookie[]{cookie});
|
||||
request.setCookies(cookie);
|
||||
|
||||
final CsrfToken csrfToken = repository.generateToken(request);
|
||||
assertNotNull(csrfToken);
|
||||
|
@ -106,7 +92,7 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
public void testLoadToken() {
|
||||
final String token = UUID.randomUUID().toString();
|
||||
final Cookie cookie = new Cookie(SecurityCookieName.REQUEST_TOKEN.getName(), token);
|
||||
when(request.getCookies()).thenReturn(new Cookie[]{cookie});
|
||||
request.setCookies(cookie);
|
||||
|
||||
final CsrfToken csrfToken = repository.loadToken(request);
|
||||
assertNotNull(csrfToken);
|
||||
|
@ -115,31 +101,22 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
|
||||
@Test
|
||||
public void testSaveToken() {
|
||||
when(request.getServletContext()).thenReturn(servletContext);
|
||||
|
||||
final CsrfToken csrfToken = repository.generateToken(request);
|
||||
repository.saveToken(csrfToken, request, response);
|
||||
|
||||
verify(response).addCookie(cookieArgumentCaptor.capture());
|
||||
final Cookie cookie = cookieArgumentCaptor.getValue();
|
||||
assertCookieEquals(csrfToken, cookie);
|
||||
final Cookie cookie = assertCookieFound();
|
||||
final String setCookieHeader = response.getHeader(SET_COOKIE_HEADER);
|
||||
assertCookieEquals(csrfToken.getToken(), MAX_AGE_SESSION, cookie, setCookieHeader);
|
||||
assertEquals(ROOT_PATH, cookie.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveTokenNullCsrfToken() {
|
||||
when(request.getServletContext()).thenReturn(servletContext);
|
||||
|
||||
repository.saveToken(null, request, response);
|
||||
|
||||
verify(response).addCookie(cookieArgumentCaptor.capture());
|
||||
final Cookie cookie = cookieArgumentCaptor.getValue();
|
||||
assertEquals(ROOT_PATH, cookie.getPath());
|
||||
assertEquals(EMPTY, cookie.getValue());
|
||||
assertEquals(MAX_AGE_EXPIRED, cookie.getMaxAge());
|
||||
assertTrue(cookie.getSecure());
|
||||
assertFalse(cookie.isHttpOnly());
|
||||
assertNull(cookie.getDomain());
|
||||
final Cookie cookie = assertCookieFound();
|
||||
final String setCookieHeader = response.getHeader(SET_COOKIE_HEADER);
|
||||
assertCookieEquals(EMPTY, MAX_AGE_EXPIRED, cookie, setCookieHeader);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -147,27 +124,36 @@ public class StandardCookieCsrfTokenRepositoryTest {
|
|||
this.repository = new StandardCookieCsrfTokenRepository();
|
||||
|
||||
final CsrfToken csrfToken = repository.generateToken(request);
|
||||
when(request.getHeader(eq(WebUtils.PROXY_SCHEME_HTTP_HEADER))).thenReturn(HTTPS);
|
||||
when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn(HOST);
|
||||
when(request.getHeader(eq(WebUtils.PROXY_PORT_HTTP_HEADER))).thenReturn(PORT);
|
||||
when(request.getHeader(eq(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER))).thenReturn(CONTEXT_PATH);
|
||||
|
||||
when(servletContext.getInitParameter(eq(ALLOWED_CONTEXT_PATHS_PARAMETER))).thenReturn(CONTEXT_PATH);
|
||||
when(request.getServletContext()).thenReturn(servletContext);
|
||||
request.addHeader(WebUtils.PROXY_SCHEME_HTTP_HEADER, HTTPS);
|
||||
request.addHeader(WebUtils.PROXY_HOST_HTTP_HEADER, HOST);
|
||||
request.addHeader(WebUtils.PROXY_PORT_HTTP_HEADER, PORT);
|
||||
request.addHeader(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER, CONTEXT_PATH);
|
||||
|
||||
final MockServletContext servletContext = (MockServletContext) request.getServletContext();
|
||||
servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, CONTEXT_PATH);
|
||||
|
||||
repository.saveToken(csrfToken, request, response);
|
||||
|
||||
verify(response).addCookie(cookieArgumentCaptor.capture());
|
||||
final Cookie cookie = cookieArgumentCaptor.getValue();
|
||||
assertCookieEquals(csrfToken, cookie);
|
||||
assertEquals(COOKIE_CONTEXT_PATH, cookie.getPath());
|
||||
final Cookie cookie = assertCookieFound();
|
||||
final String setCookieHeader = response.getHeader(SET_COOKIE_HEADER);
|
||||
assertCookieEquals(csrfToken.getToken(), MAX_AGE_SESSION, cookie, setCookieHeader);
|
||||
assertEquals(CONTEXT_PATH, cookie.getPath());
|
||||
}
|
||||
|
||||
private void assertCookieEquals(final CsrfToken csrfToken, final Cookie cookie) {
|
||||
assertEquals(csrfToken.getToken(), cookie.getValue());
|
||||
assertEquals(MAX_AGE_SESSION, cookie.getMaxAge());
|
||||
private Cookie assertCookieFound() {
|
||||
final Cookie cookie = response.getCookie(SecurityCookieName.REQUEST_TOKEN.getName());
|
||||
assertNotNull(cookie);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
private void assertCookieEquals(final String token, final int maxAge, final Cookie cookie, final String setCookieHeader) {
|
||||
assertNotNull(setCookieHeader);
|
||||
assertEquals(token, cookie.getValue());
|
||||
assertEquals(maxAge, cookie.getMaxAge());
|
||||
assertTrue(cookie.getSecure());
|
||||
assertFalse(cookie.isHttpOnly());
|
||||
assertNull(cookie.getDomain());
|
||||
assertEquals(HOST, cookie.getDomain());
|
||||
assertTrue(setCookieHeader.contains(SAME_SITE), "SameSite not found");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue