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
*/