import x0.maceShibboleth1.AttributeAcceptancePolicyDocument;
import x0.maceShibbolethTargetConfig1.ApplicationDocument;
+import x0.maceShibbolethTargetConfig1.GlobalConfigurationType;
import x0.maceShibbolethTargetConfig1.LocalConfigurationType;
import x0.maceShibbolethTargetConfig1.PluggableType;
import x0.maceShibbolethTargetConfig1.RequestMapDocument;
import x0.maceShibbolethTargetConfig1.HostDocument.Host;
import x0.maceShibbolethTargetConfig1.HostDocument.Host.Scheme.Enum;
import x0.maceShibbolethTargetConfig1.PathDocument.Path;
+import x0.maceShibbolethTargetConfig1.SessionsDocument.Sessions;
import edu.internet2.middleware.shibboleth.aap.AAP;
import edu.internet2.middleware.shibboleth.aap.AttributeRule;
import edu.internet2.middleware.shibboleth.aap.provider.XMLAAPProvider;
throw new ShibbolethConfigurationException("Problem parsing XML in "+configFilePath, e);
}
loadConfigBean(configDoc);
-
+
return;
}
-
+
+ public long getDefaultAttributeLifetime() {
+ return config.getGlobal().getMemorySessionCache().getDefaultLifetime();
+ }
+
+ public long getAAConnectTimeout() {
+ return config.getGlobal().getMemorySessionCache().getAAConnectTimeout();
+ }
+ public long getAATimeout() {
+ return config.getGlobal().getMemorySessionCache().getAATimeout();
+ }
+
+
/*
* Given a URL, determine its ApplicationId from the RequestMap config.
*
void addAapUri(String uri) {
aapUris.add(uri);
}
-
+
+ long getMaxSessionLife() {
+ Sessions sessions = applicationConfig.getSessions();
+ return sessions.getLifetime();
+ }
+ long getUnusedSessionTimeout() {
+ Sessions sessions = applicationConfig.getSessions();
+ return sessions.getTimeout();
+ }
+
/**
* Return the current array of objects that implement the
* ...metadata.Metadata interface
*/
private ServiceProviderContext() {
}
+
+ public void initialize() {
+ // Post-construction initialization of elements that require
+ // a reference back to the context.
+ sessionManager = new SessionManager();
+ }
// property accessor methods
- public synchronized SessionManager getSessionManager() {
- // deferred allocation, since sessionManger needs a reference
- // back to context.
- if (sessionManager==null)
- sessionManager = new SessionManager();
+ public SessionManager getSessionManager() {
return sessionManager;
}
try {
log.info("Initializing Service Provider.");
-
+ context.initialize();
ServiceProviderConfig config = new ServiceProviderConfig();
context.setServiceProviderConfig(config);
// could config.addOrReplaceXXXImplementor()
- context.setServiceProviderConfig(config);
-
log.info("Service Provider initialization complete.");
} catch (ShibbolethConfigurationException ex) {
/**
* Session object holds Authentication and Attribute Assertions for one
* remote Browser/User.<br>
- * Each session generates its own UUID key.<br>
+ * Each session generates its own random key.<br>
* The collection of Session objects may be checkpointed to disk using
* any attractive persistence framework, Object Relational mapping,
* or, hell, just serialize the objects to a flat file if you like.
* @author Howard Gilbert
*/
public class Session implements Serializable {
-
- // Default values from Shibboleth documentation
- private static final int DEFAULTTIMEOUT = 1800000;
- public static final int DEFAULTLIFETIME = 3600000;
-
- Session(String key) {
- // Should only be created by SessionManager
+ private long maxSessionLife;
+ private long unusedSessionTimeout;
+ private long defaultAttributeLifetime;
+
+ /**
+ * Create a Session object. Only used by the Session Manager, so it has package scope.
+ *
+ * @param key Random generated sessionId string
+ * @param maxSessionLife Maximum time this Session can remain valid
+ * @param unusedSessionTimeout Discard an unused Session
+ * @param defaultAttributeLifetime Default attribute validity time
+ */
+ Session(String key,
+ long maxSessionLife,
+ long unusedSessionTimeout,
+ long defaultAttributeLifetime) {
if (key==null)
throw new IllegalArgumentException();
this.key=key;
- this.timestamp = System.currentTimeMillis();
- }
-
- /**
- * For testing, create a Session that may already be timed out.
- */
- Session(String key, long timestamp) {
- this.key=key;
- this.timestamp = timestamp;
+ this.lastused = System.currentTimeMillis();
+ this.created = this.lastused;
+ this.maxSessionLife=maxSessionLife;
+ this.unusedSessionTimeout=unusedSessionTimeout;
+ this.defaultAttributeLifetime=defaultAttributeLifetime;
}
// Properties
this.entityId = entityId;
}
- private long lifetime = DEFAULTLIFETIME;
- public long getLifetime() {
- return lifetime;
- }
- public void setLifetime(long lifetime) {
- this.lifetime = lifetime;
- }
-
- private long timeout=DEFAULTTIMEOUT;
- public long getTimeout() {
- return timeout;
- }
- public void setTimeout(long timeout) {
- this.timeout = timeout;
- }
-
- // private persisted variable
- private long timestamp = 0;
+ private long lastused = 0;
+ private long created = 0;
public boolean isExpired() {
long now = System.currentTimeMillis();
- if (lifetime>0 && timestamp+lifetime<now)
+ if (maxSessionLife>0 &&
+ created+maxSessionLife<now)
return true;
- if (timeout>0 && timestamp+timeout<now)
+ if (unusedSessionTimeout>0 &&
+ lastused+unusedSessionTimeout<now)
return true;
return false;
}
this.attributeResponse = attributeResponse;
}
-
- public void renew(){
- timestamp = System.currentTimeMillis();
+ /**
+ * Called by Session Manager when the Session is used. Reset the
+ * unused timer.
+ */
+ void renew(){
+ lastused = System.currentTimeMillis();
}
+
+ public long getDefaultAttributeLifetime() {
+ return defaultAttributeLifetime;
+ }
+
+ public void setDefaultAttributeLifetime(long defaultAttributeLifetime) {
+ this.defaultAttributeLifetime = defaultAttributeLifetime;
+ }
+
+ public long getMaxSessionLife() {
+ return maxSessionLife;
+ }
+
+ public void setMaxSessionLife(long maxSessionLife) {
+ this.maxSessionLife = maxSessionLife;
+ }
+
+ public long getUnusedSessionTimeout() {
+ return unusedSessionTimeout;
+ }
+
+ public void setUnusedSessionTimeout(long unusedSessionTimeout) {
+ this.unusedSessionTimeout = unusedSessionTimeout;
+ }
}
import org.opensaml.SAMLResponse;
import org.opensaml.SAMLStatement;
-import x0.maceShibbolethTargetConfig1.SessionsDocument.Sessions;
-
import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderConfig.ApplicationInfo;
/**
private TreeMap sessions = new TreeMap(); // The memory cache of Sessions
private static ServiceProviderContext context = ServiceProviderContext.getInstance();
-
- private static SecureRandom rand = new SecureRandom();
- private static final String table = "0123456789" +
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
- "abcdefgjikjlmnopqrstuvwxyz"+
- "$@";
+
+
/**
- * Generate a 16 byte random ASCII string.
+ * Generate a 16 byte random ASCII string using
+ * cryptgraphically strong Java random generator.
+ *
* @return generated string
*/
public String generateKey() {
} while (null!=sessions.get(key));
return key;
}
+ private static SecureRandom rand = new SecureRandom();
+ private static final String table = "0123456789" +
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
+ "abcdefgjikjlmnopqrstuvwxyz"+
+ "$@";
/**
* Find a Session object given its sessionID key.
*
- * <p>Will not match uninitialized Sessions.</p>
+ * <p>Will not match uninitialized (reserved) Sessions.</p>
*
* @param sessionId ID and key of session
* @param applicationId Sanity check, must match session contents
public
String
newSession(
- String applicationId,
- String ipaddr,
- String entityId,
- SAMLAssertion assertion,
- SAMLAuthenticationStatement authenticationStatement,
+ String applicationId, // not null
+ String ipaddr, // may be null
+ String entityId, // not null
+ SAMLAssertion assertion, //not null
+ SAMLAuthenticationStatement authenticationStatement, // may be null
String emptySessionId // may be null
){
+ if (applicationId==null)
+ throw new IllegalArgumentException("applicationId null");
+ if (entityId==null)
+ throw new IllegalArgumentException("entityId null");
+ if (assertion==null)
+ throw new IllegalArgumentException("assertion null");
+
ServiceProviderConfig config = context.getServiceProviderConfig();
ApplicationInfo appinfo = config.getApplication(applicationId);
- Sessions appSessionValues = appinfo.getApplicationConfig().getSessions();
-
String sessionId = null;
- boolean isUpdate = false;
+ boolean isUpdate = false; // Assume new object
- Session session;
- if (emptySessionId==null) {
- session = new Session(generateKey());
- } else {
+ /*
+ * If the Id of a reserved, empty session is provided, then find
+ * that object and fill it in. Otherwise, create a new object.
+ */
+ Session session = null;
+ if (emptySessionId!=null) {
session = findEmptySession(emptySessionId);
- if (session==null) {
- session = new Session(generateKey());
- } else {
- isUpdate=true;
- }
+ }
+ if (session==null) {
+ session = new Session(generateKey(),
+ appinfo.getMaxSessionLife(),
+ appinfo.getUnusedSessionTimeout(),
+ config.getDefaultAttributeLifetime());
+ } else {
+ isUpdate=true; // mark so object is updated, not added
}
session.setApplicationId(applicationId);
- session.setIpaddr(ipaddr);
+ session.setIpaddr(ipaddr); // may be null
session.setEntityId(entityId);
session.setAuthenticationAssertion(assertion);
- session.setAuthenticationStatement(authenticationStatement);
-
- // Get lifetime and timeout from Applications/Sessions in config file
- session.setLifetime(appSessionValues.getLifetime()*1000);
- session.setTimeout(appSessionValues.getTimeout()*1000);
+ session.setAuthenticationStatement(authenticationStatement); // may be null
sessionId = session.getKey();
if (isUpdate)
- update(session);
+ update(session);
else
add(session);
reserveSession(
String applicationId
){
-
+ if (applicationId==null)
+ throw new IllegalArgumentException("applicationId null");
+
+ ServiceProviderConfig config = context.getServiceProviderConfig();
+ ApplicationInfo appinfo = config.getApplication(applicationId);
String sessionId = null;
- Session session= new Session(generateKey());
+ Session session= new Session(generateKey(),
+ appinfo.getMaxSessionLife(),
+ appinfo.getUnusedSessionTimeout(),
+ config.getDefaultAttributeLifetime());
session.setApplicationId(applicationId);
sessionId = session.getKey();
SessionCache cache) {
if (cache==null)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Session cache is null");
log.info("Enabling Session Cache");
/*
* The following code supports dynamic switching from
* @param configFileName URL format string pointing to configuration file
* @throws ShibbolethConfigurationException
*/
- public void initServiceProvider(String configFileName) throws ShibbolethConfigurationException{
+ public void initServiceProvider(String configFileName)
+ throws ShibbolethConfigurationException{
+ context.initialize();
ServiceProviderConfig config = new ServiceProviderConfig();
context.setServiceProviderConfig(config);
config.loadConfigObjects(configFileName);