aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-02-18 11:01:55 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-02-18 11:01:55 +0100
commit98cdf5c84739362a2d41702f538c370fa3d2c86e (patch)
tree41baa19e7b4503a6c53edf3ecbeca5d2ac015ad0 /id/server/idserverlib/src/main/java/at/gv/egovernment
parent89dc33e5d6053af56a6d2cb11271ab092ced7dc3 (diff)
downloadmoa-id-spss-98cdf5c84739362a2d41702f538c370fa3d2c86e.tar.gz
moa-id-spss-98cdf5c84739362a2d41702f538c370fa3d2c86e.tar.bz2
moa-id-spss-98cdf5c84739362a2d41702f538c370fa3d2c86e.zip
update error handling and Web based error messages
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MOAIDException.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java211
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/AbstractProtocolModulController.java5
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java20
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ErrorResponseUtils.java6
5 files changed, 176 insertions, 79 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MOAIDException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MOAIDException.java
index 165fee599..ef6aaa75c 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MOAIDException.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MOAIDException.java
@@ -79,6 +79,8 @@ public class MOAIDException extends Exception {
/** wrapped exception */
private Throwable wrapped;
+ private Object[] parameters;
+
/**
* Create a new <code>MOAIDException</code>.
*
@@ -89,6 +91,7 @@ public class MOAIDException extends Exception {
public MOAIDException(String messageId, Object[] parameters) {
super(MOAIDMessageProvider.getInstance().getMessage(messageId, parameters));
this.messageId = messageId;
+ this.parameters = parameters;
}
/**
@@ -108,6 +111,7 @@ public class MOAIDException extends Exception {
super(MOAIDMessageProvider.getInstance().getMessage(messageId, parameters));
this.messageId = messageId;
this.wrapped = wrapped;
+ this.parameters = parameters;
}
/**
@@ -163,7 +167,16 @@ public class MOAIDException extends Exception {
return wrapped;
}
+
+
/**
+ * @return the parameters
+ */
+public Object[] getParameters() {
+ return parameters;
+}
+
+/**
* Convert this <code>MOAIDException</code> to an <code>ErrorResponse</code>
* element from the MOA namespace.
*
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java
index 26e24f5b4..887692477 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java
@@ -22,11 +22,21 @@
*/
package at.gv.egovernment.moa.id.auth.servlet;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -48,6 +58,7 @@ import at.gv.egovernment.moa.id.storage.ITransactionStorage;
import at.gv.egovernment.moa.id.util.ErrorResponseUtils;
import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.id.util.ServletUtils;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -59,34 +70,20 @@ public abstract class AbstractController extends MOAIDAuthConstants {
public static final String ERROR_CODE_PARAM = "errorid";
+ private static final String HTMLTEMPLATESDIR = "htmlTemplates/";
+ private static final String HTMLTEMPLATEFULL = "error_message.html";
+
@Autowired protected StatisticLogger statisticLogger;
@Autowired protected IRequestStorage requestStorage;
@Autowired protected ITransactionStorage transactionStorage;
@Autowired protected MOAReversionLogger revisionsLogger;
@Autowired protected AuthConfiguration authConfig;
-
-
+
protected void handleError(String errorMessage, Throwable exceptionThrown,
HttpServletRequest req, HttpServletResponse resp, String pendingRequestID) throws IOException {
- Throwable loggedException = null;
-
- if (exceptionThrown != null
- && exceptionThrown instanceof ProcessExecutionException) {
- ProcessExecutionException procExc =
- (ProcessExecutionException) exceptionThrown;
- if (procExc.getCause() != null &&
- procExc.getCause() instanceof TaskExecutionException) {
- TaskExecutionException taskExc = (TaskExecutionException) procExc.getCause();
- loggedException = taskExc.getOriginalException();
-
- }
- }
-
- if (loggedException == null)
- loggedException = exceptionThrown;
-
-
+ Throwable loggedException = extractOriginalExceptionFromProcessException(exceptionThrown);
+
if (!(loggedException instanceof MOAIDException)) {
Logger.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
@@ -103,13 +100,13 @@ public abstract class AbstractController extends MOAIDAuthConstants {
//store error into transaction store
try {
String key = Random.nextRandom();
- transactionStorage.put(key, exceptionThrown);
+ transactionStorage.put(key, loggedException);
if (key != null && MiscUtil.isNotEmpty(pendingRequestID)) {
String redirectURL = null;
redirectURL = ServletUtils.getBaseUrl(req);
- redirectURL += AbstractProtocolModulController.FINALIZEPROTOCOL_ENDPOINT
+ redirectURL += "/"+AbstractProtocolModulController.FINALIZEPROTOCOL_ENDPOINT
+ "?" + ERROR_CODE_PARAM + "=" + key
+ "&" + MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID + "=" + pendingRequestID;
@@ -123,13 +120,13 @@ public abstract class AbstractController extends MOAIDAuthConstants {
} else {
//Exception can not be stored in database
- handleErrorNoRedirect(loggedException, req, resp);
+ handleErrorNoRedirect(loggedException, req, resp, true);
}
} catch (MOADatabaseException e) {
Logger.warn("Exception can not be stored to Database.", e);
- handleErrorNoRedirect(loggedException, req, resp);
+ handleErrorNoRedirect(loggedException, req, resp, true);
}
@@ -147,77 +144,60 @@ public abstract class AbstractController extends MOAIDAuthConstants {
* @throws IOException
*/
protected void handleErrorNoRedirect(Throwable throwable, HttpServletRequest req,
- HttpServletResponse resp) throws IOException {
+ HttpServletResponse resp, boolean writeExceptionToStatisticLog) throws IOException {
//log Exception into statistic database
- statisticLogger.logErrorOperation(throwable);
+ if (writeExceptionToStatisticLog)
+ statisticLogger.logErrorOperation(throwable);
//write errror to console
Logger.error(throwable.getMessage(), throwable);
//return error to Web browser
- if (throwable instanceof MOAIDException)
- MOAIDExceptionHandler(req, resp, (MOAIDException)throwable);
+ if (throwable instanceof MOAIDException || throwable instanceof ProcessExecutionException)
+ MOAIDExceptionHandler(req, resp, (Exception)throwable);
else
- GenericExceptionHandler(req, resp, (Exception)throwable);
+ GenericExceptionHandler(resp, (Exception)throwable);
}
@ExceptionHandler({MOAIDException.class})
- public void MOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, MOAIDException e) throws IOException {
+ public void MOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) throws IOException {
if (e instanceof ProtocolNotActiveException) {
resp.getWriter().write(e.getMessage());
resp.setContentType("text/html;charset=UTF-8");
resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
- return;
} else if (e instanceof AuthnRequestValidatorException) {
AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
//log Error Message
- statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
- return;
-
- } else if (e instanceof InvalidProtocolRequestException) {
- //write log entry
- String samlRequest = req.getParameter("SAMLRequest");
- Logger.warn("Receive INVALID protocol request: " + samlRequest, e);
+ statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
- //send error response
- ErrorResponseUtils utils = ErrorResponseUtils.getInstance();
- String code = utils.mapInternalErrorToExternalError(e.getMessageId());
- String descr = e.getMessage();
- resp.setContentType("text/html;charset=UTF-8");
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
- "(Errorcode=" + code +
- " | Description=" + descr + ")");
- return;
- } else if (e instanceof ConfigurationException) {
- resp.setContentType("text/html;charset=UTF-8");
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "NO valid protocol request received!" +
- "(Errorcode=9199"
- +" | Description="+ e.getMessage() + ")");
- return;
+ //write error message
+ writeBadRequestErrorResponse(req, resp, (MOAIDException) e);
- //TODO: check exception type
- } else if (e instanceof MOAIDException) {
- String samlRequest = req.getParameter("SAMLRequest");
- if (MiscUtil.isNotEmpty(samlRequest))
- Logger.warn("Receive INVALID protocol request: " + samlRequest, e);
- else
- Logger.error("Failed to generate a valid protocol request!");
+ } else if (e instanceof InvalidProtocolRequestException) {
+ //send error response
+ writeBadRequestErrorResponse(req, resp, (MOAIDException) e);
- resp.setContentType("text/html;charset=UTF-8");
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "NO valid protocol request received!" +
- "(Errorcode=6000"
- +" | Description=Das Authentifizierungsprotokoll wurde nicht erkannt oder wird nicht unterst\u00FCzt" + ")");
- return;
+ } else if (e instanceof ConfigurationException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(resp, (MOAIDException) e);
+ } else if (e instanceof MOAIDException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(resp, e);
+
+ } else if (e instanceof ProcessExecutionException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(resp, e);
+
}
}
@ExceptionHandler({Exception.class})
- public void GenericExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception exception) throws IOException {
+ public void GenericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException {
Logger.error("Internel Server Error." , exception);
resp.setContentType("text/html;charset=UTF-8");
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error!" +
@@ -228,11 +208,108 @@ public abstract class AbstractController extends MOAIDAuthConstants {
}
@ExceptionHandler({IOException.class})
- public void IOExceptionHandler(HttpServletRequest req, HttpServletResponse resp, IOException exception) {
+ public void IOExceptionHandler(HttpServletResponse resp, IOException exception) {
Logger.error("Internel Server Error." , exception);
resp.setContentType("text/html;charset=UTF-8");
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
+
+ private void writeBadRequestErrorResponse(HttpServletRequest req, HttpServletResponse resp, MOAIDException e) throws IOException {
+ ErrorResponseUtils utils = ErrorResponseUtils.getInstance();
+ String code = utils.mapInternalErrorToExternalError(
+ ((InvalidProtocolRequestException)e).getMessageId());
+ String descr = e.getMessage();
+ resp.setContentType("text/html;charset=UTF-8");
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
+ "(Errorcode=" + code +
+ " | Description=" + descr + ")");
+
+ }
+
+ private void writeHTMLErrorResponse(HttpServletResponse httpResp, Exception error) throws IOException {
+ VelocityContext context = new VelocityContext();
+
+ //add errorcode and errormessage
+ context.put("errorMsg", error.getMessage());
+ context.put("errorCode", ErrorResponseUtils.getInstance().getResponseErrorCode(error));
+
+ //add stacktrace if debug is enabled
+ if (Logger.isDebugEnabled()) {
+ context.put("stacktrace", getStacktraceFromException(error));
+
+ }
+
+ try {
+ InputStream is = null;
+ String pathLocation = null;
+ try {
+ String rootconfigdir = authConfig.getRootConfigFileDir();
+ pathLocation = rootconfigdir + HTMLTEMPLATESDIR + HTMLTEMPLATEFULL;
+ File file = new File(new URI(pathLocation));
+ is = new FileInputStream(file);
+ evaluateErrorTemplate(context, httpResp, is);
+
+ } catch (Exception e) {
+ Logger.warn("SLO Template is not found in configuration directory (" +
+ pathLocation + "). Load template from project library ... ");
+
+ try {
+ pathLocation = "resources/templates/" + HTMLTEMPLATEFULL;
+ is = Thread.currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream(pathLocation);
+ evaluateErrorTemplate(context, httpResp, is);
+
+ } catch (Exception e1) {
+ Logger.error("Single LogOut form can not created.", e);
+ throw new MOAIDException("Create Single LogOut information FAILED.", null, e);
+ }
+
+ } finally {
+ if (is != null)
+ is.close();
+
+ }
+ } catch (Exception e) {
+ Logger.error("Error-message form can not created.", e);
+ GenericExceptionHandler(httpResp, error);
+
+ }
+ }
+
+ private void evaluateErrorTemplate(VelocityContext context, HttpServletResponse httpResp, InputStream is) throws Exception {
+ VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is ));
+ StringWriter writer = new StringWriter();
+ engine.evaluate(context, writer, "Error Template", reader);
+ httpResp.setContentType("text/html;charset=UTF-8");
+ httpResp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+
+ }
+
+ private String getStacktraceFromException(Exception ex) {
+ StringWriter errors = new StringWriter();
+ ex.printStackTrace(new PrintWriter(errors));
+ return errors.toString();
+
+ }
+
+ private Throwable extractOriginalExceptionFromProcessException(Throwable exception) {
+ Throwable returnexception = exception;
+
+ while(returnexception != null
+ && returnexception instanceof ProcessExecutionException) {
+ ProcessExecutionException procExc = (ProcessExecutionException) returnexception;
+ if (procExc.getCause() != null &&
+ procExc.getCause() instanceof TaskExecutionException) {
+ TaskExecutionException taskExc = (TaskExecutionException) procExc.getCause();
+ returnexception = taskExc.getOriginalException();
+
+ }
+ }
+
+ return returnexception;
+ }
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/AbstractProtocolModulController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/AbstractProtocolModulController.java
index cc1886324..de64ec98e 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/AbstractProtocolModulController.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/AbstractProtocolModulController.java
@@ -229,13 +229,14 @@ public abstract class AbstractProtocolModulController extends AbstractController
return;
} else {
- handleErrorNoRedirect(throwable, req, resp);
+ handleErrorNoRedirect(throwable, req, resp, true);
}
} catch (Throwable e) {
Logger.error(e);
- handleErrorNoRedirect(throwable, req, resp);
+ handleErrorNoRedirect(throwable, req, resp, true);
+
}
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java
index ed53d1a20..107212c38 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java
@@ -90,27 +90,28 @@ public class ProtocolFinalizationController extends AbstractProtocolModulControl
return;
} else {
- handleErrorNoRedirect(throwable, req, resp);
+ handleErrorNoRedirect(throwable, req, resp, true);
}
} else {
handleErrorNoRedirect(new Exception(
MOAIDMessageProvider.getInstance().getMessage("auth.26", null)),
- req, resp);
+ req, resp, false);
}
} catch (Throwable e) {
- Logger.error(e);
- handleErrorNoRedirect(e, req, resp);
+ Logger.error(e);
+
+ handleErrorNoRedirect(e, req, resp, false);
}
-
+
// receive a pending request
} else {
if (pendingReq == null) {
Logger.error("No PendingRequest with ID " + pendingRequestID + " found.!");
- handleErrorNoRedirect(new MOAIDException("auth.28", new Object[]{pendingRequestID}), req, resp);
+ handleErrorNoRedirect(new MOAIDException("auth.28", new Object[]{pendingRequestID}), req, resp, false);
return;
}
@@ -130,7 +131,7 @@ public class ProtocolFinalizationController extends AbstractProtocolModulControl
AuthenticationSession moaSession = authenticatedSessionStorage.getSession(sessionID);
if (moaSession == null) {
Logger.error("No MOASession with ID " + sessionID + " found.!");
- handleErrorNoRedirect(new MOAIDException("auth.02", new Object[]{sessionID}), req, resp);
+ handleErrorNoRedirect(new MOAIDException("auth.02", new Object[]{sessionID}), req, resp, true);
return;
}
@@ -141,7 +142,7 @@ public class ProtocolFinalizationController extends AbstractProtocolModulControl
} else {
Logger.error("MOASession oder Pending-Request are not authenticated --> Abort authentication process!");
- handleErrorNoRedirect(new MOAIDException("auth.20", null), req, resp);
+ handleErrorNoRedirect(new MOAIDException("auth.20", null), req, resp, true);
return;
}
@@ -154,7 +155,8 @@ public class ProtocolFinalizationController extends AbstractProtocolModulControl
}
//remove pending-request
- requestStorage.removePendingRequest(pendingRequestID);
+ if (pendingReq != null)
+ requestStorage.removePendingRequest(pendingReq.getRequestID());
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ErrorResponseUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ErrorResponseUtils.java
index 99ac6ba4c..8bd682421 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ErrorResponseUtils.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ErrorResponseUtils.java
@@ -27,6 +27,7 @@ import java.util.Locale;
import at.gv.egovernment.moa.id.auth.exception.BKUException;
import at.gv.egovernment.moa.id.auth.exception.MISSimpleClientException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.process.ProcessExecutionException;
import at.gv.egovernment.moa.util.Messages;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -78,7 +79,10 @@ public class ErrorResponseUtils {
} else if (throwable instanceof MOAIDException) {
MOAIDException error = (MOAIDException) throwable;
errorCode = mapInternalErrorToExternalError(error.getMessageId());
-
+
+ } else if (throwable instanceof ProcessExecutionException) {
+ errorCode = "1100";
+
} else {
errorCode = INTERNALERRORCODE;