This is an automated email from the ASF dual-hosted git repository.
krisden pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 1b01961 KNOX-2155 - KnoxSSO should handle multiple cookies with the
same name
1b01961 is described below
commit 1b019617d408312ac33bf8f07f0ec862f7b33382
Author: Kevin Risden <[email protected]>
AuthorDate: Fri Dec 20 14:14:41 2019 -0500
KNOX-2155 - KnoxSSO should handle multiple cookies with the same name
This commit moves getting cookies by name to a
new utility class. It forces callers to look
through multiple cookies returned and handle
that case.
Signed-off-by: Kevin Risden <[email protected]>
---
.../jwt/filter/SSOCookieFederationFilter.java | 12 ----
.../provider/federation/jwt/JWTMessages.java | 3 -
.../jwt/filter/SSOCookieFederationFilter.java | 77 ++++++++++------------
.../provider/federation/SSOCookieProviderTest.java | 14 ++--
.../gateway/service/knoxsso/KnoxSSOMessages.java | 5 +-
.../gateway/service/knoxsso/WebSSOResource.java | 54 +++++++--------
.../gateway/i18n/GatewayUtilCommonMessages.java | 6 ++
.../org/apache/knox/gateway/util/CookieUtils.java | 50 ++++++++++++++
.../apache/knox/gateway/util/CookieUtilsTest.java | 68 +++++++++++++++++++
9 files changed, 191 insertions(+), 98 deletions(-)
diff --git
a/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
b/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
index 0af0153..d4e4340 100644
---
a/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
+++
b/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
@@ -39,18 +39,6 @@ public class SSOCookieFederationFilter
}
/**
- * Encapsulate the acquisition of the JWT token from HTTP cookies within the
- * request.
- *
- * @param req servlet request to get the JWT token from
- * @return serialized JWT token
- */
- @Override
- protected String getJWTFromCookie(HttpServletRequest req) {
- return super.getJWTFromCookie(req);
- }
-
- /**
* Create the URL to be used for authentication of the user in the absence of
* a JWT token within the incoming request.
*
diff --git
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
index 76d7837..e92d204 100644
---
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
+++
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
@@ -50,9 +50,6 @@ public interface JWTMessages {
@Message( level = MessageLevel.WARN, text = "Configuration for
authentication provider URL is missing - will derive default URL." )
void missingAuthenticationProviderUrlConfiguration();
- @Message( level = MessageLevel.DEBUG, text = "{0} Cookie has been found and
is being processed." )
- void cookieHasBeenFound(String cookieName);
-
@Message( level = MessageLevel.DEBUG, text = "Audience claim has been
validated." )
void jwtAudienceValidated();
}
diff --git
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
index cbdbbd1..814a5a7 100644
---
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
+++
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
@@ -23,6 +23,7 @@ import org.apache.knox.gateway.security.PrimaryPrincipal;
import org.apache.knox.gateway.services.security.token.impl.JWT;
import org.apache.knox.gateway.services.security.token.impl.JWTToken;
import org.apache.knox.gateway.util.CertificateUtils;
+import org.apache.knox.gateway.util.CookieUtils;
import org.eclipse.jetty.http.MimeTypes;
import javax.security.auth.Subject;
@@ -37,8 +38,11 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
+import java.util.List;
public class SSOCookieFederationFilter extends AbstractJWTFilter {
+ private static final JWTMessages LOGGER = MessagesFactory.get(
JWTMessages.class );
+
public static final String XHR_HEADER = "X-Requested-With";
public static final String XHR_VALUE = "XMLHttpRequest";
@@ -53,7 +57,6 @@ public class SSOCookieFederationFilter extends
AbstractJWTFilter {
private static final String ORIGINAL_URL_QUERY_PARAM = "originalUrl=";
private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt";
- private static JWTMessages log = MessagesFactory.get( JWTMessages.class );
private String cookieName;
private String authenticationProviderUrl;
@@ -78,7 +81,7 @@ public class SSOCookieFederationFilter extends
AbstractJWTFilter {
// url to SSO authentication provider
authenticationProviderUrl =
filterConfig.getInitParameter(SSO_AUTHENTICATION_PROVIDER_URL);
if (authenticationProviderUrl == null) {
- log.missingAuthenticationProviderUrlConfiguration();
+ LOGGER.missingAuthenticationProviderUrlConfiguration();
}
// token verification pem
@@ -101,35 +104,50 @@ public class SSOCookieFederationFilter extends
AbstractJWTFilter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
- String wireToken;
HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
- String loginURL = constructLoginURL(req);
- wireToken = getJWTFromCookie(req);
- if (wireToken == null) {
+ List<Cookie> ssoCookies = CookieUtils.getCookiesForName(req, cookieName);
+ if (ssoCookies.isEmpty()) {
if (req.getMethod().equals("OPTIONS")) {
// CORS preflight requests to determine allowed origins and related
config
// must be able to continue without being redirected
Subject sub = new Subject();
sub.getPrincipals().add(new PrimaryPrincipal("anonymous"));
- continueWithEstablishedSecurityContext(sub, req, (HttpServletResponse)
response, chain);
+ continueWithEstablishedSecurityContext(sub, req, res, chain);
+ } else {
+ sendRedirectToLoginURL(req, res);
}
- log.sendRedirectToLoginURL(loginURL);
- ((HttpServletResponse) response).sendRedirect(loginURL);
- }
- else {
- try {
- JWT token = new JWTToken(wireToken);
- if (validateToken((HttpServletRequest)request,
(HttpServletResponse)response, chain, token)) {
- Subject subject = createSubjectFromToken(token);
- continueWithEstablishedSecurityContext(subject,
(HttpServletRequest)request, (HttpServletResponse)response, chain);
+ } else {
+ for(Cookie ssoCookie : ssoCookies) {
+ String wireToken = ssoCookie.getValue();
+ try {
+ JWT token = new JWTToken(wireToken);
+ if (validateToken(req, res, chain, token)) {
+ Subject subject = createSubjectFromToken(token);
+ continueWithEstablishedSecurityContext(subject, req, res, chain);
+
+ // we found a valid cookie we don't need to keep checking anymore
+ return;
+ }
+ } catch (ParseException ignore) {
+ // Ignore the error since cookie was invalid
+ // Fall through to keep checking if there are more cookies
}
- } catch (ParseException ex) {
- ((HttpServletResponse) response).sendRedirect(loginURL);
}
+
+ // There were no valid cookies found so redirect to login url
+ sendRedirectToLoginURL(req, res);
}
}
+ private void sendRedirectToLoginURL(HttpServletRequest request,
HttpServletResponse response)
+ throws IOException {
+ String loginURL = constructLoginURL(request);
+ LOGGER.sendRedirectToLoginURL(loginURL);
+ response.sendRedirect(loginURL);
+ }
+
@Override
protected void handleValidationError(HttpServletRequest request,
HttpServletResponse response,
int status, String error) throws
IOException {
@@ -147,29 +165,6 @@ public class SSOCookieFederationFilter extends
AbstractJWTFilter {
String loginURL = constructLoginURL(request);
response.sendRedirect(loginURL);
}
-
- }
-
- /**
- * Encapsulate the acquisition of the JWT token from HTTP cookies within the
- * request.
- *
- * @param req servlet request to get the JWT token from
- * @return serialized JWT token
- */
- protected String getJWTFromCookie(HttpServletRequest req) {
- String serializedJWT = null;
- Cookie[] cookies = req.getCookies();
- if (cookies != null) {
- for (Cookie cookie : cookies) {
- if (cookieName.equals(cookie.getName())) {
- log.cookieHasBeenFound(cookieName);
- serializedJWT = cookie.getValue();
- break;
- }
- }
- }
- return serializedJWT;
}
/**
diff --git
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
index 4555461..720ed06 100644
---
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
+++
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
@@ -46,7 +46,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SSOCookieProviderTest extends AbstractJWTFilterTest {
- private static Logger LOGGER =
LoggerFactory.getLogger(SSOCookieProviderTest.class);
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SSOCookieProviderTest.class);
private static final String SERVICE_URL = "https://localhost:8888/resource";
@@ -58,8 +58,9 @@ public class SSOCookieProviderTest extends
AbstractJWTFilterTest {
@Override
protected void setTokenOnRequest(HttpServletRequest request, SignedJWT jwt) {
- Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
- EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+ Cookie cookie1 = new Cookie("hadoop-jwt", "garbage");
+ Cookie cookie2 = new Cookie("hadoop-jwt", jwt.serialize());
+ EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie1,
cookie2 });
if(ThreadLocalRandom.current().nextBoolean()) {
LOGGER.info("Using XHR header for request");
@@ -88,9 +89,10 @@ public class SSOCookieProviderTest extends
AbstractJWTFilterTest {
SignedJWT jwt = getJWT(AbstractJWTFilter.JWT_DEFAULT_ISSUER, "alice",
new Date(new Date().getTime() + 5000),
privateKey);
- Cookie cookie = new Cookie("jowt", jwt.serialize());
+ Cookie cookie1 = new Cookie("jowt", "garbage");
+ Cookie cookie2 = new Cookie("jowt", jwt.serialize());
HttpServletRequest request =
EasyMock.createNiceMock(HttpServletRequest.class);
- EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+ EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie1,
cookie2 });
EasyMock.expect(request.getRequestURL()).andReturn(
new StringBuffer(SERVICE_URL)).anyTimes();
EasyMock.expect(request.getQueryString()).andReturn(null);
@@ -103,7 +105,7 @@ public class SSOCookieProviderTest extends
AbstractJWTFilterTest {
handler.doFilter(request, response, chain);
Assert.assertTrue("doFilterCalled should not be false.",
chain.doFilterCalled );
Set<PrimaryPrincipal> principals =
chain.subject.getPrincipals(PrimaryPrincipal.class);
- Assert.assertTrue("No PrimaryPrincipal returned.",
!principals.isEmpty());
+ Assert.assertFalse("No PrimaryPrincipal returned.",
principals.isEmpty());
Assert.assertEquals("Not the expected principal", "alice",
((Principal)principals.toArray()[0]).getName());
} catch (ServletException se) {
fail("Should NOT have thrown a ServletException.");
diff --git
a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java
b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java
index 94de459..a1dc1bf 100644
---
a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java
+++
b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java
@@ -30,9 +30,6 @@ public interface KnoxSSOMessages {
@Message( level = MessageLevel.DEBUG, text = "Adding the following JWT token
as a cookie: {0}")
void addingJWTCookie(String token);
- @Message( level = MessageLevel.INFO, text = "Unable to find cookie with
name: {0}")
- void cookieNotFound(String name);
-
@Message( level = MessageLevel.ERROR, text = "Unable to properly send needed
HTTP status code: {0}, {1}")
void unableToCloseOutputStream(String message, String string);
@@ -63,4 +60,4 @@ public interface KnoxSSOMessages {
@Message( level = MessageLevel.ERROR, text = "The original URL: {0} for
redirecting back after authentication is " +
"not valid according to the configured whitelist: {1}. See documentation
for KnoxSSO Whitelisting.")
void whiteListMatchFail(String original, String whitelist);
-}
\ No newline at end of file
+}
diff --git
a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
index 54a315f..1fb8aa5 100644
---
a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
+++
b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
@@ -55,6 +55,7 @@ import
org.apache.knox.gateway.services.security.AliasServiceException;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.impl.JWT;
+import org.apache.knox.gateway.util.CookieUtils;
import org.apache.knox.gateway.util.RegExUtils;
import org.apache.knox.gateway.util.Urls;
import org.apache.knox.gateway.util.WhitelistUtils;
@@ -65,6 +66,8 @@ import static
org.apache.knox.gateway.services.GatewayServices.GATEWAY_CLUSTER_A
@Path( WebSSOResource.RESOURCE_PATH )
public class WebSSOResource {
+ private static final KnoxSSOMessages LOGGER = MessagesFactory.get(
KnoxSSOMessages.class );
+
private static final String SSO_COOKIE_NAME = "knoxsso.cookie.name";
private static final String SSO_COOKIE_SECURE_ONLY_INIT_PARAM =
"knoxsso.cookie.secure.only";
private static final String SSO_COOKIE_MAX_AGE_INIT_PARAM =
"knoxsso.cookie.max.age";
@@ -87,7 +90,6 @@ public class WebSSOResource {
private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt";
private static final long TOKEN_TTL_DEFAULT = 30000L;
static final String RESOURCE_PATH = "/api/v1/websso";
- private static KnoxSSOMessages log = MessagesFactory.get(
KnoxSSOMessages.class );
private String cookieName;
private boolean secureOnly = true;
private int maxAge = -1;
@@ -143,17 +145,17 @@ public class WebSSOResource {
secureOnly = Boolean.parseBoolean(secure);
}
if (!secureOnly) {
- log.cookieSecureOnly(secureOnly);
+ LOGGER.cookieSecureOnly(secureOnly);
}
String age = context.getInitParameter(SSO_COOKIE_MAX_AGE_INIT_PARAM);
if (age != null) {
try {
- log.setMaxAge(age);
+ LOGGER.setMaxAge(age);
maxAge = Integer.parseInt(age);
}
catch (NumberFormatException nfe) {
- log.invalidMaxAgeEncountered(age);
+ LOGGER.invalidMaxAgeEncountered(age);
}
}
@@ -177,12 +179,12 @@ public class WebSSOResource {
try {
tokenTTL = Long.parseLong(ttl);
if (tokenTTL < -1 || (tokenTTL + System.currentTimeMillis() < 0)) {
- log.invalidTokenTTLEncountered(ttl);
+ LOGGER.invalidTokenTTLEncountered(ttl);
tokenTTL = TOKEN_TTL_DEFAULT;
}
}
catch (NumberFormatException nfe) {
- log.invalidTokenTTLEncountered(ttl);
+ LOGGER.invalidTokenTTLEncountered(ttl);
}
}
}
@@ -203,14 +205,15 @@ public class WebSSOResource {
GatewayServices services =
(GatewayServices)
request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
boolean removeOriginalUrlCookie = true;
- String original = getCookieValue(request, ORIGINAL_URL_COOKIE_NAME);
- if (original == null) {
+ List<Cookie> originalUrlCookies = CookieUtils.getCookiesForName(request,
ORIGINAL_URL_COOKIE_NAME);
+ String original;
+ if (originalUrlCookies.isEmpty()) {
// in the case where there are no SAML redirects done before here
// we need to get it from the request parameters
removeOriginalUrlCookie = false;
original = getOriginalUrlFromQueryParams();
if (original.isEmpty()) {
- log.originalURLNotFound();
+ LOGGER.originalURLNotFound();
throw new WebApplicationException("Original URL not found in the
request.", Response.Status.BAD_REQUEST);
}
@@ -230,10 +233,13 @@ public class WebSSOResource {
}
if (!validRedirect) {
- log.whiteListMatchFail(Log4jAuditor.maskTokenFromURL(original),
whitelist);
+ LOGGER.whiteListMatchFail(Log4jAuditor.maskTokenFromURL(original),
whitelist);
throw new WebApplicationException("Original URL not valid according to
the configured whitelist.",
Response.Status.BAD_REQUEST);
}
+ } else {
+ // There should only be one original url cookie for the given path
+ original = originalUrlCookies.get(0).getValue();
}
AliasService as = services.getService(ServiceType.ALIAS_SERVICE);
@@ -261,16 +267,16 @@ public class WebSSOResource {
removeOriginalUrlCookie(response);
}
- log.aboutToRedirectToOriginal(Log4jAuditor.maskTokenFromURL(original));
+
LOGGER.aboutToRedirectToOriginal(Log4jAuditor.maskTokenFromURL(original));
response.setStatus(statusCode);
response.setHeader("Location", original);
try {
response.getOutputStream().close();
} catch (IOException e) {
- log.unableToCloseOutputStream(e.getMessage(),
Arrays.toString(e.getStackTrace()));
+ LOGGER.unableToCloseOutputStream(e.getMessage(),
Arrays.toString(e.getStackTrace()));
}
} catch (TokenServiceException| AliasServiceException e) {
- log.unableToIssueToken(e);
+ LOGGER.unableToIssueToken(e);
}
URI location = null;
try {
@@ -343,7 +349,7 @@ public class WebSSOResource {
}
private void addJWTHadoopCookie(String original, JWT token) {
- log.addingJWTCookie(token.toString());
+ LOGGER.addingJWTCookie(token.toString());
Cookie c = new Cookie(cookieName, token.toString());
c.setPath("/");
try {
@@ -359,10 +365,10 @@ public class WebSSOResource {
c.setMaxAge(maxAge);
}
response.addCookie(c);
- log.addedJWTCookie();
+ LOGGER.addedJWTCookie();
}
catch(Exception e) {
- log.unableAddCookieToResponse(e.getMessage(),
Arrays.toString(e.getStackTrace()));
+ LOGGER.unableAddCookieToResponse(e.getMessage(),
Arrays.toString(e.getStackTrace()));
throw new WebApplicationException("Unable to add JWT cookie to
response.");
}
}
@@ -373,20 +379,4 @@ public class WebSSOResource {
c.setPath(RESOURCE_PATH);
response.addCookie(c);
}
-
- private String getCookieValue(HttpServletRequest request, String name) {
- Cookie[] cookies = request.getCookies();
- String value = null;
- if (cookies != null) {
- for(Cookie cookie : cookies){
- if(name.equals(cookie.getName())){
- value = cookie.getValue();
- }
- }
- }
- if (value == null) {
- log.cookieNotFound(name);
- }
- return value;
- }
}
diff --git
a/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java
b/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java
index 96a8e32..34afd21 100644
---
a/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java
+++
b/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java
@@ -38,4 +38,10 @@ public interface GatewayUtilCommonMessages {
@Message(level = MessageLevel.ERROR, text = "Failed to serialize Object to
Json string {0}: {1}" )
void failedToSerializeObjectToJSON( Object obj, @StackTrace( level =
MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.INFO, text = "Unable to find cookie with
name: {0}")
+ void cookieNotFound(String name);
+
+ @Message( level = MessageLevel.DEBUG, text = "{0} Cookie has been found." )
+ void cookieHasBeenFound(String cookieName);
}
diff --git
a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java
b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java
new file mode 100644
index 0000000..6f94353
--- /dev/null
+++
b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java
@@ -0,0 +1,50 @@
+/*
+ * 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.knox.gateway.util;
+
+import org.apache.knox.gateway.i18n.GatewayUtilCommonMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CookieUtils {
+ private static final GatewayUtilCommonMessages LOGGER =
MessagesFactory.get(GatewayUtilCommonMessages.class);
+
+ private CookieUtils() {
+ }
+
+ public static List<Cookie> getCookiesForName(HttpServletRequest request,
String name) {
+ List<Cookie> cookiesByName = new ArrayList<>();
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for(Cookie cookie : cookies){
+ if(name.equals(cookie.getName())){
+ cookiesByName.add(cookie);
+ }
+ }
+ }
+ if (cookiesByName.isEmpty()) {
+ LOGGER.cookieNotFound(name);
+ }
+ return cookiesByName;
+ }
+}
diff --git
a/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java
b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java
new file mode 100644
index 0000000..d2063e4
--- /dev/null
+++
b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.knox.gateway.util;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+public class CookieUtilsTest {
+ @Test
+ public void testNoCookies() {
+ HttpServletRequest httpServletRequest =
EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(httpServletRequest.getCookies()).andReturn(null);
+ EasyMock.replay(httpServletRequest);
+
+ Assert.assertTrue(CookieUtils.getCookiesForName(httpServletRequest,
"any").isEmpty());
+ }
+
+ @Test
+ public void testNoCookiesByName() {
+ Cookie[] cookies = new Cookie[] {
+ new Cookie("one", "1"),
+ new Cookie("two", "2")
+ };
+
+ HttpServletRequest httpServletRequest =
EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(httpServletRequest.getCookies()).andReturn(cookies);
+ EasyMock.replay(httpServletRequest);
+
+ Assert.assertTrue(CookieUtils.getCookiesForName(httpServletRequest,
"noMatch").isEmpty());
+ }
+
+ @Test
+ public void testCookiesByName() {
+ Cookie one = new Cookie("one", "1");
+ Cookie two = new Cookie("two", "2");
+ Cookie onea = new Cookie("one", "1a");
+ Cookie[] expectedCookies = new Cookie[] { one, two, onea };
+
+ HttpServletRequest httpServletRequest =
EasyMock.createMock(HttpServletRequest.class);
+
EasyMock.expect(httpServletRequest.getCookies()).andReturn(expectedCookies);
+ EasyMock.replay(httpServletRequest);
+
+ List<Cookie> actualCookies =
CookieUtils.getCookiesForName(httpServletRequest, "one");
+ Assert.assertEquals(2, actualCookies.size());
+ Assert.assertEquals(one, actualCookies.get(0));
+ Assert.assertEquals(onea, actualCookies.get(1));
+ }
+}