From 8da90c1f897736d2d2237efedd2b6a3ac362af2d Mon Sep 17 00:00:00 2001 From: Christian Maierhofer Date: Wed, 27 Apr 2016 16:11:49 +0200 Subject: Modified SingleLogOutAction to work with REDIS --- .../moa/id/protocols/pvp2x/SingleLogOutAction.java | 274 +++++++++++---------- .../moa/id/storage/DBTransactionStorage.java | 13 +- .../moa/id/storage/ITransactionStorage.java | 17 ++ .../moa/id/storage/RedisTransactionStorage.java | 22 ++ 4 files changed, 192 insertions(+), 134 deletions(-) (limited to 'id/server/idserverlib/src/main/java') diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java index d7adab4e6..57540138e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java @@ -83,8 +83,8 @@ public class SingleLogOutAction implements IAction { @Autowired private ITransactionStorage transactionStorage; @Autowired private SingleLogOutBuilder sloBuilder; @Autowired private MOAReversionLogger revisionsLogger; - - + + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @@ -94,139 +94,145 @@ public class SingleLogOutAction implements IAction { IAuthData authData) throws MOAIDException { PVPTargetConfiguration pvpReq = (PVPTargetConfiguration) req; - + if (pvpReq.getRequest() instanceof MOARequest && ((MOARequest)pvpReq.getRequest()).getSamlRequest() instanceof LogoutRequest) { Logger.debug("Process Single LogOut request"); MOARequest samlReq = (MOARequest) pvpReq.getRequest(); LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest(); - + AuthenticationSession session = authenticationSessionStorage.searchMOASessionWithNameIDandOAID( logOutReq.getIssuer().getValue(), logOutReq.getNameID().getValue()); - - if (session == null) { - Logger.warn("Can not find active SSO session with nameID " - + logOutReq.getNameID().getValue() + " and OA " - + logOutReq.getIssuer().getValue()); - Logger.info("Search active SSO session with SSO session cookie"); - String ssoID = ssomanager.getSSOSessionID(httpReq); - if (MiscUtil.isEmpty(ssoID)) { + + if (session == null) { + Logger.warn("Can not find active SSO session with nameID " + + logOutReq.getNameID().getValue() + " and OA " + + logOutReq.getIssuer().getValue()); + Logger.info("Search active SSO session with SSO session cookie"); + String ssoID = ssomanager.getSSOSessionID(httpReq); + if (MiscUtil.isEmpty(ssoID)) { + Logger.info("Can not find active Session. Single LogOut not possible!"); + SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); + //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); + LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); + Logger.info("Sending SLO success message to requester ..."); + sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); + return null; + + } else { + String moasession = ssomanager.getMOASession(ssoID); + try { + session = authenticationSessionStorage.getSession(moasession); + + } catch (MOADatabaseException e) { Logger.info("Can not find active Session. Single LogOut not possible!"); SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); Logger.info("Sending SLO success message to requester ..."); - sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); + sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); return null; - - } else { - String moasession = ssomanager.getMOASession(ssoID); - try { - session = authenticationSessionStorage.getSession(moasession); - - } catch (MOADatabaseException e) { - Logger.info("Can not find active Session. Single LogOut not possible!"); - SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); - //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); - LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); - Logger.info("Sending SLO success message to requester ..."); - sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); - return null; - - } - } + + } + } + } + + authManager.performSingleLogOut(httpReq, httpResp, session, pvpReq); + + } else if (pvpReq.getRequest() instanceof MOAResponse && + ((MOAResponse)pvpReq.getRequest()).getResponse() instanceof LogoutResponse) { + Logger.debug("Process Single LogOut response"); + LogoutResponse logOutResp = (LogoutResponse) ((MOAResponse)pvpReq.getRequest()).getResponse(); + + //Transaction tx = null; + + try { + String relayState = pvpReq.getRequest().getRelayState(); + if (MiscUtil.isEmpty(relayState)) { + Logger.warn("SLO Response from " + logOutResp.getIssuer().getValue() + + " has no SAML2 RelayState."); + throw new SLOException("pvp2.19", null); + } - - authManager.performSingleLogOut(httpReq, httpResp, session, pvpReq); - - } else if (pvpReq.getRequest() instanceof MOAResponse && - ((MOAResponse)pvpReq.getRequest()).getResponse() instanceof LogoutResponse) { - Logger.debug("Process Single LogOut response"); - LogoutResponse logOutResp = (LogoutResponse) ((MOAResponse)pvpReq.getRequest()).getResponse(); - - Transaction tx = null; - - try { - String relayState = pvpReq.getRequest().getRelayState(); - if (MiscUtil.isEmpty(relayState)) { - Logger.warn("SLO Response from " + logOutResp.getIssuer().getValue() - + " has no SAML2 RelayState."); - throw new SLOException("pvp2.19", null); - - } - - Session session = MOASessionDBUtils.getCurrentSession(); - boolean storageSuccess = false; - int counter = 0; - - //TODO: add counter to prevent deadlock - + + //Session session = MOASessionDBUtils.getCurrentSession(); + boolean storageSuccess = false; + int counter = 0; + + //TODO: add counter to prevent deadlock + synchronized(this){ while (!storageSuccess) { - tx = session.beginTransaction(); - - List result; - Query query = session.getNamedQuery("getAssertionWithArtifact"); - query.setParameter("artifact", relayState); - result = query.list(); - Logger.trace("Found entries: " + result.size()); - - //Assertion requires an unique artifact - if (result.size() != 1) { + // tx = session.beginTransaction(); + // + // List result; + // Query query = session.getNamedQuery("getAssertionWithArtifact"); + // query.setParameter("artifact", relayState); + // 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 sessioninformation found with this ID"); + // } + // + // AssertionStore element = (AssertionStore) result.get(0); + // Object data = SerializationUtils.deserialize(element.getAssertion()); + Logger.debug("Current Thread getAssertionStore: "+Thread.currentThread().getId()); + Object o = transactionStorage.getAssertionStore(relayState); + if(o==null){ Logger.trace("No entries found."); - throw new MOADatabaseException("No sessioninformation found with this ID"); + throw new MOADatabaseException("No sessioninformation found with this ID"); } - - AssertionStore element = (AssertionStore) result.get(0); - Object data = SerializationUtils.deserialize(element.getAssertion()); - + AssertionStore element = (AssertionStore) o; + Object data = SerializationUtils.deserialize(element.getAssertion()); + if (data instanceof SLOInformationContainer) { ISLOInformationContainer sloContainer = (ISLOInformationContainer) data; - + //check status sloBuilder.checkStatusCode(sloContainer, logOutResp); - + if (sloContainer.hasFrontChannelOA()) { try { //some response are open byte[] serializedSLOContainer = SerializationUtils.serialize((Serializable) sloContainer); element.setAssertion(serializedSLOContainer); element.setType(sloContainer.getClass().getName()); - - session.saveOrUpdate(element); - tx.commit(); - + + // session.saveOrUpdate(element); + // tx.commit(); + Logger.debug("Current Thread putAssertionStore: "+Thread.currentThread().getId()); + transactionStorage.putAssertionStore(element); + //sloContainer could be stored to database storageSuccess = true; - - } catch(HibernateException e) { - tx.rollback(); + + } catch(MOADatabaseException e) { + //tx.rollback(); counter++; Logger.debug("SLOContainter could not stored to database. Wait some time and restart storage process ... "); java.util.Random rand = new java.util.Random(); - + try { Thread.sleep(rand.nextInt(20)*10); - + } catch (InterruptedException e1) { Logger.warn("Thread could not stopped. ReStart storage process immediately", e1); } } - + } else { - //last response received. - try { - session.delete(element); - tx.commit(); - - } catch(HibernateException e) { - tx.rollback(); - Logger.error("SLOContainter could not deleted from database. "); - - } - + Logger.debug("Current Thread removeElement by Artifact: "+Thread.currentThread().getId()); + transactionStorage.remove(element.getArtifact()); + // session.delete(element); + // tx.commit(); + storageSuccess = true; String redirectURL = null; if (sloContainer.getSloRequest() != null) { @@ -234,70 +240,72 @@ public class SingleLogOutAction implements IAction { SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(sloContainer.getSloRequest()); LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, sloContainer.getSloRequest(), sloContainer.getSloFailedOAs()); redirectURL = sloBuilder.getFrontChannelSLOMessageURL(sloService, message, httpReq, httpResp, sloContainer.getSloRequest().getRequest().getRelayState()); - + } else { //print SLO information directly redirectURL = req.getAuthURL() + "/idpSingleLogout"; - + String artifact = Random.nextRandom(); - - String statusCode = null; + + String statusCode = null; if (sloContainer.getSloFailedOAs() == null || - sloContainer.getSloFailedOAs().size() == 0) { - statusCode = MOAIDAuthConstants.SLOSTATUS_SUCCESS; - revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), - MOAIDEventConstants.AUTHPROCESS_SLO_ALL_VALID); - + sloContainer.getSloFailedOAs().size() == 0) { + statusCode = MOAIDAuthConstants.SLOSTATUS_SUCCESS; + revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), + MOAIDEventConstants.AUTHPROCESS_SLO_ALL_VALID); + } else { revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), MOAIDEventConstants.AUTHPROCESS_SLO_NOT_ALL_VALID); - statusCode = MOAIDAuthConstants.SLOSTATUS_ERROR; - + statusCode = MOAIDAuthConstants.SLOSTATUS_ERROR; + } transactionStorage.put(artifact, statusCode, -1); - redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SLOSTATUS, artifact); - + redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SLOSTATUS, artifact); + } //redirect to Redirect Servlet String url = req.getAuthURL() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(redirectURL, "UTF-8")); url = httpResp.encodeRedirectURL(url); - + httpResp.setContentType("text/html"); httpResp.setStatus(302); httpResp.addHeader("Location", url); - + } } else { Logger.warn("Sessioninformation Cast-Exception by using Artifact=" + relayState); throw new MOADatabaseException("Sessioninformation Cast-Exception"); - + } } - - } catch (MOADatabaseException e) { - Logger.error("MOA AssertionDatabase ERROR", e); - throw new SLOException("pvp2.19", null); - - } catch (UnsupportedEncodingException e) { - Logger.error("Finale SLO redirct not possible.", e); - throw new AuthenticationException("pvp2.13", new Object[]{}); - - } finally { - if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) { - tx.commit(); - - } } - - - - } else { - Logger.error("Process SingleLogOutAction but request is NOT of type LogoutRequest or LogoutResponse."); - throw new MOAIDException("pvp2.13", null); - - } - + } catch (MOADatabaseException e) { + Logger.error("MOA AssertionDatabase ERROR", e); + throw new SLOException("pvp2.19", null); + + } catch (UnsupportedEncodingException e) { + Logger.error("Finale SLO redirct not possible.", e); + throw new AuthenticationException("pvp2.13", new Object[]{}); + + } + + // finally { + // if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) { + // tx.commit(); + // + // } + // } + + + + } else { + Logger.error("Process SingleLogOutAction but request is NOT of type LogoutRequest or LogoutResponse."); + throw new MOAIDException("pvp2.13", null); + + } + return null; } @@ -317,7 +325,7 @@ public class SingleLogOutAction implements IAction { public String getDefaultActionName() { return PVP2XProtocol.SINGLELOGOUT; } - + protected static String addURLParameter(String url, String paramname, String paramvalue) { String param = paramname + "=" + paramvalue; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java index 89df47615..fa8ca8547 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java @@ -104,7 +104,11 @@ public class DBTransactionStorage implements ITransactionStorage { Logger.error("This exeption should not occur!!!!", e); return null; - } + } + } + + public Object getAssertionStore(String key) throws MOADatabaseException{ + return searchInDatabase(key); } public Object get(String key) throws MOADatabaseException { @@ -260,4 +264,11 @@ public class DBTransactionStorage implements ITransactionStorage { } + @Override + public void putAssertionStore(Object element) throws MOADatabaseException{ + // TODO Auto-generated method stub + entityManager.merge(element); + + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java index 4651566fc..53a7f4f5e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java @@ -111,4 +111,21 @@ public interface ITransactionStorage { */ public List clean(Date now, long dataTimeOut); + + /** + * Get whole AssertionStoreObject, required for SLO + * + * @param key key Id which identifiers the data object + * @return The transaction-data object, or null + * @throws MOADatabaseException In case of load operation failed + */ + public Object getAssertionStore(String key) throws MOADatabaseException; + + /** + * Put whole AssertionStoreObject to db, required for SLO + * + * @param element assertion store object + */ + public void putAssertionStore(Object element) throws MOADatabaseException; + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java index cae73fafd..c17bff358 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java @@ -352,4 +352,26 @@ private AssertionStore prepareAssertion(AssertionStore element, String key, Obje } +@Override +public Object getAssertionStore(String key) throws MOADatabaseException { + return searchInDatabase(key); +} + +@Override +public void putAssertionStore(Object element) throws MOADatabaseException { + // TODO Auto-generated method stub + AssertionStore as = (AssertionStore)element; + final int expTime = redisTemplate.getExpire(as.getArtifact(), TimeUnit.MILLISECONDS).intValue(); + //AssertionStore element = searchInDatabase(oldKey); + if (expTime < 0) { + Logger.info("No transaction-data with oldKey:" + as.getArtifact() + + " found. Process gets stopped."); + throw new MOADatabaseException("No transaction-data with oldKey:" + as.getArtifact() + + " found. Process gets stopped."); + + } + redisTemplate.opsForValue().set(as.getArtifact(), new String(assertionStoreSerializer.serialize(element)),expTime,TimeUnit.MILLISECONDS); + +} + } -- cgit v1.2.3