/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ package at.gv.egovernment.moa.id.storage; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.lang.SerializationUtils; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OldSSOSessionIDStore; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.data.EncryptedData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SessionEncrytionUtil; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; public class AuthenticationSessionStoreage { //private static HashMap sessionStore = new HashMap(); public static boolean isAuthenticated(String moaSessionID) { AuthenticatedSessionStore session; try { session = searchInDatabase(moaSessionID); return session.isAuthenticated(); } catch (MOADatabaseException e) { return false; } } public static void setAuthenticated(String moaSessionID, boolean value) { AuthenticatedSessionStore session; try { session = searchInDatabase(moaSessionID); session.setAuthenticated(value); MOASessionDBUtils.saveOrUpdate(session); } catch (MOADatabaseException e) { Logger.warn("isAuthenticated can not be stored in MOASession " + moaSessionID, e); } } public static AuthenticationSession createSession() throws MOADatabaseException { String id = Random.nextRandom(); AuthenticationSession session = new AuthenticationSession(id); AuthenticatedSessionStore dbsession = new AuthenticatedSessionStore(); dbsession.setSessionid(id); dbsession.setAuthenticated(false); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 dbsession.setCreated(new Date()); dbsession.setUpdated(new Date()); dbsession.setSession(SerializationUtils.serialize(session)); //store AssertionStore element to Database try { MOASessionDBUtils.saveOrUpdate(dbsession); Logger.info("MOASession with sessionID=" + id + " is stored in Database"); } catch (MOADatabaseException e) { Logger.warn("MOASession could not be created."); throw new MOADatabaseException(e); } return session; } public static String createInterfederatedSession(IRequest req, boolean isAuthenticated) throws MOADatabaseException, AssertionAttributeExtractorExeption { String id = Random.nextRandom(); AuthenticationSession session = new AuthenticationSession(id); AuthenticatedSessionStore dbsession = new AuthenticatedSessionStore(); dbsession.setSessionid(id); dbsession.setAuthenticated(isAuthenticated); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 Date now = new Date(); dbsession.setCreated(now); dbsession.setUpdated(now); dbsession.setSession(SerializationUtils.serialize(session)); //add interfederation information List idpList = dbsession.getInderfederation(); if (idpList == null) idpList = new ArrayList(); InterfederationSessionStore idp = new InterfederationSessionStore(); idp.setCreated(now); idp.setIdpurlprefix(req.getInterfederationResponse().getEntityID()); AssertionAttributeExtractor extract = new AssertionAttributeExtractor(req.getInterfederationResponse().getResponse()); idp.setSessionIndex(extract.getSessionIndex()); idp.setUserNameID(extract.getNameID()); idp.setAttributesRequested(false); idp.setQAALevel(extract.getQAALevel()); idpList.add(idp); //store AssertionStore element to Database try { MOASessionDBUtils.saveOrUpdate(dbsession); Logger.info("MOASession with sessionID=" + id + " is stored in Database"); } catch (MOADatabaseException e) { Logger.warn("MOASession could not be created."); throw new MOADatabaseException(e); } return id; } public static void setInterfederationAttributCollectorUsed(AuthenticationSession session, String idpID) throws MOADatabaseException { AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); List idpList = dbsession.getInderfederation(); for (InterfederationSessionStore idp : idpList) { if (idp.getIdpurlprefix().endsWith(idpID)) idp.setAttributesRequested(true); } //store AssertionStore element to Database try { MOASessionDBUtils.saveOrUpdate(dbsession); Logger.info("MOASession with sessionID=" + session.getSessionID() + " is stored in Database"); } catch (MOADatabaseException e) { Logger.warn("MOASession could not stored.",e); throw e; } } public static void storeSession(AuthenticationSession session) throws MOADatabaseException, BuildException { try { AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); dbsession.setAuthenticated(session.isAuthenticated()); byte[] serialized = SerializationUtils.serialize(session); EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized); dbsession.setSession(encdata.getEncData()); dbsession.setIv(encdata.getIv()); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 dbsession.setUpdated(new Date()); MOASessionDBUtils.saveOrUpdate(dbsession); Logger.debug("MOASession with sessionID=" + session.getSessionID() + " is stored in Database"); } catch (MOADatabaseException e) { Logger.warn("MOASession could not be stored."); throw new MOADatabaseException(e); } } public static void storeSession(AuthenticationSession session, String pendingRequestID) throws MOADatabaseException, BuildException { try { AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); dbsession.setPendingRequestID(pendingRequestID); dbsession.setAuthenticated(session.isAuthenticated()); byte[] serialized = SerializationUtils.serialize(session); EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized); dbsession.setSession(encdata.getEncData()); dbsession.setIv(encdata.getIv()); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 dbsession.setUpdated(new Date()); MOASessionDBUtils.saveOrUpdate(dbsession); Logger.debug("MOASession with sessionID=" + session.getSessionID() + " is stored in Database"); } catch (MOADatabaseException e) { Logger.warn("MOASession could not be stored."); throw new MOADatabaseException(e); } } public static void destroySession(String moaSessionID) throws MOADatabaseException { Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); query.setString("sessionid", moaSessionID); result = query.list(); Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); throw new MOADatabaseException("No session found with this sessionID"); } AuthenticatedSessionStore dbsession = (AuthenticatedSessionStore) result.get(0); session.getTransaction().commit(); cleanDelete(dbsession); } } public static String changeSessionID(AuthenticationSession session) throws AuthenticationException, BuildException { try { AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); String id = Random.nextRandom(); Logger.debug("Change SessionID from " + session.getSessionID() + "to " + id); session.setSessionID(id); dbsession.setSessionid(id); dbsession.setAuthenticated(session.isAuthenticated()); byte[] serialized = SerializationUtils.serialize(session); EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized); dbsession.setSession(encdata.getEncData()); dbsession.setIv(encdata.getIv()); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 dbsession.setUpdated(new Date()); MOASessionDBUtils.saveOrUpdate(dbsession); Logger.trace("Change SessionID complete."); return id; } catch (MOADatabaseException e) { throw new AuthenticationException("TODO!", null); } } public static void addSSOInformation(String moaSessionID, String SSOSessionID, SLOInformationInterface SLOInfo, String OAUrl) throws AuthenticationException { AuthenticatedSessionStore dbsession; Transaction tx = null; try { Session session = MOASessionDBUtils.getCurrentSession(); List result; Logger.trace("Add SSO information to session " + moaSessionID); synchronized (session) { tx = session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); query.setString("sessionid", moaSessionID); result = query.list(); Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); tx.rollback(); throw new MOADatabaseException("No session found with this sessionID"); } dbsession = (AuthenticatedSessionStore) result.get(0); OASessionStore activeOA = null; //check if OA already has an active OA session if (dbsession.getActiveOAsessions() != null) { for (OASessionStore el : dbsession.getActiveOAsessions()) { if (el.getOaurlprefix().equals(OAUrl)) activeOA = el; } } if (activeOA == null) activeOA = new OASessionStore(); //set active OA applications activeOA.setOaurlprefix(OAUrl); activeOA.setMoasession(dbsession); activeOA.setCreated(new Date()); //set additional information for SLO if (SLOInfo != null) { activeOA.setAssertionSessionID(SLOInfo.getSessionIndex()); activeOA.setUserNameID(SLOInfo.getUserNameIdentifier()); activeOA.setProtocolType(SLOInfo.getProtocolType()); } List activeOAs = dbsession.getActiveOAsessions(); activeOAs.add(activeOA); dbsession.setActiveOAsessions(activeOAs); //Store used SSOId if (dbsession.getSSOsessionid() != null) { OldSSOSessionIDStore oldSSOId = new OldSSOSessionIDStore(); oldSSOId.setOldsessionid(dbsession.getSSOsessionid()); oldSSOId.setMoasession(dbsession); List oldSSOIds = dbsession.getOldssosessionids(); oldSSOIds.add(oldSSOId); } dbsession.setSSOSession(true); dbsession.setSSOsessionid(SSOSessionID); dbsession.setAuthenticated(false); dbsession.setPendingRequestID(""); //Store MOASession session.saveOrUpdate(dbsession); //send transaction tx.commit(); Logger.debug("Add SSO-Session login information for OA: " + OAUrl + " and AssertionID: " + SLOInfo.getSessionIndex()); } } catch (MOADatabaseException e) { throw new AuthenticationException("No MOASession found with Id="+moaSessionID, null); } catch(HibernateException e) { Logger.warn("Error during database saveOrUpdate. Rollback.", e); tx.rollback(); throw new AuthenticationException("SSO Session information can not be stored! --> SSO is deactivated", null); } } public static AuthenticationSession getSession(String sessionID) throws MOADatabaseException { try { AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); //decrypt Session EncryptedData encdata = new EncryptedData(dbsession.getSession(), dbsession.getIv()); byte[] decrypted = SessionEncrytionUtil.decrypt(encdata); AuthenticationSession session = (AuthenticationSession) SerializationUtils.deserialize(decrypted); return session; } catch (MOADatabaseException e) { Logger.info("No MOA Session with id: " + sessionID); throw new MOADatabaseException("No MOA Session with id: " + sessionID); } catch (Throwable e) { Logger.warn("MOASession deserialization-exception by using MOASessionID=" + sessionID, e); throw new MOADatabaseException("MOASession deserialization-exception"); } } public static boolean isSSOSession(String sessionID) throws MOADatabaseException { try { AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); return dbsession.isSSOSession(); } catch (MOADatabaseException e) { Logger.info("No MOA Session with id: " + sessionID); throw new MOADatabaseException("No MOA Session with id: " + sessionID); } } public static String getMOASessionID(String SSOSessionID) { MiscUtil.assertNotNull(SSOSessionID, "moasessionID"); Logger.trace("Get authenticated session with SSOID " + SSOSessionID + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithSSOID"); query.setString("sessionid", SSOSessionID); result = query.list(); //send transaction session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); return null; } else { return result.get(0).getSessionid(); } } public static boolean isValidSessionWithSSOID(String SSOId, String moaSessionId) { MiscUtil.assertNotNull(SSOId, "SSOSessionID"); Logger.trace("Get authenticated session with SSOID " + SSOId + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithSSOID"); query.setString("sessionid", SSOId); result = query.list(); //send transaction session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); return false; } else { return true; } } public static boolean deleteSessionWithPendingRequestID(String id) { MiscUtil.assertNotNull(id, "PendingRequestID"); Logger.trace("Delete MOAsession with PendingRequestID " + id + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithPendingRequestID"); query.setString("sessionid", id); result = query.list(); //send transaction session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); return false; } else { cleanDelete(result.get(0)); return true; } } public static String getPendingRequestID(String sessionID) { try { AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); return dbsession.getPendingRequestID(); } catch (MOADatabaseException e) { Logger.warn("MOASession with ID " + sessionID + " not found"); return ""; } } public static AuthenticationSession getSessionWithPendingRequestID(String pedingRequestID) { try { MiscUtil.assertNotNull(pedingRequestID, "pedingRequestID"); Logger.trace("Get authenticated session with pedingRequestID " + pedingRequestID + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithPendingRequestID"); query.setString("sessionid", pedingRequestID); result = query.list(); //send transaction session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); return null; } //decrypt Session EncryptedData encdata = new EncryptedData(result.get(0).getSession(), result.get(0).getIv()); byte[] decrypted = SessionEncrytionUtil.decrypt(encdata); return (AuthenticationSession) SerializationUtils.deserialize(decrypted); } catch (Throwable e) { Logger.warn("MOASession deserialization-exception by using MOASessionID=" + pedingRequestID); return null; } } public static void clean(long now, long authDataTimeOutCreated, long authDataTimeOutUpdated) { Date expioredatecreate = new Date(now - authDataTimeOutCreated); Date expioredateupdate = new Date(now - authDataTimeOutUpdated); List results; Session session = MOASessionDBUtils.getCurrentSession(); synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getMOAISessionsWithTimeOut"); query.setTimestamp("timeoutcreate", expioredatecreate); query.setTimestamp("timeoutupdate", expioredateupdate); results = query.list(); session.getTransaction().commit(); } if (results.size() != 0) { for(AuthenticatedSessionStore result : results) { try { cleanDelete(result); Logger.info("Authenticated session with sessionID=" + result.getSessionid() + " after session timeout."); } catch (HibernateException e){ Logger.warn("Authenticated session with sessionID=" + result.getSessionid() + " not removed after timeout! (Error during Database communication)", e); } } } } private static void cleanDelete(AuthenticatedSessionStore result) { try { result.setSession(new byte[] {}); MOASessionDBUtils.saveOrUpdate(result); } catch (MOADatabaseException e) { Logger.warn("Blank authenticated session with sessionID=" + result.getSessionid() + " FAILED.", e); } finally { if (!MOASessionDBUtils.delete(result)) Logger.error("Authenticated session with sessionID=" + result.getSessionid() + " not removed! (Error during Database communication)"); } } @SuppressWarnings("rawtypes") private static AuthenticatedSessionStore searchInDatabase(String sessionID) throws MOADatabaseException { MiscUtil.assertNotNull(sessionID, "moasessionID"); Logger.trace("Get authenticated session with sessionID " + sessionID + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List result; synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); query.setString("sessionid", sessionID); result = query.list(); //send transaction session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); throw new MOADatabaseException("No session found with this sessionID"); } return (AuthenticatedSessionStore) result.get(0); } }