diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java | 369 |
1 files changed, 302 insertions, 67 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java index 557d9af48..b5005d0c9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java @@ -23,32 +23,49 @@ package at.gv.egovernment.moa.id.moduls; import java.util.Date; +import java.util.Map; +import java.util.Map.Entry; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager; +import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; +import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; +import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException; +import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException; +import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionExtensions; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; -import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.SessionDataStorageException; 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.OldSSOSessionIDStore; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameterDecorator; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; -import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.id.util.legacy.LegacyHelper; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @Service("MOAID_SSOManager") -public class SSOManager { +public class SSOManager implements ISSOManager { + private static final String HTMLTEMPLATESDIR = "htmlTemplates/"; private static final String HTMLTEMPLATEFULL = "slo_template.html"; public static String CONTEXTPATH = "contextPath"; @@ -58,10 +75,228 @@ public class SSOManager { private static final int INTERFEDERATIONCOOKIEMAXAGE = 5 * 60;// sec + public static final String DATAID_INTERFEDERATIOIDP_URL = "interIDPURL"; + public static final String DATAID_INTERFEDERATIOIDP_RESPONSE = "interIDPResponse"; + public static final String DATAID_INTERFEDERATIOIDP_ENTITYID = "interIDPEntityID"; + + @Autowired private IAuthenticationSessionStoreage authenticatedSessionStore; - @Autowired protected AuthConfiguration authConfig; + @Autowired private AuthConfiguration authConfig; + @Autowired private IRevisionLogger revisionsLogger; + + + + //@Autowired private MOASessionDBUtils moaSessionDBUtils; + @Override + public boolean checkAndValidateSSOSession(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp) throws EAAFSSOException { + try { + //get SSO cookie from http request + String ssoId = getSSOSessionID(httpReq); + + //check if interfederation IDP is requested + checkInterfederationIsRequested(httpReq, httpResp, pendingReq); + + //check if SSO session cookie is already used + if (ssoId != null) { + String correspondingMOASession = existsOldSSOSession(ssoId); + + if (correspondingMOASession != null) { + Logger.warn("Request sends an old SSO Session ID("+ssoId+")! " + + "Invalidate the corresponding MOASession with ID="+ correspondingMOASession); + + revisionsLogger.logEvent(pendingReq, EVENT_SSO_SESSION_INVALID); + + //destroy internal SSO-session object and SSO-session cooky + authenticatedSessionStore.destroyInternalSSOSession(correspondingMOASession); + deleteSSOSessionID(httpReq, httpResp); + } + } + + //check if SSO Session is valid + boolean isSSOValid = isValidSSOSession(ssoId, pendingReq); + + return isSSOValid; + + + } catch (SessionDataStorageException | ConfigurationException | EAAFStorageException e) { + Logger.warn("Cann not process SSO session. Reason: " + e.getMessage(), e); + Logger.info("All SSO session will be ignored."); + + } + + return false; + + } + + + @Override + public void isSSOAllowedForSP(IRequest pendingReq, HttpServletRequest httpReq) { + // check if Service-Provider allows SSO sessions + IOAAuthParameters oaConfig = pendingReq.getServiceProviderConfiguration(OAAuthParameterDecorator.class); + boolean useSSOOA = oaConfig.useSSO() || oaConfig.isInderfederationIDP(); + + //if a legacy request is used SSO should not be allowed in case of mandate authentication + boolean isUseMandateRequested = false; + try { + isUseMandateRequested = LegacyHelper.isUseMandateRequested(httpReq); + + //check if SSO is allowed for the actually executed request + //INFO: Actually, useMandate disables SSO functionality!!!!! + pendingReq.setNeedSingleSignOnFunctionality((useSSOOA && !isUseMandateRequested)); + + //check if current service provider needs user consent for SSO + pendingReq.setNeedUserConsent(oaConfig.useSSOQuestion()); + + } catch (WrongParametersException e) { + Logger.warn("Find suspect http parameter for mandates! Reason: " + e.getMessage()); + + } + + } + + @Override + public void populatePendingRequestWithSSOInformation(IRequest pendingReq) throws EAAFSSOException { + //populate pending request with eID data from SSO session if no userConsent is required + try { + AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(pendingReq.getInternalSSOSessionIdentifier()); + + if (ssoMOASession == null) + Logger.info("No MOASession FOUND with provided SSO-Cookie."); + + else { + Logger.debug("Found authenticated MOASession with provided SSO-Cookie."); + revisionsLogger.logEvent(pendingReq, EVENT_SSO_SESSION_VALID); + + Logger.trace("Populatint pending request with SSO session information .... "); + Map<String, Object> fullSSOData = ssoMOASession.getKeyValueRepresentationFromAuthSession(); + if (Logger.isTraceEnabled()) { + Logger.trace("Full SSO DataSet: "); + for (Entry<String, Object> el : fullSSOData.entrySet()) { + Logger.trace(" Key: " + el.getKey() + " Value: " + el.getValue()); + + } + + } + pendingReq.setRawDataToTransaction(fullSSOData); + pendingReq.setAuthenticated(true); + + } + + } catch (EAAFStorageException e) { + Logger.warn("Can NOT populate pending request from SSO session.", e); + throw new EAAFSSOException("", new Object[] {}, e); + + } + + } + + + @Override + public boolean destroySSOSessionOnIDPOnly(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) throws EAAFSSOException { + //get SSO token from request + String internalSSOSessionId = null; + try { + if (pendingReq != null && MiscUtil.isNotEmpty(pendingReq.getInternalSSOSessionIdentifier())) { + internalSSOSessionId = pendingReq.getInternalSSOSessionIdentifier(); + + } else { + String ssoid = getSSOSessionID(httpReq); + if (isValidSSOSession(ssoid, null)) { + internalSSOSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoid); + + } + } + + //destroy SSO session if it was found + if (StringUtils.isNotEmpty(internalSSOSessionId)) { + //delete SSO session and MOA session + AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(internalSSOSessionId); + + if (ssoMOASession == null) { + Logger.info("No internal MOA SSO-Session found. Nothing to destroy"); + return false; + + } + + + ssoMOASession.setAuthenticated(false); + + //log Session_Destroy to reversionslog + AuthenticationSessionExtensions sessionExtensions = + authenticatedSessionStore.getAuthenticationSessionExtensions(ssoMOASession.getSSOSessionID()); + revisionsLogger.logEvent(MOAIDEventConstants.SESSION_DESTROYED, sessionExtensions.getUniqueSessionId()); + authenticatedSessionStore.destroyInternalSSOSession(ssoMOASession.getSSOSessionID()); + } + + } catch (ConfigurationException | SessionDataStorageException | EAAFStorageException e) { + Logger.info("NO MOA Authentication data for ID " + internalSSOSessionId); + return false; + + } + + + //Remove SSO token + deleteSSOSessionID(httpReq, httpResp); + + return true; + + } + + @Override + public String createNewSSOSessionCookie(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) + throws EAAFSSOException { + Logger.debug("Creating new SSO session-cookie for http response ... "); + + //Store SSO information into database + String newSSOSessionId = Random.nextHexRandom32(); + + //set SSO cookie to response + if (StringUtils.isNotEmpty(newSSOSessionId)) + setSSOSessionID(httpReq, httpResp, newSSOSessionId); + else + deleteSSOSessionID(httpReq, httpResp); + + return newSSOSessionId; + } + + +@Override +public void createNewSSOSession(IRequest pendingReq, String newSSOSessionId) throws EAAFSSOException { + AuthenticationSession internalDBSSOSession; + try { + internalDBSSOSession = authenticatedSessionStore.createInternalSSOSession(pendingReq); + pendingReq.setInternalSSOSessionIdentifier(internalDBSSOSession.getSSOSessionID()); + + } catch (MOADatabaseException | BuildException e) { + Logger.warn("Can NOT create SSO session.", e); + throw new EAAFSSOException("builder.10", null, e); + + } + +} + + +@Override +public void updateSSOSession(IRequest pendingReq, String newSSOSessionId, SLOInformationInterface sloInformation) throws EAAFSSOException { + try { + authenticatedSessionStore.addSSOInformation( + pendingReq.getInternalSSOSessionIdentifier(), + newSSOSessionId, + sloInformation, + pendingReq); + + } catch (AuthenticationException e) { + Logger.warn("Can NOT update SSO session.", e); + throw new EAAFSSOException("builder.10", null, e); + } + +} + + + //*********************************** old ************************************** + /** * Check if interfederation IDP is requested via HTTP GET parameter or if interfederation cookie exists. * Set the requested interfederation IDP as attribte of the {protocolRequest} @@ -70,14 +305,15 @@ public class SSOManager { * @param httpResp HttpServletResponse * @param protocolRequest Authentication request which is actually in process * @throws SessionDataStorageException + * @throws EAAFStorageException * **/ public void checkInterfederationIsRequested(HttpServletRequest httpReq, HttpServletResponse httpResp, - IRequest protocolRequest) throws SessionDataStorageException { + IRequest protocolRequest) throws SessionDataStorageException, EAAFStorageException { String interIDP = httpReq.getParameter(MOAIDAuthConstants.INTERFEDERATION_IDP); String interfederationIDP = - protocolRequest.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class); + protocolRequest.getRawData(DATAID_INTERFEDERATIOIDP_URL, String.class); if (MiscUtil.isNotEmpty(interfederationIDP)) { Logger.debug("Protocolspecific preprocessing already set interfederation IDP " + interfederationIDP); return; @@ -89,14 +325,14 @@ public class SSOManager { RequestImpl moaReq = (RequestImpl) protocolRequest; if (MiscUtil.isNotEmpty(interIDP)) { Logger.info("Receive SSO request for interfederation IDP " + interIDP); - moaReq.setGenericDataToSession(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, interIDP); + moaReq.setRawDataToTransaction(DATAID_INTERFEDERATIOIDP_URL, interIDP); } else { //check if IDP cookie is set String cookie = getValueFromCookie(httpReq, SSOINTERFEDERATION); if (MiscUtil.isNotEmpty(cookie)) { Logger.info("Receive SSO request for interfederated IDP from Cookie " + cookie); - moaReq.setGenericDataToSession(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, cookie); + moaReq.setRawDataToTransaction(DATAID_INTERFEDERATIOIDP_URL, cookie); deleteCookie(httpReq, httpResp, SSOINTERFEDERATION); } @@ -113,8 +349,7 @@ public class SSOManager { } - - public boolean isValidSSOSession(String ssoSessionID, IRequest protocolRequest) throws ConfigurationException, SessionDataStorageException { + public boolean isValidSSOSession(String ssoSessionID, IRequest protocolRequest) throws ConfigurationException, SessionDataStorageException, EAAFStorageException { // search SSO Session if (ssoSessionID == null) { @@ -144,7 +379,7 @@ public class SSOManager { //in case of federated SSO session, jump to federated IDP for authentication String interfederationIDP = - protocolRequest.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class); + protocolRequest.getRawData(DATAID_INTERFEDERATIOIDP_URL, String.class); if (MiscUtil.isEmpty(interfederationIDP)) { InterfederationSessionStore selectedIDP = authenticatedSessionStore.searchInterfederatedIDPFORSSOWithMOASession(storedSession.getSessionid()); @@ -152,8 +387,8 @@ public class SSOManager { if (selectedIDP != null) { //no local SSO session exist -> request interfederated IDP Logger.info("SSO Session refer to federated IDP: " + selectedIDP.getIdpurlprefix()); - protocolRequest.setGenericDataToSession( - RequestImpl.DATAID_INTERFEDERATIOIDP_URL, selectedIDP.getIdpurlprefix()); + protocolRequest.setRawDataToTransaction( + DATAID_INTERFEDERATIOIDP_URL, selectedIDP.getIdpurlprefix()); } else { Logger.warn("MOASession is marked as interfederated SSO session but no interfederated IDP is found. Switch to local authentication ..."); @@ -170,25 +405,32 @@ public class SSOManager { return false; } - + + //set internal SSO SessionID + if (protocolRequest != null) + protocolRequest.setInternalSSOSessionIdentifier(storedSession.getSessionid()); + return true; } } - public AuthenticationSession getInternalMOASession(String ssoSessionID) throws MOADatabaseException { - return authenticatedSessionStore.getInternalMOASessionWithSSOID(ssoSessionID); - - } +// public String getInternalSSOSession(String ssoSessionID) throws MOADatabaseException { +// return authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoSessionID); +// +// } //TODO: refactor for faster DB access public String getUniqueSessionIdentifier(String ssoSessionID) { try { if (MiscUtil.isNotEmpty(ssoSessionID)) { - AuthenticationSession moaSession = authenticatedSessionStore.getInternalMOASessionWithSSOID(ssoSessionID); - if (moaSession != null) { - AuthenticationSessionExtensions extSessionInformation = authenticatedSessionStore.getAuthenticationSessionExtensions(moaSession.getSessionID()); + String ssoSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoSessionID); + if (MiscUtil.isNotEmpty(ssoSessionId)) { + AuthenticationSessionExtensions extSessionInformation = authenticatedSessionStore.getAuthenticationSessionExtensions(ssoSessionId); + if (extSessionInformation != null) return extSessionInformation.getUniqueSessionId(); + else + Logger.warn("Extended SSO-Session Information ARE NULL. Something looks wrong!"); } } @@ -199,55 +441,13 @@ public class SSOManager { return null; } - - public String existsOldSSOSession(String ssoId) { - - Logger.trace("Check that the SSOID has already been used"); - - OldSSOSessionIDStore oldSSOSession = authenticatedSessionStore.checkSSOTokenAlreadyUsed(ssoId); - - if (oldSSOSession == null) { - Logger.debug("SSO session-cookie was not used in parst"); - return null; - } - - AuthenticatedSessionStore correspondingMoaSession = oldSSOSession.getMoasession(); - - if (correspondingMoaSession == null) { - Logger.info("Get request with old SSO SessionID but no corresponding SSO Session is found."); - return null; - } - - return correspondingMoaSession.getSessionid(); - - } - - public String createSSOSessionInformations(String moaSessionID, String OAUrl) { - - String newSSOId = Random.nextRandom(); - - if (MiscUtil.isEmpty(moaSessionID) || MiscUtil.isEmpty(OAUrl)) { - Logger.warn("MoaSessionID or OAUrl are empty -> SSO is not enabled!"); - return null; - } - - return newSSOId; - - } - - public void setSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp, String ssoId) { - setCookie(httpReq, httpResp, SSOCOOKIE, ssoId, -1); - - } - + public String getSSOSessionID(HttpServletRequest httpReq) { return getValueFromCookie(httpReq, SSOCOOKIE); } - public void deleteSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp) { - deleteCookie(httpReq, httpResp, SSOCOOKIE); - } + /** * @param entityID @@ -284,7 +484,41 @@ public class SSOManager { return false; } - + + + private String existsOldSSOSession(String ssoId) { + + Logger.trace("Check that the SSOID has already been used"); + + OldSSOSessionIDStore oldSSOSession = authenticatedSessionStore.checkSSOTokenAlreadyUsed(ssoId); + + if (oldSSOSession == null) { + Logger.debug("SSO session-cookie was not used in parst"); + return null; + } + + AuthenticatedSessionStore correspondingMoaSession = oldSSOSession.getMoasession(); + + if (correspondingMoaSession == null) { + Logger.info("Get request with old SSO SessionID but no corresponding SSO Session is found."); + return null; + } + + return correspondingMoaSession.getSessionid(); + + } + + + private void setSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp, String ssoId) { + setCookie(httpReq, httpResp, SSOCOOKIE, ssoId, -1); + + } + + private void deleteSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp) { + deleteCookie(httpReq, httpResp, SSOCOOKIE); + + } + private String getValueFromCookie(HttpServletRequest httpReq, String cookieName) { Cookie[] cookies = httpReq.getCookies(); @@ -312,6 +546,7 @@ public class SSOManager { private void deleteCookie(HttpServletRequest httpReq, HttpServletResponse httpResp, String cookieName) { setCookie(httpReq, httpResp, cookieName, "", 0); + } - + } |