Skip to content

Commit

Permalink
changes to support single-sign-on (sso)
Browse files Browse the repository at this point in the history
  • Loading branch information
ran-jit committed May 2, 2020
1 parent 372332e commit 39df088
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 21 deletions.
15 changes: 14 additions & 1 deletion src/main/java/tomcat/request/session/model/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
/** author: Ranjith Manickam @ 5 Feb' 2020 */
public class Config implements Serializable {

private static final long serialVersionUID = 3480402257971437776L;

public static final String APPLICATION_PROPERTIES_FILE = "redis-data-cache.properties";

/** Redis config type. */
Expand Down Expand Up @@ -77,6 +79,9 @@ public enum RedisConfigType {
@Property(name = "session.persistent.policies", defaultValue = "DEFAULT")
private String sessionPersistentPolicies;

@Property(name = "redis.sso.timeout", type = INTEGER, defaultValue = "0")
private Integer redisSSOTimeout;

public Config() {
}

Expand All @@ -98,7 +103,8 @@ public Config(String redisHosts,
String redisSentinelMaster,
Integer redisSessionExpiryJobInterval,
Integer redisSessionDataSyncJobInterval,
String sessionPersistentPolicies) {
String sessionPersistentPolicies,
Integer redisSSOTimeout) {
this.redisHosts = redisHosts;
this.redisClusterEnabled = redisClusterEnabled;
this.redisSentinelEnabled = redisSentinelEnabled;
Expand All @@ -118,6 +124,7 @@ public Config(String redisHosts,
this.redisSessionExpiryJobInterval = redisSessionExpiryJobInterval;
this.redisSessionDataSyncJobInterval = redisSessionDataSyncJobInterval;
this.sessionPersistentPolicies = sessionPersistentPolicies;
this.redisSSOTimeout = redisSSOTimeout;
}

/** To get 'redis.hosts' value. */
Expand Down Expand Up @@ -215,6 +222,11 @@ public String getSessionPersistentPolicies() {
return sessionPersistentPolicies;
}

/** To get 'redis.sso.timeout' value */
public Integer getRedisSSOTimeout() {
return redisSSOTimeout;
}

/** {@inheritDoc} */
@Override
public String toString() {
Expand All @@ -238,6 +250,7 @@ public String toString() {
", redisSessionExpiryJobInterval=" + redisSessionExpiryJobInterval +
", redisSessionDataSyncJobInterval=" + redisSessionDataSyncJobInterval +
", sessionPersistentPolicies='" + sessionPersistentPolicies + '\'' +
", redisSSOTimeout='" + redisSSOTimeout + '\'' +
'}';
}

Expand Down
17 changes: 7 additions & 10 deletions src/main/java/tomcat/request/session/redis/SessionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ public class SessionManager extends ManagerBase implements Lifecycle {

private static final Logger LOGGER = LoggerFactory.getLogger(SessionManager.class);

private Integer ssoTimeout;
private DataCache dataCache;
private SerializationUtil serializer;
private ThreadLocal<SessionContext> sessionContext = new ThreadLocal<>();
private Set<SessionPolicy> sessionPolicy = EnumSet.of(SessionPolicy.DEFAULT);
private final ThreadLocal<SessionContext> sessionContext = new ThreadLocal<>();
private final Set<SessionPolicy> sessionPolicy = EnumSet.of(SessionPolicy.DEFAULT);

public boolean getSaveOnChange() {
return this.sessionPolicy.contains(SessionPolicy.SAVE_ON_CHANGE);
Expand Down Expand Up @@ -78,14 +79,6 @@ protected synchronized void startInternal() throws LifecycleException {
initializedValve = true;
break;
}

if (valve instanceof SingleSignOnValve) {
SingleSignOnValve ssoValve = (SingleSignOnValve) valve;
ssoValve.setSessionManager(this);
ssoValve.setContext(context);
initializedValve = true;
break;
}
}

if (!initializedValve) {
Expand Down Expand Up @@ -218,6 +211,7 @@ public void unload() {
private void initialize() {
try {
Config config = ConfigUtil.getConfig();
this.ssoTimeout = config.getRedisSSOTimeout();
this.dataCache = new DataCacheFactory(config, getSessionTimeout(null)).getDataCache();
this.serializer = new SerializationUtil();

Expand Down Expand Up @@ -353,6 +347,9 @@ void setSingleSignOnEntry(String ssoId, SingleSignOnEntry entry) {
try {
byte[] data = this.serializer.serializeSingleSignOnEntry(entry);
this.dataCache.set(ssoId, data);
if (this.ssoTimeout > 0) {
this.dataCache.expire(ssoId, this.ssoTimeout);
}
} catch (IOException ex) {
LOGGER.error("Error occurred while serializing the single-sign-on entry..", ex);
}
Expand Down
28 changes: 19 additions & 9 deletions src/main/java/tomcat/request/session/redis/SingleSignOnValve.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Manager;
import org.apache.catalina.Realm;
import org.apache.catalina.Session;
Expand All @@ -26,14 +28,27 @@ public class SingleSignOnValve extends SingleSignOn {

private static final Logger LOGGER = LoggerFactory.getLogger(SingleSignOnValve.class);

private Context context;
private Engine engine;
private SessionManager manager;

/** {@inheritDoc} */
@Override
protected synchronized void startInternal() throws LifecycleException {
Container c;
for (c = this.getContainer(); c != null && !(c instanceof Engine); c = c.getParent()) {
}

if (c instanceof Engine) {
this.engine = (Engine) c;
}

super.startInternal();
}

/** {@inheritDoc} */
@Override
public void invoke(Request request, Response response) throws BackendException {
try {
this.setContext(request.getContext());
this.setSessionManager(request.getContext().getManager());

request.removeNote("org.apache.catalina.request.SSOID");
Expand Down Expand Up @@ -213,17 +228,12 @@ void setSessionManager(Manager manager) {
this.manager = (SessionManager) manager;
}

/** To set context. */
void setContext(Context context) {
this.context = context;
}

/** To expire session. */
private void expire(SingleSignOnSessionKey key) {
if (this.context == null) {
if (this.engine == null) {
LOGGER.warn("singleSignOn.sessionExpire.engineNull, key: {}", key);
} else {
Container host = this.context.findChild(key.getHostName());
Container host = this.engine.findChild(key.getHostName());
if (host == null) {
LOGGER.warn("singleSignOn.sessionExpire.hostNotFound, key: {}", key);
} else {
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/redis-data-cache.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ lb.sticky-session.enabled=false
# policies - DEFAULT, SAVE_ON_CHANGE, ALWAYS_SAVE_AFTER_REQUEST
# 1. SAVE_ON_CHANGE: every time session.setAttribute() or session.removeAttribute() is called the session will be saved.
# 2. ALWAYS_SAVE_AFTER_REQUEST: force saving after every request, regardless of whether or not the manager has detected changes to the session.
session.persistent.policies=DEFAULT
session.persistent.policies=DEFAULT

#- single-sign-on session timeout. (default value: 0 ms (-no expiry))
redis.sso.timeout=0

0 comments on commit 39df088

Please sign in to comment.