KNOX-1378 - Declare SSO params using KnoxSSO service option  knoxsso.expected.params
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 cda3d48..17e5c7c 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
@@ -65,6 +65,10 @@
   private static final String SSO_COOKIE_TOKEN_AUDIENCES_PARAM = "knoxsso.token.audiences";
   private static final String SSO_COOKIE_TOKEN_SIG_ALG = "knoxsso.token.sigalg";
   private static final String SSO_COOKIE_TOKEN_WHITELIST_PARAM = "knoxsso.redirect.whitelist.regex";
+
+  /* parameters expected by knoxsso */
+  private static final String SSO_EXPECTED_PARAM = "knoxsso.expected.params";
+
   private static final String SSO_ENABLE_SESSION_PARAM = "knoxsso.enable.session";
   private static final String ORIGINAL_URL_REQUEST_PARAM = "originalUrl";
   private static final String ORIGINAL_URL_COOKIE_NAME = "original-url";
@@ -81,6 +85,7 @@
   private List<String> targetAudiences = new ArrayList<>();
   private boolean enableSession = false;
   private String signatureAlgorithm = "RS256";
+  private List<String> ssoExpectedparams = new ArrayList<>();
 
   @Context
   HttpServletRequest request;
@@ -155,6 +160,11 @@
     if (sigAlg != null) {
       signatureAlgorithm = sigAlg;
     }
+
+    final String expectedParams = context.getInitParameter(SSO_EXPECTED_PARAM);
+    if (expectedParams != null) {
+      ssoExpectedparams = Arrays.asList(expectedParams.split(","));
+    }
   }
 
   @GET
@@ -262,13 +272,22 @@
     String original = request.getParameter(ORIGINAL_URL_REQUEST_PARAM);
     StringBuffer buf = new StringBuffer(original);
 
+    boolean first = true;
+
     // Add any other query params.
     // Probably not ideal but will not break existing integrations by requiring
     // some encoding.
     Map<String, String[]> params = request.getParameterMap();
     for (Entry<String, String[]> entry : params.entrySet()) {
       if (!ORIGINAL_URL_REQUEST_PARAM.equals(entry.getKey())
-          && !original.contains(entry.getKey() + "=")) {
+          && !original.contains(entry.getKey() + "=")
+          && !ssoExpectedparams.contains(entry.getKey())) {
+
+        if(first) {
+          buf.append("?");
+          first = false;
+        }
+
         buf.append("&").append(entry.getKey());
         String[] values = entry.getValue();
         if (values.length > 0 && values[0] != null) {
diff --git a/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java b/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
index 19a8f03..a631d73 100644
--- a/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
+++ b/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
@@ -49,6 +49,7 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponseWrapper;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
 
 import org.apache.knox.gateway.services.GatewayServices;
 import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
@@ -760,6 +761,71 @@
     assertEquals("^.*$", whitelistValue);
   }
 
+  @Test
+  public void testExpectedKnoxSSOParams() throws Exception {
+
+    final HashMap<String, String[]> paramMap = new HashMap<>();
+    paramMap.put("knoxtoken", new String[]{"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiO"
+        + "iJhZG1pbjEiLCJpc3MiOiJLTk9YU1NPIiwiZXhwIjoxNTMwODk1NjUw"
+        + "fQ.Sodks_BTwaijMM5eg9rY77ro1H4um12TCqmwL5eWn4IMWBBXZQOV"
+        + "D4JRWNKG_OtITKvkn9EhowOZO6Qtb6tvZLUPyW8Bf9gfgKAHJNLSYyc"
+        + "yWSPzBOc2kcPmwdYXkOXtPu6KWZaQcD-WRw-89aORbgqZVRKX2Zyk2MLb0Rnig_0"});
+
+    final String originalUrl = "http://localhost:9080/service";
+
+
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(context.getInitParameter("knoxsso.expected.params")).andReturn("knoxtoken,originalUrl");
+
+    ServletContext contextNoParam = EasyMock.createNiceMock(ServletContext.class);
+
+    HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+    EasyMock.expect(request.getParameter("originalUrl")).andReturn(originalUrl).anyTimes();
+    EasyMock.expect(request.getParameterMap()).andReturn(paramMap).anyTimes();
+    EasyMock.expect(request.getServletContext()).andReturn(context).anyTimes();
+
+    Principal principal = EasyMock.createNiceMock(Principal.class);
+    EasyMock.expect(principal.getName()).andReturn("tom").anyTimes();
+    EasyMock.expect(request.getUserPrincipal()).andReturn(principal).anyTimes();
+
+    GatewayServices services = EasyMock.createNiceMock(GatewayServices.class);
+    EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).andReturn(services).anyTimes();
+
+    JWTokenAuthority authority = new TestJWTokenAuthority(publicKey, privateKey);
+    EasyMock.expect(services.getService(GatewayServices.TOKEN_SERVICE)).andReturn(authority).anyTimes();
+
+    HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+    ServletOutputStream outputStream = EasyMock.createNiceMock(ServletOutputStream.class);
+    CookieResponseWrapper responseWrapper = new CookieResponseWrapper(response, outputStream);
+
+    EasyMock.replay(principal, services, context, contextNoParam, request);
+
+    /* declare knoxtoken as part of knoxsso param so it is stripped from the final url */
+    WebSSOResource webSSOResponse = new WebSSOResource();
+    webSSOResponse.request = request;
+    webSSOResponse.response = responseWrapper;
+    webSSOResponse.context = context;
+    webSSOResponse.init();
+
+    Response resp = webSSOResponse.doGet();
+    assertEquals(originalUrl, resp.getLocation().toString());
+
+    /* declare knoxtoken as NOT part of knoxsso param so it is stripped from the final url */
+    webSSOResponse = new WebSSOResource();
+    webSSOResponse.request = request;
+    webSSOResponse.response = responseWrapper;
+    webSSOResponse.context = contextNoParam;
+    webSSOResponse.init();
+
+    resp = webSSOResponse.doGet();
+    assertEquals(originalUrl+"?&"+"knoxtoken="+"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiO"
+        + "iJhZG1pbjEiLCJpc3MiOiJLTk9YU1NPIiwiZXhwIjoxNTMwODk1NjUw"
+        + "fQ.Sodks_BTwaijMM5eg9rY77ro1H4um12TCqmwL5eWn4IMWBBXZQOV"
+        + "D4JRWNKG_OtITKvkn9EhowOZO6Qtb6tvZLUPyW8Bf9gfgKAHJNLSYyc"
+        + "yWSPzBOc2kcPmwdYXkOXtPu6KWZaQcD-WRw-89aORbgqZVRKX2Zyk2MLb0Rnig_0",resp.getLocation().toString());
+
+  }
+
   /**
    * A wrapper for HttpServletResponseWrapper to store the cookies
    */