From cc20e4171331f78a1bb188f2b885c9754da58a28 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 3 Jun 2014 17:09:42 +0200 Subject: update IDP single logout --- .../moa/id/data/SLOInformationContainer.java | 102 ++++++++++++++------- .../moa/id/protocols/pvp2x/MetadataAction.java | 58 ++++++------ .../moa/id/protocols/pvp2x/SingleLogOutAction.java | 12 ++- .../pvp2x/builder/SingleLogOutBuilder.java | 19 ++-- .../id/storage/AuthenticationSessionStoreage.java | 53 ++++++++--- 5 files changed, 161 insertions(+), 83 deletions(-) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationContainer.java index a0f3dd309..df195c0de 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationContainer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationContainer.java @@ -29,8 +29,10 @@ import java.util.LinkedHashMap; import java.util.List; import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.metadata.SingleLogoutService; +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.protocols.pvp2x.PVP2XProtocol; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; @@ -52,47 +54,87 @@ public class SLOInformationContainer implements Serializable { public void parseActiveOAs(List dbOAs, String removeOAID) { - activeFrontChannalOAs = new LinkedHashMap(); - activeBackChannelOAs = new LinkedHashMap(); + if (activeBackChannelOAs == null) + activeBackChannelOAs = new LinkedHashMap(); + if (activeFrontChannalOAs == null) + activeFrontChannalOAs = new LinkedHashMap(); if (dbOAs != null) { for (OASessionStore oa : dbOAs) { - //Actually only PVP 2.1 support Single LogOut - if (PVP2XProtocol.NAME.equals(oa.getProtocolType()) && - !oa.getOaurlprefix().equals(removeOAID)) { + if (!oa.getOaurlprefix().equals(removeOAID)) { + + //Actually only PVP 2.1 support Single LogOut + if (PVP2XProtocol.PATH.equals(oa.getProtocolType())) { + SingleLogoutService sloDesc; + try { + sloDesc = SingleLogOutBuilder.getRequestSLODescriptor(oa.getOaurlprefix()); + + if (sloDesc.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) + activeBackChannelOAs.put(oa.getOaurlprefix(), + new SLOInformationImpl( + oa.getAssertionSessionID(), + oa.getUserNameID(), + oa.getUserNameIDFormat(), + oa.getProtocolType(), + sloDesc)); + + else + activeFrontChannalOAs.put(oa.getOaurlprefix(), + new SLOInformationImpl( + oa.getAssertionSessionID(), + oa.getUserNameID(), + oa.getUserNameIDFormat(), + oa.getProtocolType(), + sloDesc)); + + } catch (NOSLOServiceDescriptorException e) { + putFailedOA(oa.getOaurlprefix()); + + } + + } else + putFailedOA(oa.getOaurlprefix()); + } + } + } + } + + /** + * @param dbIDPs + * @param value + */ + public void parseActiveIDPs(List dbIDPs, + String removeIDP) { + if (activeBackChannelOAs == null) + activeBackChannelOAs = new LinkedHashMap(); + if (activeFrontChannalOAs == null) + activeFrontChannalOAs = new LinkedHashMap(); + + if (dbIDPs != null) { + for (InterfederationSessionStore el : dbIDPs) { + if (!el.getIdpurlprefix().equals(removeIDP)) { + SingleLogoutService sloDesc; try { - sloDesc = SingleLogOutBuilder.getRequestSLODescriptor(oa.getOaurlprefix()); - - if (sloDesc.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) - activeBackChannelOAs.put(oa.getOaurlprefix(), - new SLOInformationImpl( - oa.getAssertionSessionID(), - oa.getUserNameID(), - oa.getUserNameIDFormat(), - oa.getProtocolType(), - sloDesc)); + sloDesc = SingleLogOutBuilder.getRequestSLODescriptor(el.getIdpurlprefix()); - else - activeFrontChannalOAs.put(oa.getOaurlprefix(), - new SLOInformationImpl( - oa.getAssertionSessionID(), - oa.getUserNameID(), - oa.getUserNameIDFormat(), - oa.getProtocolType(), + activeFrontChannalOAs.put(el.getIdpurlprefix(), + new SLOInformationImpl( + el.getSessionIndex(), + el.getUserNameID(), + NameID.TRANSIENT, + PVP2XProtocol.PATH, sloDesc)); } catch (NOSLOServiceDescriptorException e) { - putFailedOA(oa.getOaurlprefix()); + putFailedOA(el.getIdpurlprefix()); } - - } else - putFailedOA(oa.getOaurlprefix()); + } } } } - + public String getNextFrontChannelOA() { Iterator interator = activeFrontChannalOAs.keySet().iterator(); if (interator.hasNext()) @@ -147,9 +189,5 @@ public class SLOInformationContainer implements Serializable { if (sloFailedOAs == null) sloFailedOAs = new ArrayList(); sloFailedOAs.add(oaID); - } - - - - + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java index 01f7e18ba..c60e69df6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java @@ -258,21 +258,21 @@ public class MetadataAction implements IAction { //add SLO descriptor -// SingleLogoutService postSLOService = -// SAML2Utils.createSAMLObject(SingleLogoutService.class); -// postSLOService.setLocation(PVPConfiguration -// .getInstance().getIDPSSOPostService()); -// postSLOService -// .setBinding(SAMLConstants.SAML2_POST_BINDING_URI); -// spSSODescriptor.getSingleLogoutServices().add(postSLOService); -// -// SingleLogoutService redirectSLOService = -// SAML2Utils.createSAMLObject(SingleLogoutService.class); -// redirectSLOService.setLocation(PVPConfiguration -// .getInstance().getIDPSSOPostService()); -// redirectSLOService -// .setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); -// spSSODescriptor.getSingleLogoutServices().add(redirectSLOService); + SingleLogoutService postSLOService = + SAML2Utils.createSAMLObject(SingleLogoutService.class); + postSLOService.setLocation(PVPConfiguration + .getInstance().getIDPSSOPostService()); + postSLOService + .setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + spSSODescriptor.getSingleLogoutServices().add(postSLOService); + + SingleLogoutService redirectSLOService = + SAML2Utils.createSAMLObject(SingleLogoutService.class); + redirectSLOService.setLocation(PVPConfiguration + .getInstance().getIDPSSOPostService()); + redirectSLOService + .setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + spSSODescriptor.getSingleLogoutServices().add(redirectSLOService); spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); @@ -333,13 +333,13 @@ public class MetadataAction implements IAction { postSingleSignOnService); //add SLO descriptor -// SingleLogoutService postSLOService = -// SAML2Utils.createSAMLObject(SingleLogoutService.class); -// postSLOService.setLocation(PVPConfiguration -// .getInstance().getIDPSSOPostService()); -// postSLOService -// .setBinding(SAMLConstants.SAML2_POST_BINDING_URI); -// idpSSODescriptor.getSingleLogoutServices().add(postSLOService); + SingleLogoutService postSLOService = + SAML2Utils.createSAMLObject(SingleLogoutService.class); + postSLOService.setLocation(PVPConfiguration + .getInstance().getIDPSSOPostService()); + postSLOService + .setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + idpSSODescriptor.getSingleLogoutServices().add(postSLOService); } @@ -355,13 +355,13 @@ public class MetadataAction implements IAction { redirectSingleSignOnService); //add SLO descriptor -// SingleLogoutService redirectSLOService = -// SAML2Utils.createSAMLObject(SingleLogoutService.class); -// redirectSLOService.setLocation(PVPConfiguration -// .getInstance().getIDPSSOPostService()); -// redirectSLOService -// .setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); -// idpSSODescriptor.getSingleLogoutServices().add(redirectSLOService); + SingleLogoutService redirectSLOService = + SAML2Utils.createSAMLObject(SingleLogoutService.class); + redirectSLOService.setLocation(PVPConfiguration + .getInstance().getIDPSSORedirectService()); + redirectSLOService + .setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + idpSSODescriptor.getSingleLogoutServices().add(redirectSLOService); } /*if (PVPConfiguration.getInstance().getIDPResolveSOAPService() != null) { 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 c67d10ab7..92441e663 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 @@ -42,6 +42,7 @@ import org.opensaml.xml.security.SecurityException; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +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.ex.MOADatabaseException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; @@ -124,9 +125,11 @@ public class SingleLogOutAction implements IAction { } //store active OAs to SLOContaine - List dbOAs = AuthenticationSessionStoreage.getAllActiveOAFromMOASession(session); + List dbOAs = AuthenticationSessionStoreage.getAllActiveOAFromMOASession(session); + List dbIDPs = AuthenticationSessionStoreage.getAllActiveIDPsFromMOASession(session); SLOInformationContainer sloContainer = new SLOInformationContainer(); sloContainer.setSloRequest(pvpReq); + sloContainer.parseActiveIDPs(dbIDPs, logOutReq.getIssuer().getValue()); sloContainer.parseActiveOAs(dbOAs, logOutReq.getIssuer().getValue()); //terminate MOASession @@ -247,10 +250,13 @@ public class SingleLogOutAction implements IAction { private void checkStatusCode(SLOInformationContainer sloContainer, LogoutResponse logOutResp) { Status status = logOutResp.getStatus(); - if (!status.getStatusCode().equals(StatusCode.SUCCESS_URI)) { + if (!status.getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + String message = " Message: "; + if (status.getStatusMessage() != null) + message += status.getStatusMessage().getMessage(); Logger.warn("Single LogOut for OA " + logOutResp.getIssuer().getValue() + " FAILED. (ResponseCode: " + status.getStatusCode().getValue() - + " Message: " + status.getStatusMessage().getMessage() + ")"); + + message + ")"); sloContainer.putFailedOA(logOutResp.getIssuer().getValue()); } else diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java index 04d374e93..7aa860c5c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java @@ -35,6 +35,7 @@ import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusMessage; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.SSODescriptor; import org.opensaml.saml2.metadata.SingleLogoutService; import org.opensaml.saml2.metadata.provider.MetadataProviderException; @@ -125,7 +126,7 @@ public class SingleLogOutBuilder { public static SingleLogoutService getRequestSLODescriptor(String entityID) throws NOSLOServiceDescriptorException { try { EntityDescriptor entity = MOAMetadataProvider.getInstance().getEntityDescriptor(entityID); - SPSSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); + SSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); SingleLogoutService sloService = null; for (SingleLogoutService el : spsso.getSingleLogoutServices()) { @@ -173,14 +174,18 @@ public class SingleLogOutBuilder { if (el.getBinding().equals(spRequest.getBinding())) sloService = el; } - if (sloService == null && spsso.getSingleLogoutServices().size() != 0) - sloService = spsso.getSingleLogoutServices().get(0); - else { - Logger.error("Found no SLO ServiceDescriptor in Metadata"); - throw new NOSLOServiceDescriptorException("NO SLO ServiceDescriptor", null); + if (sloService == null) { + if (spsso.getSingleLogoutServices().size() != 0) + sloService = spsso.getSingleLogoutServices().get(0); + + else { + Logger.error("Found no SLO ServiceDescriptor in Metadata"); + throw new NOSLOServiceDescriptorException("NO SLO ServiceDescriptor", null); + } } - return sloService; + + return sloService; } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java index 6c2900752..5daca0888 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java @@ -64,7 +64,7 @@ public class AuthenticationSessionStoreage { AuthenticatedSessionStore session; try { - session = searchInDatabase(moaSessionID); + session = searchInDatabase(moaSessionID, true); return session.isAuthenticated(); } catch (MOADatabaseException e) { @@ -102,7 +102,7 @@ public class AuthenticationSessionStoreage { public static AuthenticationSession getSession(String sessionID) throws MOADatabaseException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); return decryptSession(dbsession); } catch (MOADatabaseException e) { @@ -122,7 +122,7 @@ public class AuthenticationSessionStoreage { public static void storeSession(AuthenticationSession session, String pendingRequestID) throws MOADatabaseException, BuildException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); + AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID(), true); if (MiscUtil.isNotEmpty(pendingRequestID)) dbsession.setPendingRequestID(pendingRequestID); @@ -175,7 +175,7 @@ public class AuthenticationSessionStoreage { throws AuthenticationException, BuildException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); + AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID(), true); String id = Random.nextRandom(); @@ -207,7 +207,7 @@ public class AuthenticationSessionStoreage { AuthenticatedSessionStore session; try { - session = searchInDatabase(moaSessionID); + session = searchInDatabase(moaSessionID, true); session.setAuthenticated(value); MOASessionDBUtils.saveOrUpdate(session); @@ -249,7 +249,7 @@ public class AuthenticationSessionStoreage { public static boolean isSSOSession(String sessionID) throws MOADatabaseException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); return dbsession.isSSOSession(); } catch (MOADatabaseException e) { @@ -391,8 +391,36 @@ public class AuthenticationSessionStoreage { MiscUtil.assertNotNull(moaSession, "MOASession"); try { - AuthenticatedSessionStore dbsession = searchInDatabase(moaSession.getSessionID()); - return dbsession.getActiveOAsessions(); + List oas = new ArrayList(); + + AuthenticatedSessionStore dbsession = searchInDatabase(moaSession.getSessionID(), false); + oas.addAll(dbsession.getActiveOAsessions()); + + Session session = MOASessionDBUtils.getCurrentSession(); + session.getTransaction().commit(); + + return oas; + + } catch (MOADatabaseException e) { + Logger.warn("NO session information found for sessionID " + moaSession.getSessionID(), e); + + } + + return null; + } + + public static List getAllActiveIDPsFromMOASession(AuthenticationSession moaSession) { + MiscUtil.assertNotNull(moaSession, "MOASession"); + + try { + List idps = new ArrayList(); + AuthenticatedSessionStore dbsession = searchInDatabase(moaSession.getSessionID(), false); + idps.addAll(dbsession.getInderfederation()); + + Session session = MOASessionDBUtils.getCurrentSession(); + session.getTransaction().commit(); + + return idps; } catch (MOADatabaseException e) { Logger.warn("NO session information found for sessionID " + moaSession.getSessionID(), e); @@ -475,7 +503,7 @@ public class AuthenticationSessionStoreage { public static String getPendingRequestID(String sessionID) { try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); return dbsession.getPendingRequestID(); } catch (MOADatabaseException e) { @@ -654,7 +682,7 @@ public class AuthenticationSessionStoreage { String moaSession = getMOASessionSSOID(ssoID); if (MiscUtil.isNotEmpty(moaSession)) { try { - dbsession = searchInDatabase(moaSession); + dbsession = searchInDatabase(moaSession, true); }catch (MOADatabaseException e) { @@ -889,7 +917,7 @@ public class AuthenticationSessionStoreage { } @SuppressWarnings("rawtypes") - private static AuthenticatedSessionStore searchInDatabase(String sessionID) throws MOADatabaseException { + private static AuthenticatedSessionStore searchInDatabase(String sessionID, boolean commit) throws MOADatabaseException { MiscUtil.assertNotNull(sessionID, "moasessionID"); Logger.trace("Get authenticated session with sessionID " + sessionID + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); @@ -903,7 +931,8 @@ public class AuthenticationSessionStoreage { result = query.list(); //send transaction - session.getTransaction().commit(); + if (commit) + session.getTransaction().commit(); } Logger.trace("Found entries: " + result.size()); -- cgit v1.2.3