summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2019-04-11 09:44:11 +0200
committerThomas Lenz <thomas.lenz@egiz.gv.at>2019-04-11 09:44:11 +0200
commit61d276832ebcf1901183dab323126f8ecb6a7370 (patch)
treeec9df86e1eb3cfb74f1fb68a371cb21d04e40d6b /eaaf_core/src/main/java
parent13952dddd85fc08115f963b259885b5c9b7f2b57 (diff)
downloadEAAF-Components-61d276832ebcf1901183dab323126f8ecb6a7370.tar.gz
EAAF-Components-61d276832ebcf1901183dab323126f8ecb6a7370.tar.bz2
EAAF-Components-61d276832ebcf1901183dab323126f8ecb6a7370.zip
refactor protocol finalization to support protocol response without final redirect
Diffstat (limited to 'eaaf_core/src/main/java')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java4
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java6
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java4
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java3
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/services/IProtocolAuthenticationService.java83
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java6
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java4
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java458
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java242
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java227
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java6
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java78
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java28
13 files changed, 630 insertions, 519 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
index b60d39e1..0a457825 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java
@@ -66,8 +66,12 @@ public class EAAFConstants {
public static final String PROCESS_ENGINE_SERVICE_PROVIDER_ENTITYID = PROCESS_ENGINE_PREFIX + "uniqueSPId";
public static final String PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE = PROCESS_ENGINE_PREFIX + "holderofkey_cert";
public static final String PROCESSCONTEXT_SP_CONFIG = PROCESS_ENGINE_PREFIX + "spConfig";
+ public static final String PROCESS_ENGINE_REQUIRES_NO_POSTAUTH_REDIRECT
+ = PROCESS_ENGINE_PREFIX + "requireNoPostAuthRedirect";
public static final int ALLOWED_TIME_JITTER = 5; //minutes
public static final String COUNTRYCODE_AUSTRIA = "AT";
+
+ public static final String TESTCREDENTIALROOTOID = "1.2.40.0.10.2.4.1";
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
index e8e41999..7dcd643d 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/IAuthData.java
@@ -119,6 +119,7 @@ public interface IAuthData {
*
* @return
*/
+ @Deprecated
String getBPK();
/**
@@ -127,6 +128,7 @@ public interface IAuthData {
*
* @return Sector identifier with prefix
*/
+ @Deprecated
String getBPKType();
@@ -134,6 +136,7 @@ public interface IAuthData {
* Get List of bPK/bPKType tuples for this service provider
* @return List of Pairs<bPK, bPKType>
*/
+ @Deprecated
List<Pair<String, String>> getAdditionalbPKs();
/**
@@ -141,6 +144,7 @@ public interface IAuthData {
*
* @return
*/
+ @Deprecated
String getIdentificationValue();
/**
@@ -149,6 +153,7 @@ public interface IAuthData {
*
* @return
*/
+ @Deprecated
String getIdentificationType();
@@ -157,6 +162,7 @@ public interface IAuthData {
*
* @return IDL, or NULL if no IDL is available
*/
+ @Deprecated
IIdentityLink getIdentityLink();
/**
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
index cba8fde7..5481fd52 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/ISSOManager.java
@@ -60,11 +60,11 @@ public interface ISSOManager {
/**
* Populate service provider specific SSO settings
*
- * Check if Single Sign-On is allowed for the current pending request and the requested service provider
+ * Check if Single Sign-On is allowed for the current pending request and the requested service provider
+ * Set IRequest.needSingleSignOnFunctionality() to true if SSO is allowed
*
* @param pendingReq Current incoming pending request
* @param httpReq http Servlet request
- * @return true if SSO is allowed for this service provider, otherwise false
*/
public void isSSOAllowedForSP(IRequest pendingReq, HttpServletRequest httpReq);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
index 76e071c6..46dd3850 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/data/IAuthProcessDataContainer.java
@@ -67,6 +67,7 @@ public interface IAuthProcessDataContainer {
*
* @return IdentityLink
*/
+ @Deprecated
IIdentityLink getIdentityLink();
/**
@@ -75,9 +76,9 @@ public interface IAuthProcessDataContainer {
* @param identityLink
* The identityLink to set
*/
+ @Deprecated
void setIdentityLink(IIdentityLink identityLink);
-
/**
* Indicate that mandates was used in this auth. process
*
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/services/IProtocolAuthenticationService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/services/IProtocolAuthenticationService.java
new file mode 100644
index 00000000..f6f8e576
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/idp/auth/services/IProtocolAuthenticationService.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2017 Graz University of Technology
+ * EAAF-Core Components has been developed in a cooperation between EGIZ,
+ * A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.api.idp.auth.services;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+
+public interface IProtocolAuthenticationService {
+
+ /**
+ * Initialize an authentication process for this protocol request
+ *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param protocolRequest Authentication request which is actually in process
+ * @throws IOException
+ * @throws EAAFException
+ */
+ void performAuthentication(HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq)
+ throws IOException, EAAFException;
+
+ /**
+ * Finalize the requested protocol operation
+ *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param protocolRequest Authentication request which is actually in process
+ * @throws IOException If response can not be written into {@link HttpServletResponse}
+ * @throws EAAFException If an internal error occur
+ */
+ void finalizeAuthentication(HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq) throws EAAFException, IOException;
+
+ /**
+ * @param throwable Exception that should be handled
+ * @param req Current open http request as {@link HttpServletRequest}
+ * @param resp Current open http response as {@link HttpServletResponse}
+ * @param pendingReq Authentication request which is actually in process
+ * @throws IOException If response can not be written into {@link HttpServletResponse}
+ * @throws EAAFException If an internal error occur
+ */
+ void buildProtocolSpecificErrorResponse(Throwable throwable, HttpServletRequest req, HttpServletResponse resp,
+ IRequest pendingReq) throws IOException, EAAFException;
+
+ /**
+ * Handles all exceptions with no pending request.
+ * Therefore, the error is written to the users browser
+ *
+ * @param throwable Exception that should be handled
+ * @param req Current open http request as {@link HttpServletRequest}
+ * @param resp Current open http response as {@link HttpServletResponse}
+ * @param writeExceptionToStatisticLog if <code>true</code>, the exception get logged into {@link IStatisticLogger}
+ * @throws IOException If response can not be written into {@link HttpServletResponse}
+ * @throws EAAFException If an internal error occure
+ */
+ void handleErrorNoRedirect(Throwable throwable, HttpServletRequest req, HttpServletResponse resp, boolean writeExceptionToStatisticLog) throws IOException, EAAFException;
+
+} \ No newline at end of file
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
index 23763cde..0d3eaf18 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
@@ -134,8 +134,10 @@ public abstract class AbstractAuthenticationManager implements IAuthenticationMa
ssoManager.isSSOAllowedForSP(pendingReq, httpReq);
//check if SSO session is active and valid
- isValidSSOSession = ssoManager.checkAndValidateSSOSession(pendingReq, httpReq, httpResp);
-
+ isValidSSOSession = ssoManager.checkAndValidateSSOSession(pendingReq, httpReq, httpResp) &&
+ pendingReq.needSingleSignOnFunctionality();
+
+
}
//check if session is already authenticated
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
index 0b334126..eb87e893 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
@@ -55,7 +55,7 @@ import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
-import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractAuthProtocolModulController;
+import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController;
import at.gv.egiz.eaaf.core.impl.idp.process.springweb.AbstractTask;
import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder;
@@ -101,7 +101,7 @@ public abstract class AbstractAuthServletTask extends AbstractTask {
* @param httpResp
*/
protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) {
- performRedirectToItself(pendingReq, httpResp, AbstractAuthProtocolModulController.ENDPOINT_FINALIZEPROTOCOL);
+ performRedirectToItself(pendingReq, httpResp, ProtocolFinalizationController.ENDPOINT_FINALIZEPROTOCOL);
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java
new file mode 100644
index 00000000..85c609e0
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java
@@ -0,0 +1,458 @@
+/*******************************************************************************
+ * Copyright 2019 Graz University of Technology
+ * EAAF-Core Components has been developed in a cooperation between EGIZ,
+ * A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.auth.services;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
+import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IAction;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
+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.api.logging.IStatisticLogger;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
+import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
+
+@Service
+public class ProtocolAuthenticationService implements IProtocolAuthenticationService {
+ private static final Logger log = LoggerFactory.getLogger(ProtocolAuthenticationService.class);
+
+ @Autowired(required=true) private ApplicationContext applicationContext;
+ @Autowired(required=true) private ITransactionStorage transactionStorage;
+ @Autowired(required=true) private IAuthenticationManager authmanager;
+ @Autowired(required=true) private IAuthenticationDataBuilder authDataBuilder;
+ @Autowired(required=true) private IGUIFormBuilder guiBuilder;
+ @Autowired(required=true) private IGUIBuilderConfigurationFactory guiConfigFactory;
+ @Autowired(required=true) private IStatusMessenger statusMessager;
+ @Autowired(required=true) private IRequestStorage requestStorage;
+
+ @Autowired private ISSOManager ssoManager;
+ @Autowired private IStatisticLogger statisticLogger;
+ @Autowired private IRevisionLogger revisionsLogger;
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#performAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
+ */
+ @Override
+ public void performAuthentication(final HttpServletRequest req, final HttpServletResponse resp,
+ final IRequest pendingReq) throws IOException, EAAFException {
+ try {
+ if (pendingReq.isNeedAuthentication()) {
+ //request needs authentication --> start authentication process ...
+
+ //load Parameters from OnlineApplicationConfiguration
+ final ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+
+ if (oaParam == null)
+ throw new EAAFAuthenticationException(
+ IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
+ new Object[] { pendingReq.getSPEntityId() });
+
+ if (authmanager.doAuthentication(req, resp, pendingReq)) {
+ //pending request is already authenticated --> protocol-specific postProcessing can start directly
+ finalizeAuthentication(req, resp, pendingReq);
+
+ //transaction is finished, log transaction finished event
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+
+ }
+
+ } else {
+ executeProtocolSpecificAction(req, resp, pendingReq, null);
+
+ }
+
+ } catch (final Exception e) {
+ buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+ authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#finalizeAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
+ */
+ @Override
+ public void finalizeAuthentication(final HttpServletRequest req, final HttpServletResponse resp, final IRequest pendingReq) throws EAAFException, IOException{
+ log.debug("Finalize PendingRequest with ID " + pendingReq.getPendingRequestId());
+ try {
+
+ //check if pending-request has 'abortedByUser' flag set
+ if (pendingReq.isAbortedByUser()) {
+ //send authentication aborted error to Service Provider
+ buildProtocolSpecificErrorResponse(
+ new EAAFAuthenticationException(
+ IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP,
+ new Object[] {}),
+ req, resp, pendingReq);
+
+ //do not remove the full active SSO-Session
+ // in case of only one Service-Provider authentication request is aborted
+ if ( !pendingReq.needSingleSignOnFunctionality()) {
+ transactionStorage.remove(pendingReq.getPendingRequestId());
+
+ }
+
+ //check if pending-request are authenticated
+ } else if (pendingReq.isAuthenticated()) {
+ internalFinalizeAuthenticationProcess(req, resp, pendingReq);
+
+ } else {
+ //suspect state: pending-request is not aborted but also are not authenticated
+ log.error("PendingRequest is NOT authenticated --> Abort authentication process!");
+ handleErrorNoRedirect(
+ new EAAFException(
+ "auth.20",
+ null), req, resp, true);
+
+ }
+
+ } catch (Exception e) {
+ log.error("Finalize authentication protocol FAILED." , e);
+ buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+
+ if (pendingReq != null)
+ transactionStorage.remove(pendingReq.getPendingRequestId());
+
+ }
+
+ //remove pending-request
+ if (pendingReq != null) {
+ requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+
+ }
+ }
+
+
+ @Override
+ public void buildProtocolSpecificErrorResponse(final Throwable throwable, final HttpServletRequest req,
+ final HttpServletResponse resp, final IRequest protocolRequest) throws EAAFException, IOException {
+ try {
+
+ final Class<?> clazz = Class.forName(protocolRequest.requestedModule());
+
+ if (clazz == null ||
+ !IModulInfo.class.isAssignableFrom(clazz)) {
+ log.error("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+ throw new Exception("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+
+ }
+
+ final IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
+
+ if (handlingModule.generateErrorMessage(
+ throwable, req, resp, protocolRequest)) {
+
+ //log Error to technical log
+ logExceptionToTechnicalLog(throwable);
+
+ //log Error Message
+ statisticLogger.logErrorOperation(throwable, protocolRequest);
+
+ //write revision log entries
+ revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR, protocolRequest.getUniqueTransactionIdentifier());
+
+ return;
+
+ } else {
+ handleErrorNoRedirect(throwable, req, resp, true);
+
+ }
+
+ } catch (final Throwable e) {
+ handleErrorNoRedirect(throwable, req, resp, true);
+
+ }
+
+ }
+
+ @Override
+ public void handleErrorNoRedirect(final Throwable throwable, final HttpServletRequest req,
+ final HttpServletResponse resp, final boolean writeExceptionToStatisticLog) throws IOException, EAAFException {
+
+ //log Exception into statistic database
+ if (writeExceptionToStatisticLog)
+ statisticLogger.logErrorOperation(throwable);
+
+ //write errror to console
+ logExceptionToTechnicalLog(throwable);
+
+ //return error to Web browser
+ if (throwable instanceof EAAFException || throwable instanceof ProcessExecutionException)
+ internalMOAIDExceptionHandler(req, resp, (Exception)throwable, false);
+
+ else {
+ //write generic message for general exceptions
+ final String msg = statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null);
+ writeHTMLErrorResponse(req, resp, msg, "9199", (Exception) throwable);
+
+ }
+
+ }
+
+ /**
+ * Finalize the requested protocol operation
+ *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param protocolRequest Authentication request which is actually in process
+ * @param moaSession MOASession object, which is used to generate the protocol specific authentication information
+ * @throws Exception
+ */
+ protected void internalFinalizeAuthenticationProcess(final HttpServletRequest req, final HttpServletResponse resp,
+ final IRequest pendingReq) throws Exception {
+
+ String newSSOSessionId = null;
+
+ //if Single Sign-On functionality is enabled for this request
+ if (pendingReq.needSingleSignOnFunctionality()) {
+ if (ssoManager != null) {
+ newSSOSessionId = ssoManager.createNewSSOSessionCookie(req, resp, pendingReq);
+ if (StringUtils.isEmpty(pendingReq.getInternalSSOSessionIdentifier()))
+ ssoManager.createNewSSOSession(pendingReq, newSSOSessionId);
+
+ } else
+ log.warn("SSO is requested but there is not SSO Session-Manager available");
+
+ }
+
+ //build authenticationdata from session information and OA configuration
+ final IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);
+
+ //execute the protocol-specific action
+ final SLOInformationInterface sloInformation = executeProtocolSpecificAction(req, resp, pendingReq, authData);
+
+ //Store OA specific SSO session information if an SSO cookie is set
+ if (StringUtils.isNotEmpty(newSSOSessionId)) {
+ try {
+ ssoManager.updateSSOSession(pendingReq, newSSOSessionId, sloInformation);
+
+ } catch (final EAAFSSOException e) {
+ log.warn("SSO Session information can not be stored -> SSO is not enabled!");
+ authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+
+ }
+
+ } else {
+ //remove MOASession from database
+ authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
+
+ }
+
+ //Advanced statistic logging
+ statisticLogger.logSuccessOperation(pendingReq, authData, StringUtils.isNotEmpty(newSSOSessionId));
+
+ }
+
+ /**
+ * Executes the requested protocol action
+ *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param protocolRequest Authentication request which is actually in process
+ * @param authData Service-provider specific authentication data
+ *
+ * @return Return Single LogOut information or null if protocol supports no SSO
+ *
+ * @throws Exception
+ */
+ private SLOInformationInterface executeProtocolSpecificAction(final HttpServletRequest httpReq, final HttpServletResponse httpResp,
+ final IRequest pendingReq, final IAuthData authData) throws Exception {
+ try {
+ // request needs no authentication --> start request processing
+ final Class<?> clazz = Class.forName(pendingReq.requestedAction());
+ if (clazz == null ||
+ !IAction.class.isAssignableFrom(clazz)) {
+ log.error("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+ throw new Exception("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+
+ }
+
+ final IAction protocolAction = (IAction) applicationContext.getBean(clazz);
+ return protocolAction.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ } catch (final ClassNotFoundException e) {
+ log.error("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+ throw new Exception("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+ }
+
+ }
+
+ /**
+ * Write a Exception to the MOA-ID-Auth internal technical log
+ *
+ * @param loggedException Exception to log
+ */
+ protected void logExceptionToTechnicalLog(final Throwable loggedException) {
+ if (!( loggedException instanceof EAAFException
+ || loggedException instanceof ProcessExecutionException )) {
+ log.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
+
+ } else {
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.warn(loggedException.getMessage(), loggedException);
+
+ } else {
+ log.warn(loggedException.getMessage());
+
+ }
+ }
+ }
+
+ private void writeBadRequestErrorResponse(final HttpServletRequest req, final HttpServletResponse resp, final EAAFException e) throws IOException {
+ final String code = statusMessager.mapInternalErrorToExternalError(((InvalidProtocolRequestException)e).getErrorId());
+ final String descr = StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage()));
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
+ "(Errorcode=" + code +
+ " | Description=" + descr + ")");
+
+ }
+
+ private void writeHTMLErrorResponse(final HttpServletRequest req, final HttpServletResponse httpResp, final String msg, final String errorCode, final Exception error) throws IOException, EAAFException {
+
+ try {
+ final IGUIBuilderConfiguration config
+ = guiConfigFactory.getDefaultErrorGUI(HTTPUtils.extractAuthURLFromRequest(req));
+
+// HTTPUtils.extractAuthURLFromRequest(req),
+// DefaultGUIFormBuilderConfiguration.VIEW_ERRORMESSAGE,
+// null);
+
+ //add errorcode and errormessage
+ if (config instanceof ModifyableGuiBuilderConfiguration) {
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorMsg", msg);
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorCode", errorCode);
+
+ //add stacktrace if debug is enabled
+ if (log.isTraceEnabled()) {
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("stacktrace", getStacktraceFromException(error));
+
+ }
+
+ } else
+ log.info("Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
+
+
+
+ guiBuilder.build(httpResp, config, "Error-Message");
+
+ } catch (final GUIBuildException e) {
+ log.warn("Can not build error-message GUI.", e);
+ throw new EAAFException("9199", null, e);
+
+
+ }
+
+ }
+
+ private void writeHTMLErrorResponse(final HttpServletRequest req, final HttpServletResponse httpResp, final Exception error) throws IOException, EAAFException {
+ writeHTMLErrorResponse(req, httpResp,
+ error.getMessage(),
+ statusMessager.getResponseErrorCode(error),
+ error);
+ }
+
+
+ private String getStacktraceFromException(final Exception ex) {
+ final StringWriter errors = new StringWriter();
+ ex.printStackTrace(new PrintWriter(errors));
+ return errors.toString();
+
+ }
+
+ private void internalMOAIDExceptionHandler(final HttpServletRequest req, final HttpServletResponse resp, final Exception e, final boolean writeExceptionToStatisicLog) throws IOException, EAAFException {
+ if (e instanceof ProtocolNotActiveException) {
+ resp.getWriter().write(e.getMessage());
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN,
+ StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
+
+ } else if (e instanceof AuthnRequestValidatorException) {
+ final AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
+ //log Error Message
+ if (writeExceptionToStatisicLog)
+ statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
+
+ //write error message
+ writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+
+ } else if (e instanceof InvalidProtocolRequestException) {
+ //send error response
+ writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+
+ } else if (e instanceof ConfigurationException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, e);
+
+ } else if (e instanceof EAAFException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, e);
+
+ } else if (e instanceof ProcessExecutionException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, e);
+
+ }
+
+ }
+
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java
deleted file mode 100644
index 2f1cc6b4..00000000
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractAuthProtocolModulController.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.core.impl.idp.controller;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import at.gv.egiz.components.eventlog.api.EventConstants;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.IStatusMessenger;
-import at.gv.egiz.eaaf.core.api.idp.IAction;
-import at.gv.egiz.eaaf.core.api.idp.IAuthData;
-import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder;
-import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
-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.exceptions.EAAFAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
-
-/**
- * @author tlenz
- *
- */
-
-public abstract class AbstractAuthProtocolModulController extends AbstractController {
- private static final Logger log = LoggerFactory.getLogger(AbstractAuthProtocolModulController.class);
-
- public static final String ENDPOINT_FINALIZEPROTOCOL = "finalizeAuthProtocol";
- public static final String ENDPOINT_ERRORHANDLING = "errorHandling";
-
-
- @Autowired(required=true) private IAuthenticationManager authmanager;
- @Autowired(required=true) private IAuthenticationDataBuilder authDataBuilder;
- @Autowired(required=false) private ISSOManager ssoManager;
-
- /**
- * Initialize an authentication process for this protocol request
- *
- * @param httpReq HttpServletRequest
- * @param httpResp HttpServletResponse
- * @param protocolRequest Authentication request which is actually in process
- * @throws IOException
- */
- protected void performAuthentication(HttpServletRequest req, HttpServletResponse resp,
- IRequest pendingReq) throws IOException {
- try {
- if (pendingReq.isNeedAuthentication()) {
- //request needs authentication --> start authentication process ...
-
- //load Parameters from OnlineApplicationConfiguration
- ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
-
- if (oaParam == null)
- throw new EAAFAuthenticationException(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
- new Object[] { pendingReq.getSPEntityId() });
-
- if (authmanager.doAuthentication(req, resp, pendingReq)) {
- //pending request is already authenticated --> protocol-specific postProcessing can start directly
- finalizeAuthenticationProcess(req, resp, pendingReq);
-
- //transaction is finished, log transaction finished event
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
-
- }
-
- } else {
- executeProtocolSpecificAction(req, resp, pendingReq, null);
-
- }
-
- } catch (Exception e) {
- buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
- }
-
-
- /**
- * Finalize the requested protocol operation
- *
- * @param httpReq HttpServletRequest
- * @param httpResp HttpServletResponse
- * @param protocolRequest Authentication request which is actually in process
- * @param moaSession MOASession object, which is used to generate the protocol specific authentication information
- * @throws Exception
- */
- protected void finalizeAuthenticationProcess(HttpServletRequest req, HttpServletResponse resp,
- IRequest pendingReq) throws Exception {
-
- String newSSOSessionId = null;
-
- //if Single Sign-On functionality is enabled for this request
- if (pendingReq.needSingleSignOnFunctionality()) {
- if (ssoManager != null) {
- newSSOSessionId = ssoManager.createNewSSOSessionCookie(req, resp, pendingReq);
- if (StringUtils.isEmpty(pendingReq.getInternalSSOSessionIdentifier()))
- ssoManager.createNewSSOSession(pendingReq, newSSOSessionId);
-
- } else
- log.warn("SSO is requested but there is not SSO Session-Manager available");
-
- }
-
- //build authenticationdata from session information and OA configuration
- IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);
-
- //execute the protocol-specific action
- SLOInformationInterface sloInformation = executeProtocolSpecificAction(req, resp, pendingReq, authData);
-
- //Store OA specific SSO session information if an SSO cookie is set
- if (StringUtils.isNotEmpty(newSSOSessionId)) {
- try {
- ssoManager.updateSSOSession(pendingReq, newSSOSessionId, sloInformation);
-
- } catch (EAAFSSOException e) {
- log.warn("SSO Session information can not be stored -> SSO is not enabled!");
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
-
- } else {
- //remove MOASession from database
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
-
- //Advanced statistic logging
- statisticLogger.logSuccessOperation(pendingReq, authData, StringUtils.isNotEmpty(newSSOSessionId));
-
- }
-
- /**
- * Executes the requested protocol action
- *
- * @param httpReq HttpServletRequest
- * @param httpResp HttpServletResponse
- * @param protocolRequest Authentication request which is actually in process
- * @param authData Service-provider specific authentication data
- *
- * @return Return Single LogOut information or null if protocol supports no SSO
- *
- * @throws Exception
- */
- private SLOInformationInterface executeProtocolSpecificAction(HttpServletRequest httpReq, HttpServletResponse httpResp,
- IRequest pendingReq, IAuthData authData) throws Exception {
- try {
- // request needs no authentication --> start request processing
- Class<?> clazz = Class.forName(pendingReq.requestedAction());
- if (clazz == null ||
- !IAction.class.isAssignableFrom(clazz)) {
- log.error("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
- throw new Exception("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
-
- }
-
- IAction protocolAction = (IAction) applicationContext.getBean(clazz);
- return protocolAction.processRequest(pendingReq, httpReq, httpResp, authData);
-
- } catch (ClassNotFoundException e) {
- log.error("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
- throw new Exception("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
- }
-
- }
-
- protected void buildProtocolSpecificErrorResponse(Throwable throwable, HttpServletRequest req,
- HttpServletResponse resp, IRequest protocolRequest) throws IOException {
- try {
-
- Class<?> clazz = Class.forName(protocolRequest.requestedModule());
-
- if (clazz == null ||
- !IModulInfo.class.isAssignableFrom(clazz)) {
- log.error("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
- throw new Exception("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
-
- }
-
- IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
-
- if (handlingModule.generateErrorMessage(
- throwable, req, resp, protocolRequest)) {
-
- //log Error to technical log
- logExceptionToTechnicalLog(throwable);
-
- //log Error Message
- statisticLogger.logErrorOperation(throwable, protocolRequest);
-
- //write revision log entries
- revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR, protocolRequest.getUniqueTransactionIdentifier());
-
- return;
-
- } else {
- handleErrorNoRedirect(throwable, req, resp, true);
-
- }
-
- } catch (Throwable e) {
- handleErrorNoRedirect(throwable, req, resp, true);
-
- }
-
- }
-
-}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
index e7f2fe62..4e58868b 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
@@ -27,14 +27,9 @@
package at.gv.egiz.eaaf.core.impl.idp.controller;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import javax.naming.ConfigurationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,26 +39,16 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
-import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
-import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
-import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
-import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
-import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
-import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
-import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
-import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
-import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
import at.gv.egiz.eaaf.core.impl.utils.Random;
import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
@@ -76,30 +61,29 @@ public abstract class AbstractController {
private static final Logger log = LoggerFactory.getLogger(AbstractController.class);
+ @Autowired(required=true) protected IProtocolAuthenticationService protAuthService;
@Autowired(required=true) protected ApplicationContext applicationContext;
@Autowired(required=true) protected IConfiguration authConfig;
@Autowired(required=true) protected ITransactionStorage transactionStorage;
- @Autowired(required=true) protected IRequestStorage requestStorage;
- @Autowired(required=true) protected IGUIFormBuilder guiBuilder;
- @Autowired(required=true) protected IGUIBuilderConfigurationFactory guiConfigFactory;
@Autowired(required=true) protected IStatusMessenger statusMessager;
-
- @Autowired protected IStatisticLogger statisticLogger;
+
@Autowired protected IRevisionLogger revisionsLogger;
-
-
-
-
-
+
@ExceptionHandler({EAAFException.class})
- public void MOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) throws IOException {
- log.error(e.getMessage() , e);
- internalMOAIDExceptionHandler(req, resp, e, true);
+ public void MOAIDExceptionHandler(final HttpServletRequest req, final HttpServletResponse resp, final Exception e) throws IOException {
+ try {
+ protAuthService.handleErrorNoRedirect(e, req, resp, true);
+
+ } catch (final EAAFException e1) {
+ log.warn("Can NOT handle an 'EAAFException'. Forwarding to generic error ... ", e);
+ IOExceptionHandler(resp, e);
+
+ }
}
@ExceptionHandler({Exception.class})
- public void GenericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException {
+ public void GenericExceptionHandler(final HttpServletResponse resp, final Exception exception) throws IOException {
log.error("Internel Server Error." , exception);
resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error!" +
@@ -112,7 +96,7 @@ public abstract class AbstractController {
}
@ExceptionHandler({IOException.class})
- public void IOExceptionHandler(HttpServletResponse resp, Throwable exception) {
+ public void IOExceptionHandler(final HttpServletResponse resp, final Throwable exception) {
log.error("Internel Server Error." , exception);
resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@@ -120,15 +104,11 @@ public abstract class AbstractController {
}
- protected void handleError(String errorMessage, Throwable exceptionThrown,
- HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq) throws IOException {
-
- String pendingRequestID = null;
- if (pendingReq != null)
- pendingRequestID = pendingReq.getPendingRequestId();
+ protected void handleError(final String errorMessage, final Throwable exceptionThrown,
+ final HttpServletRequest req, final HttpServletResponse resp, final IRequest pendingReq) throws IOException, EAAFException {
Throwable loggedException = null;
- Throwable extractedException = extractOriginalExceptionFromProcessException(exceptionThrown);
+ final Throwable extractedException = extractOriginalExceptionFromProcessException(exceptionThrown);
//extract pendingRequestID and originalException if it was a TaskExecutionException
if (extractedException instanceof TaskExecutionException) {
@@ -138,12 +118,7 @@ public abstract class AbstractController {
//use TaskExecutionException directly, if no Original Exeception is included
if (loggedException == null)
loggedException = exceptionThrown;
-
- //set pending-request ID if it is set
- String reqID = ((TaskExecutionException) extractedException).getPendingRequestID();
- if (StringUtils.isNotEmpty(reqID))
- pendingRequestID = reqID;
-
+
} else
loggedException = exceptionThrown;
@@ -156,7 +131,7 @@ public abstract class AbstractController {
//put exception into transaction store for redirect
- String key = Random.nextLongRandom();
+ final String key = Random.nextLongRandom();
if (pendingReq != null) {
revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR);
transactionStorage.put(key,
@@ -171,13 +146,9 @@ public abstract class AbstractController {
//build up redirect URL
String redirectURL = null;
redirectURL = ServletUtils.getBaseUrl(req);
- redirectURL += "/"+AbstractAuthProtocolModulController.ENDPOINT_ERRORHANDLING
+ redirectURL += "/"+ProtocolFinalizationController.ENDPOINT_ERRORHANDLING
+ "?" + EAAFConstants.PARAM_HTTP_ERROR_CODE + "=" + key;
-
-// //only add pending-request Id if it exists
-// if (StringUtils.isNotEmpty(pendingRequestID))
-// redirectURL += "&" + EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + pendingRequestID;
-
+
resp.setContentType("text/html");
resp.setStatus(302);
@@ -186,128 +157,18 @@ public abstract class AbstractController {
return;
- } catch (Exception e) {
+ } catch (final Exception e) {
log.warn("Default error-handling FAILED. Exception can not be stored ....", e);
log.info("Switch to generic generic backup error-handling ... ");
- handleErrorNoRedirect(loggedException, req, resp, true);
+ protAuthService.handleErrorNoRedirect(loggedException, req, resp, true);
}
}
- /**
- * Handles all exceptions with no pending request.
- * Therefore, the error is written to the users browser
- *
- * @param throwable
- * @param req
- * @param resp
- * @throws IOException
- */
- protected void handleErrorNoRedirect(Throwable throwable, HttpServletRequest req,
- HttpServletResponse resp, boolean writeExceptionToStatisticLog) throws IOException {
-
- //log Exception into statistic database
- if (writeExceptionToStatisticLog)
- statisticLogger.logErrorOperation(throwable);
-
- //write errror to console
- logExceptionToTechnicalLog(throwable);
-
- //return error to Web browser
- if (throwable instanceof EAAFException || throwable instanceof ProcessExecutionException)
- internalMOAIDExceptionHandler(req, resp, (Exception)throwable, false);
-
- else {
- //write generic message for general exceptions
- String msg = statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null);
- writeHTMLErrorResponse(req, resp, msg, "9199", (Exception) throwable);
-
- }
-
- }
-
- /**
- * Write a Exception to the MOA-ID-Auth internal technical log
- *
- * @param loggedException Exception to log
- */
- protected void logExceptionToTechnicalLog(Throwable loggedException) {
- if (!( loggedException instanceof EAAFException
- || loggedException instanceof ProcessExecutionException )) {
- log.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
-
- } else {
- if (log.isDebugEnabled() || log.isTraceEnabled()) {
- log.warn(loggedException.getMessage(), loggedException);
-
- } else {
- log.warn(loggedException.getMessage());
-
- }
- }
- }
-
- private void writeBadRequestErrorResponse(HttpServletRequest req, HttpServletResponse resp, EAAFException e) throws IOException {
- String code = statusMessager.mapInternalErrorToExternalError(((InvalidProtocolRequestException)e).getErrorId());
- String descr = StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage()));
- resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
- "(Errorcode=" + code +
- " | Description=" + descr + ")");
-
- }
-
- private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, String msg, String errorCode, Exception error) throws IOException {
-
- try {
- IGUIBuilderConfiguration config
- = guiConfigFactory.getDefaultErrorGUI(HTTPUtils.extractAuthURLFromRequest(req));
-// HTTPUtils.extractAuthURLFromRequest(req),
-// DefaultGUIFormBuilderConfiguration.VIEW_ERRORMESSAGE,
-// null);
-
- //add errorcode and errormessage
- if (config instanceof ModifyableGuiBuilderConfiguration) {
- ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorMsg", msg);
- ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorCode", errorCode);
-
- //add stacktrace if debug is enabled
- if (log.isTraceEnabled()) {
- ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("stacktrace", getStacktraceFromException(error));
-
- }
-
- } else
- log.info("Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
-
-
- guiBuilder.build(httpResp, config, "Error-Message");
-
- } catch (GUIBuildException e) {
- log.warn("Can not build error-message GUI.", e);
- GenericExceptionHandler(httpResp, e);
-
- }
-
- }
-
- private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, Exception error) throws IOException {
- writeHTMLErrorResponse(req, httpResp,
- error.getMessage(),
- statusMessager.getResponseErrorCode(error),
- error);
- }
-
- private String getStacktraceFromException(Exception ex) {
- StringWriter errors = new StringWriter();
- ex.printStackTrace(new PrintWriter(errors));
- return errors.toString();
-
- }
/**
* Extracts a TaskExecutionException of a ProcessExecutionExeception Stacktrace.
@@ -315,13 +176,13 @@ public abstract class AbstractController {
* @param exception
* @return Return the latest TaskExecutionExecption if exists, otherwise the latest ProcessExecutionException
*/
- private Throwable extractOriginalExceptionFromProcessException(Throwable exception) {
+ private Throwable extractOriginalExceptionFromProcessException(final Throwable exception) {
Throwable exholder = exception;
TaskExecutionException taskExc = null;
while(exholder != null
&& exholder instanceof ProcessExecutionException) {
- ProcessExecutionException procExc = (ProcessExecutionException) exholder;
+ final ProcessExecutionException procExc = (ProcessExecutionException) exholder;
if (procExc.getCause() != null &&
procExc.getCause() instanceof TaskExecutionException) {
taskExc = (TaskExecutionException) procExc.getCause();
@@ -339,40 +200,6 @@ public abstract class AbstractController {
return taskExc;
}
- private void internalMOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e, boolean writeExceptionToStatisicLog) throws IOException {
- if (e instanceof ProtocolNotActiveException) {
- resp.getWriter().write(e.getMessage());
- resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
- resp.sendError(HttpServletResponse.SC_FORBIDDEN,
- StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
-
- } else if (e instanceof AuthnRequestValidatorException) {
- AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
- //log Error Message
- if (writeExceptionToStatisicLog)
- statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
-
- //write error message
- writeBadRequestErrorResponse(req, resp, (EAAFException) e);
-
- } else if (e instanceof InvalidProtocolRequestException) {
- //send error response
- writeBadRequestErrorResponse(req, resp, (EAAFException) e);
-
- } else if (e instanceof ConfigurationException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp, (EAAFException) e);
-
- } else if (e instanceof EAAFException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp, e);
-
- } else if (e instanceof ProcessExecutionException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp, e);
-
- }
-
- }
+
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
index d6448c95..6afa4fee 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
@@ -53,9 +54,10 @@ import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
public abstract class AbstractProcessEngineSignalController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(AbstractProcessEngineSignalController.class);
- @Autowired protected ProcessEngine processEngine;
+ @Autowired(required=true) protected ProcessEngine processEngine;
+ @Autowired(required=true) IRequestStorage requestStorage;
- protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException, EAAFException {
String pendingRequestID = StringEscapeUtils.escapeHtml4(getPendingRequestId(req));
IRequest pendingReq = null;
try {
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
index e96ea138..b830e240 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
@@ -20,10 +20,6 @@
* The "NOTICE" text file is part of the distribution. Any derivative works
* that you distribute must include a readable copy of the "NOTICE" text file.
*******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
package at.gv.egiz.eaaf.core.impl.idp.controller;
import java.io.IOException;
@@ -34,16 +30,18 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
import at.gv.egiz.eaaf.core.exceptions.EAAFException;
/**
@@ -51,8 +49,12 @@ import at.gv.egiz.eaaf.core.exceptions.EAAFException;
*
*/
@Controller
-public class ProtocolFinalizationController extends AbstractAuthProtocolModulController {
+public class ProtocolFinalizationController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(ProtocolFinalizationController.class);
+ public static final String ENDPOINT_FINALIZEPROTOCOL = "finalizeAuthProtocol";
+ public static final String ENDPOINT_ERRORHANDLING = "errorHandling";
+
+ @Autowired(required=true) IRequestStorage requestStorage;
@RequestMapping(value = ENDPOINT_ERRORHANDLING, method = {RequestMethod.GET})
public void errorHandling(HttpServletRequest req, HttpServletResponse resp) throws EAAFException, IOException {
@@ -72,7 +74,7 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon
if (pendingReq != null) {
//build protocol-specific error message if possible
- buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq);
+ protAuthService.buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq);
//remove active user-session
transactionStorage.remove(pendingReq.getPendingRequestId());
@@ -80,11 +82,11 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon
return;
} else {
- handleErrorNoRedirect(throwable, req, resp, true);
+ protAuthService.handleErrorNoRedirect(throwable, req, resp, true);
}
} else {
- handleErrorNoRedirect(
+ protAuthService.handleErrorNoRedirect(
new EAAFException(
IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID,
null), req, resp, false);
@@ -93,7 +95,7 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon
} catch (Throwable e) {
log.error(e.getMessage(), e);
- handleErrorNoRedirect(e, req, resp, false);
+ protAuthService.handleErrorNoRedirect(e, req, resp, false);
} finally {
//remove pending-request
@@ -107,7 +109,7 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon
} else {
log.debug("Request contains NO ErrorId");
- handleErrorNoRedirect(
+ protAuthService.handleErrorNoRedirect(
new EAAFException(
IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID,
null), req, resp, false);
@@ -132,62 +134,14 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon
if (pendingReq == null) {
log.error("No PendingRequest with ID " + pendingRequestID + " found.!");
- handleErrorNoRedirect(
+ protAuthService.handleErrorNoRedirect(
new EAAFException(
IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_TIMEOUT,
new Object[]{pendingRequestID,
}), req, resp, false);
- } else {
- try {
- log.debug("Finalize PendingRequest with ID " + pendingRequestID);
-
- //check if pending-request has 'abortedByUser' flag set
- if (pendingReq.isAbortedByUser()) {
- //send authentication aborted error to Service Provider
- buildProtocolSpecificErrorResponse(
- new EAAFAuthenticationException(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP,
- new Object[] {}),
- req, resp, pendingReq);
-
- //do not remove the full active SSO-Session
- // in case of only one Service-Provider authentication request is aborted
- if ( !pendingReq.needSingleSignOnFunctionality()) {
- transactionStorage.remove(pendingReq.getPendingRequestId());
-
- }
-
- //check if pending-request are authenticated
- } else if (pendingReq.isAuthenticated()) {
- finalizeAuthenticationProcess(req, resp, pendingReq);
-
- } else {
- //suspect state: pending-request is not aborted but also are not authenticated
- log.error("PendingRequest is NOT authenticated --> Abort authentication process!");
- handleErrorNoRedirect(
- new EAAFException(
- "auth.20",
- null), req, resp, true);
-
- }
-
- } catch (Exception e) {
- log.error("Finalize authentication protocol FAILED." , e);
- buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
-
- if (pendingReq != null)
- transactionStorage.remove(pendingReq.getPendingRequestId());
-
- }
- }
-
- //remove pending-request
- if (pendingReq != null) {
- requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
-
- }
+ } else
+ protAuthService.finalizeAuthentication(req, resp, pendingReq);
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
index 0370c14d..eff6b631 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java
@@ -26,15 +26,20 @@
*******************************************************************************/
package at.gv.egiz.eaaf.core.impl.idp.controller.tasks;
+import java.io.Serializable;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.stereotype.Component;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.exceptions.EAAFException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
@@ -47,7 +52,9 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
@Component("FinalizeAuthenticationTask")
public class FinalizeAuthenticationTask extends AbstractAuthServletTask {
- private static final Logger log = LoggerFactory.getLogger(FinalizeAuthenticationTask.class);
+ private static final Logger log = LoggerFactory.getLogger(FinalizeAuthenticationTask.class);
+
+ @Autowired(required=true) IProtocolAuthenticationService protAuchService;
/* (non-Javadoc)
* @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@@ -60,13 +67,22 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask {
try {
//set pending request to authenticated
pendingReq.setAuthenticated(true);
- requestStoreage.storePendingRequest(pendingReq);
-
- log.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
- performRedirectToProtocolFinialization(pendingReq, response);
-
revisionsLogger.logEvent(pendingReq, IAuthenticationManager.EVENT_AUTHENTICATION_PROCESS_FINISHED);
+
+ Object frontChannelRedirectFlagObj = executionContext.get(EAAFConstants.PROCESS_ENGINE_REQUIRES_NO_POSTAUTH_REDIRECT);
+ if (frontChannelRedirectFlagObj != null && frontChannelRedirectFlagObj instanceof Boolean &&
+ (Boolean)frontChannelRedirectFlagObj) {
+ log.info("AuthProcess finished. Forward to Protocol finalization.");
+ protAuchService.finalizeAuthentication(request, response, pendingReq);
+
+ } else {
+ log.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
+ requestStoreage.storePendingRequest(pendingReq);
+ performRedirectToProtocolFinialization(pendingReq, response);
+
+ }
+
} catch (EAAFException e) {
throw new TaskExecutionException(pendingReq, e.getMessage(), e);