diff options
4 files changed, 192 insertions, 134 deletions
| 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<String> 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); +	 +} +  } | 
