diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-04-11 09:44:11 +0200 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-04-11 09:44:11 +0200 |
commit | 61d276832ebcf1901183dab323126f8ecb6a7370 (patch) | |
tree | ec9df86e1eb3cfb74f1fb68a371cb21d04e40d6b /eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller | |
parent | 13952dddd85fc08115f963b259885b5c9b7f2b57 (diff) | |
download | EAAF-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/at/gv/egiz/eaaf/core/impl/idp/controller')
5 files changed, 69 insertions, 512 deletions
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); |