You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2018/03/08 14:45:02 UTC
knox git commit: KNOX-1190 - Compress cookies set by Pac4J,
in some cases the cookie size exceeds 4K and cause them not to set.
Repository: knox
Updated Branches:
refs/heads/master 9b5665be7 -> 6f4555418
KNOX-1190 - Compress cookies set by Pac4J, in some cases the cookie size exceeds 4K and cause them not to set.
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/6f455541
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/6f455541
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/6f455541
Branch: refs/heads/master
Commit: 6f45554182d122a39511a6d145d5f99b4cc19c50
Parents: 9b5665b
Author: Sandeep More <mo...@apache.org>
Authored: Thu Mar 8 09:44:56 2018 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Thu Mar 8 09:44:56 2018 -0500
----------------------------------------------------------------------
.../pac4j/filter/Pac4jDispatcherFilter.java | 18 ++++-
.../gateway/pac4j/session/KnoxSessionStore.java | 73 +++++++++++++++++---
2 files changed, 82 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/6f455541/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
index 0086228..46186f6 100644
--- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
@@ -17,6 +17,7 @@
*/
package org.apache.knox.gateway.pac4j.filter;
+import org.apache.commons.lang.StringUtils;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.pac4j.Pac4jMessages;
import org.apache.knox.gateway.pac4j.session.KnoxSessionStore;
@@ -29,6 +30,8 @@ import org.apache.knox.gateway.services.security.CryptoService;
import org.pac4j.config.client.PropertiesConfigFactory;
import org.pac4j.core.client.Client;
import org.pac4j.core.config.Config;
+import org.pac4j.core.context.session.J2ESessionStore;
+import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.util.CommonHelper;
import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
@@ -71,6 +74,8 @@ public class Pac4jDispatcherFilter implements Filter {
private static final String PAC4J_CONFIG = "pac4j.config";
+ private static final String PAC4J_SESSION_STORE = "pac4j.session.store";
+
private CallbackFilter callbackFilter;
private SecurityFilter securityFilter;
@@ -160,7 +165,18 @@ public class Pac4jDispatcherFilter implements Filter {
securityFilter.setConfigOnly(config);
final String domainSuffix = filterConfig.getInitParameter(PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM);
- config.setSessionStore(new KnoxSessionStore(cryptoService, clusterName, domainSuffix));
+ final String sessionStoreVar = filterConfig.getInitParameter(PAC4J_SESSION_STORE);
+
+ SessionStore sessionStore;
+
+ if(!StringUtils.isBlank(sessionStoreVar) && J2ESessionStore.class.getName().contains(sessionStoreVar) ) {
+ sessionStore = new J2ESessionStore();
+ } else {
+ sessionStore = new KnoxSessionStore(cryptoService, clusterName, domainSuffix);
+ }
+
+ config.setSessionStore(sessionStore);
+
}
private void addDefaultConfig(String clientNameParameter, Map<String, String> properties) {
http://git-wip-us.apache.org/repos/asf/knox/blob/6f455541/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
index 4ba55ea..0eb5322 100644
--- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
@@ -18,6 +18,7 @@
package org.apache.knox.gateway.pac4j.session;
import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
import org.apache.knox.gateway.services.security.CryptoService;
import org.apache.knox.gateway.services.security.EncryptionResult;
import org.apache.knox.gateway.util.Urls;
@@ -30,8 +31,13 @@ import org.pac4j.core.util.JavaSerializationHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
/**
* Specific session store where data are saved into cookies (and not in memory).
@@ -66,7 +72,7 @@ public class KnoxSessionStore implements SessionStore {
return null;
}
- private Serializable decryptBase64(final String v) {
+ private Serializable uncompressDecryptBase64(final String v) {
if (v != null && v.length() > 0) {
byte[] bytes = Base64.decodeBase64(v);
EncryptionResult result = EncryptionResult.fromByteArray(bytes);
@@ -76,7 +82,11 @@ public class KnoxSessionStore implements SessionStore {
result.iv,
result.salt);
if (clear != null) {
- return javaSerializationHelper.unserializeFromBytes(clear);
+ try {
+ return javaSerializationHelper.unserializeFromBytes(unCompress(clear));
+ } catch (IOException e) {
+ throw new TechnicalException(e);
+ }
}
}
return null;
@@ -86,18 +96,31 @@ public class KnoxSessionStore implements SessionStore {
final Cookie cookie = ContextHelper.getCookie(context, PAC4J_SESSION_PREFIX + key);
Object value = null;
if (cookie != null) {
- value = decryptBase64(cookie.getValue());
+ value = uncompressDecryptBase64(cookie.getValue());
}
logger.debug("Get from session: {} = {}", key, value);
return value;
}
- private String encryptBase64(final Object o) {
+ private String compressEncryptBase64(final Object o) {
if (o == null || o.equals("")
|| (o instanceof Map<?,?> && ((Map<?,?>)o).isEmpty())) {
return null;
} else {
- final byte[] bytes = javaSerializationHelper.serializeToBytes((Serializable) o);
+ byte[] bytes = javaSerializationHelper.serializeToBytes((Serializable) o);
+
+ /* compress the data */
+ try {
+ bytes = compress(bytes);
+
+ if(bytes.length > 3000) {
+ logger.warn("Cookie too big, it might not be properly set");
+ }
+
+ } catch (final IOException e) {
+ throw new TechnicalException(e);
+ }
+
EncryptionResult result = cryptoService.encryptForCluster(this.clusterName, PAC4J_PASSWORD, bytes);
return Base64.encodeBase64String(result.toByteAray());
}
@@ -105,7 +128,7 @@ public class KnoxSessionStore implements SessionStore {
public void set(WebContext context, String key, Object value) {
logger.debug("Save in session: {} = {}", key, value);
- final Cookie cookie = new Cookie(PAC4J_SESSION_PREFIX + key, encryptBase64(value));
+ final Cookie cookie = new Cookie(PAC4J_SESSION_PREFIX + key, compressEncryptBase64(value));
try {
String domain = Urls.getDomainName(context.getFullRequestURL(), this.domainSuffix);
if (domain == null) {
@@ -120,6 +143,41 @@ public class KnoxSessionStore implements SessionStore {
context.addResponseCookie(cookie);
}
+ /**
+ * A function used to compress the data using GZIP
+ * @param data
+ * @return gziped data
+ * @since 1.1.0
+ */
+ private static byte[] compress(final byte[] data) throws IOException {
+
+ try (final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(
+ data.length);
+ final GZIPOutputStream gzip = new GZIPOutputStream(byteStream)) {
+ gzip.write(data);
+ gzip.close();
+ return byteStream.toByteArray();
+ }
+ }
+
+ /**
+ * Decompress the data compressed using gzip
+ *
+ * @param data
+ * @return uncompressed data
+ * @throws IOException
+ * @since 1.1.0
+ */
+ private static byte[] unCompress(final byte[] data) throws IOException {
+
+ try (final ByteArrayInputStream inputStream = new ByteArrayInputStream(
+ data);
+ final GZIPInputStream gzip = new GZIPInputStream(inputStream)) {
+ return IOUtils.toByteArray(gzip);
+ }
+ }
+
+
@Override
public SessionStore buildFromTrackableSession(WebContext arg0, Object arg1) {
// TODO Auto-generated method stub
@@ -139,8 +197,7 @@ public class KnoxSessionStore implements SessionStore {
}
@Override
- public boolean renewSession(WebContext arg0) {
- // TODO Auto-generated method stub
+ public boolean renewSession(final WebContext context) {
return false;
}
}