package org.wso2.carbon.identity.authenticator.saml2.sso.ui.session;
import org.apache.axis2.clustering.ClusteringAgent;
import org.apache.axis2.clustering.ClusteringFault;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.authenticator.saml2.sso.ui.internal.SAML2SSOAuthFEDataHolder;
import org.wso2.carbon.ui.CarbonSSOSessionManager;
import org.wso2.carbon.ui.CarbonSecuredHttpContext;
import org.wso2.carbon.ui.CarbonUIAuthenticator;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class SSOSessionManager {
public static final Log log = LogFactory.getLog(SSOSessionManager.class);
private static volatile SSOSessionManager instance;
private Map sessionMap = new ConcurrentHashMap<String, HttpSession>();
public static SSOSessionManager getInstance() {
if (instance == null) {
synchronized (SSOSessionManager.class) {
if (instance == null) {
instance = new SSOSessionManager();
}
}
}
return instance;
}
public void addSession(String sessionIndex, HttpSession httpSession) {
sessionMap.put(sessionIndex, httpSession);
}
public void removeSession(String sessionIndex) {
if (sessionMap.containsKey(sessionIndex)) {
sessionMap.remove(sessionIndex);
}
}
public HttpSession getSession(String sessionIndex) {
Object session = sessionMap.get(sessionIndex);
if (session != null) {
return (HttpSession) session;
}
return null;
}
public void handleLogout(String sessionIndex) {
HttpSession session = (HttpSession) sessionMap.get(sessionIndex);
if (session == null) {
//send cluster message
sendSessionInvalidationClusterMessage(sessionIndex);
return;
}
CarbonSSOSessionManager ssoSessionManager = SAML2SSOAuthFEDataHolder.getInstance()
.getCarbonSSOSessionManager();
// mark this session as invalid.
ssoSessionManager.makeSessionInvalid(sessionIndex);
String username = (String) session.getAttribute(CarbonSecuredHttpContext.LOGGED_USER);
log.info("Invalidating session for user " + username);
// invalidating backend session
try {
CarbonUIAuthenticator authenticator =
(CarbonUIAuthenticator) session.getAttribute(CarbonSecuredHttpContext.CARBON_AUTHNETICATOR);
if (authenticator != null) {
authenticator.unauthenticate(session);
log.debug("Backend session invalidated");
}
} catch (Exception e) {
log.error(e.getMessage());
}
// clearing front end session
session.setAttribute("authenticated", false);
session.removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
session.getServletContext().removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
removeSession(sessionIndex);
try {
session.invalidate();
} catch (Exception ignored) {
log.error(ignored.getMessage());
}
if (log.isDebugEnabled()) {
log.debug("Cleared authenticated session " + session.getId());
}
}
public void sendSessionInvalidationClusterMessage(String sessionIndex) {
SessionClusterMessage clusterMessage = new SessionClusterMessage();
clusterMessage.setMessageId(UUID.randomUUID());
clusterMessage.setSessionIndex(sessionIndex);
ClusteringAgent clusteringAgent = SAML2SSOAuthFEDataHolder.getInstance()
.getConfigurationContextService().getServerConfigContext().getAxisConfiguration()
.getClusteringAgent();
if (clusteringAgent != null) {
int numberOfRetries = 0;
while (numberOfRetries < 60) {
try {
clusteringAgent.sendMessage(clusterMessage, true);
log.info("Sent [" + clusterMessage + "]");
break;
} catch (ClusteringFault e) {
numberOfRetries++;
if (numberOfRetries < 60) {
log.warn(
"Could not send SSOSessionInvalidationClusterMessage. Retry will be attempted in 2s. Request: "
+ clusterMessage, e);
} else {
log.error(
"Could not send SSOSessionInvalidationClusterMessage. Several retries failed. Request:"
+ clusterMessage, e);
}
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
}
}
}
}
}
}