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 <kris...@apache.org>
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 <kris...@apache.org>
---
 .../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));
+  }
+}

Reply via email to