aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java
diff options
context:
space:
mode:
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.java369
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);
+
}
-
+
}