aboutsummaryrefslogtreecommitdiff
path: root/id/server
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-02-19 10:22:11 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-02-19 10:22:11 +0100
commit18f7c6609058ed5c3bfb59c625682f4f4a53d75d (patch)
tree6081c9dd22addf5db78d754a431aae86156becfc /id/server
parent0d827d781679187d4a73e7b51510539a69a46d79 (diff)
downloadmoa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.tar.gz
moa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.tar.bz2
moa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.zip
refactor Single Sign-On authentication consents evaluator to get executed by processEngine
Diffstat (limited to 'id/server')
-rw-r--r--id/server/doc/handbook/protocol/protocol.html4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java78
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java20
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java69
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java115
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java16
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java87
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java177
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java550
-rw-r--r--id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule2
-rw-r--r--id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml20
-rw-r--r--id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml6
-rw-r--r--id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties3
-rw-r--r--id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties1
14 files changed, 627 insertions, 521 deletions
diff --git a/id/server/doc/handbook/protocol/protocol.html b/id/server/doc/handbook/protocol/protocol.html
index 6214c393c..a3a06bc6d 100644
--- a/id/server/doc/handbook/protocol/protocol.html
+++ b/id/server/doc/handbook/protocol/protocol.html
@@ -606,6 +606,10 @@ Redirect Binding</td>
<td>1109</td>
<td>Fehler beim Validieren der SZR-Gateway Response</td>
</tr>
+ <tr>
+ <td>1110</td>
+ <td>Ung&uuml;ltige Single Sign-On Session</td>
+ </tr>
</table>
<h5><a name="statuscodes_12xxx" id="allgemeines_zugangspunkte13"></a>1.3.1.3 STORK (12xxx)</h5>
<table class="configtable">
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java
index d14910319..7121935b0 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java
@@ -34,7 +34,8 @@ import java.net.URI;
import org.apache.commons.io.IOUtils;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
-import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.util.FormBuildUtils;
import at.gv.egovernment.moa.logging.Logger;
@@ -46,8 +47,6 @@ public class SendAssertionFormBuilder {
private static final String TEMPLATEBGCOLOR = "style=\"background-color: #COLOR#\"";
private static String URL = "#URL#";
- private static String MODUL = "#MODUL#";
- private static String ACTION = "#ACTION#";
private static String ID = "#ID#";
private static String OANAME = "#OAName#";
private static String CONTEXTPATH = "#CONTEXTPATH#";
@@ -56,8 +55,7 @@ public class SendAssertionFormBuilder {
private static String SERVLET = CONTEXTPATH+"/SSOSendAssertionServlet";
- private static String getTemplate() {
-
+ private static String getTemplate() {
String pathLocation;
InputStream input = null;
try {
@@ -68,12 +66,9 @@ public class SendAssertionFormBuilder {
File file = new File(new URI(pathLocation));
input = new FileInputStream(file);
- } catch (FileNotFoundException e) {
-
- Logger.warn("No LoginFormTempaltes found. Use Generic Templates from package.");
-
- pathLocation = "resources/templates/" + HTMLTEMPLATEFULL;
-
+ } catch (FileNotFoundException e) {
+ Logger.warn("No LoginFormTempaltes found. Use Generic Templates from package.");
+ pathLocation = "resources/templates/" + HTMLTEMPLATEFULL;
input = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(pathLocation);
@@ -82,48 +77,43 @@ public class SendAssertionFormBuilder {
return getTemplate(input);
- } catch (Exception e) {
+ } catch (Exception e) {
+ return null;
+
+ } finally {
try {
- input.close();
+ if (input != null)
+ input.close();
- } catch (IOException e1) {
+ } catch (IOException e) {
Logger.warn("SendAssertionTemplate inputstream can not be closed.", e);
+
}
-
- return null;
- }
-
+ }
}
private static String getTemplate(InputStream input) {
+ String template = null;
+ try {
- String template = null;
-
- try {
-
- StringWriter writer = new StringWriter();
- IOUtils.copy(input, writer);
- template = writer.toString();
- template = template.replace(URL, SERVLET);
-
- } catch (Exception e) {
- Logger.error("Failed to read template", e);
-
- } finally {
- try {
- input.close();
-
- } catch (IOException e) {
- Logger.warn("SendAssertionTemplate inputstream can not be closed.", e);
- }
- }
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(input, writer);
+ template = writer.toString();
+ template = template.replace(URL, SERVLET);
+
+ } catch (Exception e) {
+ Logger.error("Failed to read template", e);
+ }
return template;
}
- public static String buildForm(String modul, String action, String id, OAAuthParameter oaParam, String contextpath) {
+ public static String buildForm(IRequest pendingReq) {
String value = null;
+ String contextpath = pendingReq.getAuthURL();
+ IOAAuthParameters oaParam = pendingReq.getOnlineApplicationConfiguration();
+
byte[] oatemplate = oaParam.getSendAssertionTemplate();
// OA specific template requires a size of 8 bits minimum
if (oatemplate != null && oatemplate.length > 7) {
@@ -137,15 +127,7 @@ public class SendAssertionFormBuilder {
}
if(value != null) {
-// if(modul == null) {
-// modul = SAML1Protocol.PATH;
-// }
-// if(action == null) {
-// action = SAML1Protocol.GETARTIFACT;
-// }
- value = value.replace(MODUL, modul);
- value = value.replace(ACTION, action);
- value = value.replace(ID, id);
+ value = value.replace(ID, pendingReq.getRequestID());
value = value.replace(OANAME, oaParam.getFriendlyName());
if (contextpath.endsWith("/"))
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java
index 68d5ae299..559d4fd4f 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java
@@ -12,6 +12,7 @@ import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
@@ -25,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
@@ -33,6 +35,7 @@ import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.moduls.IRequestStorage;
import at.gv.egovernment.moa.id.process.api.ExecutionContext;
import at.gv.egovernment.moa.id.process.springweb.MoaIdTask;
+import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -96,6 +99,23 @@ public abstract class AbstractAuthServletTask extends MoaIdTask {
}
/**
+ * Redirect the authentication process to protocol specific finalization endpoint.
+ *
+ * @param pendingReq Actually processed protocol specific authentication request
+ * @param httpResp
+ */
+ protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) {
+ String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(),
+ AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, pendingReq.getRequestID());
+
+ httpResp.setContentType("text/html");
+ httpResp.setStatus(302);
+ httpResp.addHeader("Location", redirectURL);
+ Logger.debug("REDIRECT TO: " + redirectURL);
+
+ }
+
+ /**
* Parses the request input stream for parameters, assuming parameters are
* encoded UTF-8 (no standard exists how browsers should encode them).
*
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java
new file mode 100644
index 000000000..d64126de6
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.auth.modules;
+
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SingleSignOnConsentsModuleImpl implements AuthModule {
+
+ public static final String PARAM_SSO_CONSENTS_EVALUATION = "ssoconsentsevaluation";
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 0;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext)
+ */
+ @Override
+ public String selectProcess(ExecutionContext context) {
+ Object evaluationObj = context.get(PARAM_SSO_CONSENTS_EVALUATION);
+ if (evaluationObj != null && evaluationObj instanceof Boolean) {
+ boolean evaluateSSOConsents = (boolean) evaluationObj;
+ if (evaluateSSOConsents) {
+ return "SSOConsentsEvluationProcess";
+
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions()
+ */
+ @Override
+ public String[] getProcessDefinitions() {
+ return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml" };
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java
new file mode 100644
index 000000000..8dcb63550
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.auth.modules.internal.tasks;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.moduls.SSOManager;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * Evaluate the Single Sign-On user consent
+ *
+ * @author tlenz
+ *
+ */
+public class EvaluateSSOConsentsTaskImpl extends AbstractAuthServletTask {
+
+ private static final String PARAM_SSO_CONSENTS = "value";
+
+ @Autowired private SSOManager ssoManager;
+
+ /* (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)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ try {
+ //evaluate SSO consents flag
+ String ssoConsentsString = request.getParameter(PARAM_SSO_CONSENTS);
+ ssoConsentsString = StringEscapeUtils.escapeHtml(ssoConsentsString);
+ if (!ParamValidatorUtils.isValidUseMandate(ssoConsentsString))
+ throw new WrongParametersException("EvaluateSSOConsentsTaskImpl", PARAM_SSO_CONSENTS, null);
+
+ boolean ssoConsents = false;
+ if (MiscUtil.isNotEmpty(ssoConsentsString))
+ ssoConsents = Boolean.parseBoolean(ssoConsentsString);
+
+ //perform default task initialization
+ defaultTaskInitialization(request, executionContext);
+
+ //check SSO session cookie and MOASession object
+ String ssoId = ssoManager.getSSOSessionID(request);
+ boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq);
+ if (!(isValidSSOSession && moasession.isAuthenticated() )) {
+ Logger.info("Single Sign-On consents evaluator found NO valid SSO session. Stopping authentication process ...");
+ throw new AuthenticationException("auth.30", null);
+
+ }
+
+ //Log consents evaluator event to revisionslog
+ revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_FINISHED, String.valueOf(ssoConsents));
+
+ //user allow single sign-on authentication
+ if (ssoConsents) {
+ //authenticate pending-request
+ pendingReq.setAuthenticated(true);
+
+ //store pending-request
+ requestStoreage.storePendingRequest(pendingReq);
+
+ //redirect to auth. protocol finalization
+ performRedirectToProtocolFinialization(pendingReq, response);
+
+ } else {
+ //user deny single sign-on authentication
+ throw new AuthenticationException("auth.21", new Object[] {});
+
+ }
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (Exception e) {
+ Logger.warn("FinalizeAuthenticationTask has an internal error", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java
index 4fd43b6ba..d1d2cdca8 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java
@@ -28,14 +28,12 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
-import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
import at.gv.egovernment.moa.id.moduls.RequestImpl;
import at.gv.egovernment.moa.id.process.api.ExecutionContext;
-import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -93,7 +91,6 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask {
}
-
//set MOASession to authenticated and store MOASession
moasession.setAuthenticated(true);
String newMOASessionID = authenticatedSessionStorage.changeSessionID(moasession);
@@ -103,16 +100,9 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask {
pendingReq.setAuthenticated(true);
requestStoreage.storePendingRequest(pendingReq);
- Logger.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
-
- String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(),
- AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, pendingReq.getRequestID());
-
- response.setContentType("text/html");
- response.setStatus(302);
- response.addHeader("Location", redirectURL);
- Logger.debug("REDIRECT TO: " + redirectURL);
-
+ Logger.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
+ performRedirectToProtocolFinialization(pendingReq, response);
+
} catch (MOAIDException e) {
throw new TaskExecutionException(pendingReq, e.getMessage(), e);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java
new file mode 100644
index 000000000..f9f121520
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.auth.modules.internal.tasks;
+
+import java.io.PrintWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.builder.SendAssertionFormBuilder;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * Build a Single Sign-On consents evaluator form
+ *
+ * @author tlenz
+ *
+ */
+public class GenerateSSOConsentEvaluatorFrameTask extends AbstractAuthServletTask {
+
+ /* (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)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ try {
+ //perform default task initialization
+ defaultTaskInitialization(request, executionContext);
+
+ //set authenticated flag to false, because user consents is required
+ pendingReq.setAuthenticated(false);
+
+ //build consents evaluator form
+ String form = SendAssertionFormBuilder.buildForm(pendingReq);
+
+ //store pending request
+ requestStoreage.storePendingRequest(pendingReq);
+
+ //Log consents evaluator event to revisionslog
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(),
+ pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_START);
+
+ //write form to response object
+ response.setContentType("text/html;charset=UTF-8");
+ PrintWriter out = new PrintWriter(response.getOutputStream());
+ out.print(form);
+ out.flush();
+
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (Exception e) {
+ Logger.warn("FinalizeAuthenticationTask has an internal error", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java
deleted file mode 100644
index 4c895e387..000000000
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java
+++ /dev/null
@@ -1,177 +0,0 @@
-///*******************************************************************************
-// * Copyright 2014 Federal Chancellery Austria
-// * MOA-ID has been developed in a cooperation between BRZ, the Federal
-// * Chancellery Austria - ICT staff unit, and Graz University of Technology.
-// *
-// * Licensed under the EUPL, Version 1.1 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:
-// * http://www.osor.eu/eupl/
-// *
-// * 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.egovernment.moa.id.auth.servlet;
-//
-//import java.io.IOException;
-//
-//import javax.servlet.ServletException;
-//import javax.servlet.http.HttpServletRequest;
-//import javax.servlet.http.HttpServletResponse;
-//
-//import org.apache.commons.lang.StringEscapeUtils;
-//
-//import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
-//import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
-//import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
-//import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
-//import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
-//import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
-//import at.gv.egovernment.moa.id.moduls.IRequest;
-//import at.gv.egovernment.moa.id.moduls.RequestStorage;
-//import at.gv.egovernment.moa.id.moduls.SSOManager;
-//import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
-//import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
-//import at.gv.egovernment.moa.logging.Logger;
-//import at.gv.egovernment.moa.util.MiscUtil;
-//
-//public class SSOSendAssertionServlet extends AuthServlet{
-//
-// private static final long serialVersionUID = 1L;
-//
-// private static final String PARAM = "value";
-// private static final String MODULE = "mod";
-// private static final String ACTION = "action";
-// private static final String ID = "identifier";
-//
-// protected void doPost(HttpServletRequest req, HttpServletResponse resp)
-// throws ServletException, IOException {
-//
-// String id = null;
-// Logger.debug("Receive " + SSOSendAssertionServlet.class + " Request");
-// try {
-//
-// Object idObject = req.getParameter(ID);
-//
-// if (idObject != null && (idObject instanceof String)) {
-// id = (String) idObject;
-// }
-//
-// String value = req.getParameter(PARAM);
-// value = StringEscapeUtils.escapeHtml(value);
-// if (!ParamValidatorUtils.isValidUseMandate(value))
-// throw new WrongParametersException("SSOSendAssertionServlet", PARAM, null);
-//
-// //get module and action
-// Object moduleObject = req.getParameter(MODULE);
-// String module = null;
-// if (moduleObject != null && (moduleObject instanceof String)) {
-// module = (String) moduleObject;
-// }
-//
-//
-// Object actionObject = req.getParameter(ACTION);
-// String action = null;
-// if (actionObject != null && (actionObject instanceof String)) {
-// action = (String) actionObject;
-// }
-//
-// if (MiscUtil.isEmpty(module) || MiscUtil.isEmpty(action) || MiscUtil.isEmpty(id)) {
-// Logger.warn("No Moduel or Action parameter received!");
-// throw new WrongParametersException("Module or Action is empty", "", "auth.10");
-// }
-//
-//
-// SSOManager ssomanager = SSOManager.getInstance();
-// //get SSO Cookie for Request
-// String ssoId = ssomanager.getSSOSessionID(req);
-//
-// //check SSO session
-// if (ssoId != null) {
-// String correspondingMOASession = ssomanager.existsOldSSOSession(ssoId);
-//
-// if (correspondingMOASession != null) {
-// Logger.warn("Request sends an old SSO Session ID("+ssoId+")! " +
-// "Invalidate the corresponding MOASession with ID="+ correspondingMOASession);
-//
-//
-// AuthenticationSessionStoreage.destroySession(correspondingMOASession);
-//
-// ssomanager.deleteSSOSessionID(req, resp);
-// }
-// }
-//
-// boolean isValidSSOSession = ssomanager.isValidSSOSession(ssoId, null);
-//
-// String moaSessionID = null;
-//
-// if (isValidSSOSession) {
-//
-//
-// //check UseMandate flag
-// String valueString = null;;
-// if ((value != null) && (value.compareTo("") != 0)) {
-// valueString = value;
-// } else {
-// valueString = "false";
-// }
-//
-// if (valueString.compareToIgnoreCase("true") == 0) {
-// moaSessionID = AuthenticationSessionStoreage.getMOASessionSSOID(ssoId);
-// AuthenticationSession moasession = AuthenticationSessionStoreage.getSession(moaSessionID);
-// AuthenticationSessionStoreage.setAuthenticated(moaSessionID, true);
-//
-// //log event
-// //String pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
-// IRequest pendingReq = RequestStorage.getPendingRequest(id);
-// MOAReversionLogger.getInstance().logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_FINISHED);
-//
-// //TODO: only for development!!!!!!!
-//// String redirectURL = new DataURLBuilder().buildDataURL(moasession.getAuthURL(),
-//// ModulUtils.buildAuthURL(module, action, id), "");
-//
-// String redirectURL = "Remove commants in Class:SSOSendAssertionServlet Line:141";
-//
-// resp.setContentType("text/html");
-// resp.setStatus(302);
-//
-//
-// resp.addHeader("Location", redirectURL);
-// Logger.debug("REDIRECT TO: " + redirectURL);
-//
-// }
-//
-// else {
-// throw new AuthenticationException("auth.21", new Object[] {});
-// }
-//
-// } else {
-// handleError("SSO Session is not valid", null, req, resp, id);
-// }
-//
-//
-// } catch (MOADatabaseException e) {
-// handleError("SSO Session is not found", e, req, resp, id);
-//
-// } catch (WrongParametersException e) {
-// handleError("Parameter is not valid", e, req, resp, id);
-//
-// } catch (AuthenticationException e) {
-// handleError(e.getMessage(), e, req, resp, id);
-//
-// } catch (Exception e) {
-// Logger.error("SSOSendAssertion has an interal Error.", e);
-// }
-//
-// }
-//
-//}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
index 4131e49fc..7863c684e 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
@@ -23,7 +23,6 @@
package at.gv.egovernment.moa.id.moduls;
import java.io.IOException;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
@@ -53,6 +52,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionExtensions;
import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.SingleSignOnConsentsModuleImpl;
import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
import at.gv.egovernment.moa.id.auth.modules.registration.ModuleRegistration;
import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore;
@@ -101,52 +101,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {
public AuthenticationManager() {
}
-
- /**
- * Checks if a authenticated MOASession already exists and if {protocolRequest} is authenticated
- *
- * @param protocolRequest Authentication request which is actually in process
- * @param moaSession MOASession with authentication information or null if no MOASession exists
- *
- * @return true if session is already authenticated, otherwise false
- * @throws MOAIDException
- */
- private boolean tryPerformAuthentication(RequestImpl protocolRequest, AuthenticationSession moaSession) {
-
- //if no MOASession exist -> authentication is required
- if (moaSession == null) {
- return false;
- } else {
- //if MOASession is Found but not authenticated --> authentication is required
- if (!moaSession.isAuthenticated()) {
- return false;
- }
-
- //if MOASession is already authenticated and protocol-request is authenticated
- // --> no authentication is required any more
- else if (moaSession.isAuthenticated() && protocolRequest.isAuthenticated()) {
- return true;
-
- // if MOASession is authenticated and SSO is allowed --> authenticate pendingRequest
- } else if (!protocolRequest.isAuthenticated()
- && moaSession.isAuthenticated() && protocolRequest.needSingleSignOnFunctionality()) {
- Logger.debug("Found active MOASession and SSO is allowed --> pendingRequest is authenticted");
- protocolRequest.setAuthenticated(true);
- protocolRequest.setMOASessionIdentifier(moaSession.getSessionID());
- return true;
-
- }
-
- // force authentication as backup solution
- else {
- Logger.warn("Authentication-required check find an unsuspected state --> force authentication");
- return false;
-
- }
- }
- }
-
public void performSingleLogOut(HttpServletRequest httpReq,
HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq) throws MOAIDException {
performSingleLogOut(httpReq, httpResp, session, pvpReq, null);
@@ -159,163 +114,6 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
-
- private void performSingleLogOut(HttpServletRequest httpReq,
- HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq, String authURL) throws MOAIDException {
- String pvpSLOIssuer = null;
- String inboundRelayState = null;
-
- if (pvpReq != null) {
- MOARequest samlReq = (MOARequest) pvpReq.getRequest();
- LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest();
- pvpSLOIssuer = logOutReq.getIssuer().getValue();
- inboundRelayState = samlReq.getRelayState();
-
- }
-
- //store active OAs to SLOContaine
- List<OASessionStore> dbOAs = authenticatedSessionStore.getAllActiveOAFromMOASession(session);
- List<InterfederationSessionStore> dbIDPs = authenticatedSessionStore.getAllActiveIDPsFromMOASession(session);
- SLOInformationContainer sloContainer = new SLOInformationContainer();
- sloContainer.setSloRequest(pvpReq);
- sloContainer.parseActiveIDPs(dbIDPs, pvpSLOIssuer);
- sloContainer.parseActiveOAs(dbOAs, pvpSLOIssuer);
-
- //terminate MOASession
- try {
- authenticatedSessionStore.destroySession(session.getSessionID());
- ssoManager.deleteSSOSessionID(httpReq, httpResp);
-
- } catch (MOADatabaseException e) {
- Logger.warn("Delete MOASession FAILED.");
- sloContainer.putFailedOA(pvpReq.getAuthURL());
-
- }
-
- //start service provider back channel logout process
- Iterator<String> nextOAInterator = sloContainer.getNextBackChannelOA();
- while (nextOAInterator.hasNext()) {
- SLOInformationImpl sloDescr = sloContainer.getBackChannelOASessionDescripten(nextOAInterator.next());
- LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(sloDescr);
-
- try {
- List<XMLObject> soapResp = MOASAMLSOAPClient.send(sloDescr.getServiceURL(), sloReq);
-
- LogoutResponse sloResp = null;
- for (XMLObject el : soapResp) {
- if (el instanceof LogoutResponse)
- sloResp = (LogoutResponse) el;
- }
-
- if (sloResp == null) {
- Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
- + " FAILED. NO LogOut response received.");
- sloContainer.putFailedOA(sloReq.getIssuer().getValue());
-
- } else {
- SAMLVerificationEngine engine = new SAMLVerificationEngine();
- engine.verifySLOResponse(sloResp,
- TrustEngineFactory.getSignatureKnownKeysTrustEngine());
-
- }
-
- SingleLogOutBuilder.checkStatusCode(sloContainer, sloResp);
-
- } catch (SOAPException e) {
- Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
- + " FAILED.", e);
- sloContainer.putFailedOA(sloReq.getIssuer().getValue());
-
- } catch (SecurityException | InvalidProtocolRequestException e) {
- Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
- + " FAILED.", e);
- sloContainer.putFailedOA(sloReq.getIssuer().getValue());
-
- }
- }
-
- //start service provider front channel logout process
- try {
- if (sloContainer.hasFrontChannelOA()) {
- String relayState = Random.nextRandom();
-
- Collection<Entry<String, SLOInformationImpl>> sloDescr = sloContainer.getFrontChannelOASessionDescriptions();
- List<String> sloReqList = new ArrayList<String>();
- for (Entry<String, SLOInformationImpl> el : sloDescr) {
- LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(el.getValue());
- try {
- sloReqList.add(SingleLogOutBuilder.getFrontChannelSLOMessageURL(el.getValue().getServiceURL(), el.getValue().getBinding(),
- sloReq, httpReq, httpResp, relayState));
-
- } catch (Exception e) {
- Logger.warn("Failed to build SLO request for OA:" + el.getKey());
- sloContainer.putFailedOA(el.getKey());
-
- }
- }
-
- //put SLO process-information into transaction storage
- transactionStorage.put(relayState, sloContainer);
-
- if (MiscUtil.isEmpty(authURL))
- authURL = pvpReq.getAuthURL();
-
- String timeOutURL = authURL
- + "/idpSingleLogout"
- + "?restart=" + relayState;
-
- VelocityContext context = new VelocityContext();
- context.put("redirectURLs", sloReqList);
- context.put("timeoutURL", timeOutURL);
- context.put("timeout", SLOTIMEOUT);
- ssoManager.printSingleLogOutInfo(context, httpResp);
-
-
- } else {
- if (pvpReq != null) {
- //send SLO response to SLO request issuer
- SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq);
- LogoutResponse message = SingleLogOutBuilder.buildSLOResponseMessage(sloService, pvpReq, sloContainer.getSloFailedOAs());
- SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState);
-
- } else {
- //print SLO information directly
- VelocityContext context = new VelocityContext();
- if (sloContainer.getSloFailedOAs() == null ||
- sloContainer.getSloFailedOAs().size() == 0)
- context.put("successMsg",
- MOAIDMessageProvider.getInstance().getMessage("slo.00", null));
- else
- context.put("errorMsg",
- MOAIDMessageProvider.getInstance().getMessage("slo.01", null));
- ssoManager.printSingleLogOutInfo(context, httpResp);
-
- }
-
- }
-
- } catch (MOADatabaseException e) {
- Logger.error("MOA AssertionDatabase ERROR", e);
- if (pvpReq != null) {
- SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq);
- LogoutResponse message = SingleLogOutBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI);
- SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState);
-
- }else {
- //print SLO information directly
- VelocityContext context = new VelocityContext();
- context.put("errorMsg",
- MOAIDMessageProvider.getInstance().getMessage("slo.01", null));
- ssoManager.printSingleLogOutInfo(context, httpResp);
-
- }
-
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
public void performOnlyIDPLogOut(HttpServletRequest request,
HttpServletResponse response, String moaSessionID) {
Logger.info("Logout");
@@ -387,7 +185,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {
//check if interfederation IDP is requested
ssoManager.checkInterfederationIsRequested(httpReq, httpResp, pendingReq);
- //check SSO session
+ //check if SSO session cookie is already used
if (ssoId != null) {
String correspondingMOASession = ssoManager.existsOldSSOSession(ssoId);
@@ -402,21 +200,22 @@ public class AuthenticationManager extends MOAIDAuthConstants {
ssoManager.deleteSSOSessionID(httpReq, httpResp);
}
}
-
+
+ //check if SSO Session is valid
+ boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq);
+
// check if Service-Provider allows SSO sessions
IOAAuthParameters oaParam = pendingReq.getOnlineApplicationConfiguration();
- boolean useSSOOA = oaParam.useSSO() || oaParam.isInderfederationIDP();
+ boolean useSSOOA = oaParam.useSSO() || oaParam.isInderfederationIDP();
revisionsLogger.logEvent(oaParam,
pendingReq, MOAIDEventConstants.AUTHPROCESS_SERVICEPROVIDER, pendingReq.getOAURL());
//if a legacy request is used SSO should not be allowed in case of mandate authentication
boolean isUseMandateRequested = LegacyHelper.isUseMandateRequested(httpReq);
-
- //check if SSO Session is valid
- boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq);
-
+
//check if SSO is allowed for the actually executed request
+ //INFO: Actually, useMandate disables SSO functionality!!!!!
boolean isSSOAllowed = (useSSOOA && !isUseMandateRequested);
pendingReq.setNeedSingleSignOnFunctionality(isSSOAllowed);
@@ -428,6 +227,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {
if (moaSession == null)
Logger.info("No MOASession FOUND with provided SSO-Cookie.");
+
else {
Logger.debug("Found authenticated MOASession with provided SSO-Cookie.");
revisionsLogger.logEvent(oaParam, pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO);
@@ -436,25 +236,22 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
//check if session is already authenticated
- boolean tryperform = tryPerformAuthentication((RequestImpl) pendingReq, moaSession);
-
- //perfom SSO-Consents question if it it required
- if (tryperform && isSSOAllowed && oaParam.useSSOQuestion()) {
- sendTransmitAssertionQuestion(httpReq, httpResp, pendingReq, oaParam);
- return null;
-
- }
-
+ boolean isSessionAuthenticated = tryPerformAuthentication((RequestImpl) pendingReq, moaSession);
+
//force new authentication authentication process
if (pendingReq.forceAuth()) {
startAuthenticationProcess(httpReq, httpResp, pendingReq);
return null;
-
+
+ //perform SSO-Consents evaluation if it it required
+ } else if (isSessionAuthenticated && oaParam.useSSOQuestion()) {
+ sendSingleSignOnConsentsEvaluation(httpReq, httpResp, pendingReq);
+ return null;
+
} else if (pendingReq.isPassiv()) {
- if (tryperform) {
+ if (isSessionAuthenticated) {
// Passive authentication ok!
- revisionsLogger.logEvent(oaParam,
- pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED);
+ revisionsLogger.logEvent(oaParam, pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED);
return moaSession;
} else {
@@ -462,7 +259,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
} else {
- if (tryperform) {
+ if (isSessionAuthenticated) {
// Is authenticated .. proceed
revisionsLogger.logEvent(oaParam,
pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED);
@@ -476,6 +273,50 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
}
+ /**
+ * Checks if a authenticated MOASession already exists and if {protocolRequest} is authenticated
+ *
+ * @param protocolRequest Authentication request which is actually in process
+ * @param moaSession MOASession with authentication information or null if no active MOASession exists
+ *
+ * @return true if session is already authenticated, otherwise false
+ * @throws MOAIDException
+ */
+ private boolean tryPerformAuthentication(RequestImpl protocolRequest, AuthenticationSession moaSession) {
+
+ //if no MOASession exist -> authentication is required
+ if (moaSession == null) {
+ return false;
+
+ } else {
+ //if MOASession is Found but not authenticated --> authentication is required
+ if (!moaSession.isAuthenticated()) {
+ return false;
+ }
+
+ //if MOASession is already authenticated and protocol-request is authenticated
+ // --> no authentication is required any more
+ else if (moaSession.isAuthenticated() && protocolRequest.isAuthenticated()) {
+ return true;
+
+ // if MOASession is authenticated and SSO is allowed --> authenticate pendingRequest
+ } else if (!protocolRequest.isAuthenticated()
+ && moaSession.isAuthenticated() && protocolRequest.needSingleSignOnFunctionality()) {
+ Logger.debug("Found active MOASession and SSO is allowed --> pendingRequest is authenticted");
+ protocolRequest.setAuthenticated(true);
+ protocolRequest.setMOASessionIdentifier(moaSession.getSessionID());
+ return true;
+
+ }
+
+ // force authentication as backup solution
+ else {
+ Logger.warn("Authentication-required check find an unsuspected state --> force authentication");
+ return false;
+
+ }
+ }
+ }
private void startAuthenticationProcess(HttpServletRequest httpReq,
HttpServletResponse httpResp, RequestImpl pendingReq)
@@ -505,37 +346,64 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
//create authentication process execution context
- try {
- // create execution context
+ ExecutionContext executionContext = new ExecutionContextImpl();
+
+ executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_INTERFEDERATION_ENTITYID,
+ MiscUtil.isNotEmpty(
+ pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class)));
+
+ boolean leagacyMode = (legacyallowed && legacyparamavail);
+ executionContext.put("isLegacyRequest", leagacyMode);
+ executionContext.put("performBKUSelection", !leagacyMode
+ && MiscUtil.isEmpty(pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class)));
+
+ //add leagcy parameters to context
+ if (leagacyMode) {
+ Enumeration<String> reqParamNames = httpReq.getParameterNames();
+ while(reqParamNames.hasMoreElements()) {
+ String paramName = reqParamNames.nextElement();
+ if (MiscUtil.isNotEmpty(paramName) &&
+ MOAIDAuthConstants.LEGACYPARAMETERWHITELIST.contains(paramName))
+ executionContext.put(paramName, httpReq.getParameter(paramName));
+
+ }
+ }
+
+ //start process engine
+ startProcessEngine(pendingReq, executionContext);
+
+ }
+
+ private void sendSingleSignOnConsentsEvaluation(HttpServletRequest request,
+ HttpServletResponse response, RequestImpl pendingReq)
+ throws ServletException, IOException, MOAIDException {
+
+ Logger.info("Start SSO user-consents evaluation ...");
+
+ //set authenticated flag to false, because user consents is required
+ pendingReq.setAuthenticated(false);
+
+ //create execution context
ExecutionContext executionContext = new ExecutionContextImpl();
- executionContext.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());
- executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_INTERFEDERATION_ENTITYID,
- MiscUtil.isNotEmpty(
- pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class)));
+ executionContext.put(SingleSignOnConsentsModuleImpl.PARAM_SSO_CONSENTS_EVALUATION, true);
- boolean leagacyMode = (legacyallowed && legacyparamavail);
- executionContext.put("isLegacyRequest", leagacyMode);
- executionContext.put("performBKUSelection", !leagacyMode
- && MiscUtil.isEmpty(pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class)));
-
- //add leagcy parameters to context
- if (leagacyMode) {
- Enumeration<String> reqParamNames = httpReq.getParameterNames();
- while(reqParamNames.hasMoreElements()) {
- String paramName = reqParamNames.nextElement();
- if (MiscUtil.isNotEmpty(paramName) &&
- MOAIDAuthConstants.LEGACYPARAMETERWHITELIST.contains(paramName))
- executionContext.put(paramName, httpReq.getParameter(paramName));
-
- }
- }
+ //start process engine
+ startProcessEngine(pendingReq, executionContext);
+
+ }
+
+ private void startProcessEngine(RequestImpl pendingReq, ExecutionContext executionContext) throws MOAIDException {
+ try {
+ //put pending-request ID on execurtionContext
+ executionContext.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());
+
// create process instance
String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext);
if (processDefinitionId == null) {
- Logger.warn("No suitable process found for SessionID " + moasession.getSessionID() );
+ Logger.warn("No suitable process found for SessionID " + pendingReq.getRequestID() );
throw new MOAIDException("process.02",new Object[] {
- moasession.getSessionID()});
+ pendingReq.getRequestID()});
}
String processInstanceId = processEngine.createProcessInstance(processDefinitionId, executionContext);
@@ -545,18 +413,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {
//store pending-request
requestStoreage.storePendingRequest(pendingReq);
-
-
- // make sure moa session has been persisted before running the process
- try {
- authenticatedSessionStore.storeSession(moasession);
-
- } catch (MOADatabaseException e) {
- Logger.error("Database Error! MOASession is not stored!");
- throw new MOAIDException("init.04", new Object[] {
- moasession.getSessionID()});
- }
-
+
// start process
processEngine.start(processInstanceId);
@@ -572,32 +429,163 @@ public class AuthenticationManager extends MOAIDAuthConstants {
}
}
- throw new MOAIDException("process.01", new Object[] { pendingReq.getProcessInstanceId(), moasession }, e);
- }
+ throw new MOAIDException("process.01", new Object[] { pendingReq.getProcessInstanceId(), pendingReq.getRequestID() }, e);
+ }
}
-
- private void sendTransmitAssertionQuestion(HttpServletRequest request,
- HttpServletResponse response, IRequest target, IOAAuthParameters oaParam)
- throws ServletException, IOException, MOAIDException {
-
- //TODO: change to process management version!!!!
+
+ private void performSingleLogOut(HttpServletRequest httpReq,
+ HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq, String authURL) throws MOAIDException {
+ String pvpSLOIssuer = null;
+ String inboundRelayState = null;
- //set authenticated flag to false, because user consents is required
- target.setAuthenticated(false);
+ if (pvpReq != null) {
+ MOARequest samlReq = (MOARequest) pvpReq.getRequest();
+ LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest();
+ pvpSLOIssuer = logOutReq.getIssuer().getValue();
+ inboundRelayState = samlReq.getRelayState();
+
+ }
+ //store active OAs to SLOContaine
+ List<OASessionStore> dbOAs = authenticatedSessionStore.getAllActiveOAFromMOASession(session);
+ List<InterfederationSessionStore> dbIDPs = authenticatedSessionStore.getAllActiveIDPsFromMOASession(session);
+ SLOInformationContainer sloContainer = new SLOInformationContainer();
+ sloContainer.setSloRequest(pvpReq);
+ sloContainer.parseActiveIDPs(dbIDPs, pvpSLOIssuer);
+ sloContainer.parseActiveOAs(dbOAs, pvpSLOIssuer);
+
+ //terminate MOASession
+ try {
+ authenticatedSessionStore.destroySession(session.getSessionID());
+ ssoManager.deleteSSOSessionID(httpReq, httpResp);
-// String form = SendAssertionFormBuilder.buildForm(target.requestedModule(),
-// target.requestedAction(), target.getRequestID(), oaParam,
-// target.getAuthURL());
-
- String form =null;
+ } catch (MOADatabaseException e) {
+ Logger.warn("Delete MOASession FAILED.");
+ sloContainer.putFailedOA(pvpReq.getAuthURL());
- revisionsLogger.logEvent(target.getOnlineApplicationConfiguration(),
- target, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_START);
+ }
+
+ //start service provider back channel logout process
+ Iterator<String> nextOAInterator = sloContainer.getNextBackChannelOA();
+ while (nextOAInterator.hasNext()) {
+ SLOInformationImpl sloDescr = sloContainer.getBackChannelOASessionDescripten(nextOAInterator.next());
+ LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(sloDescr);
+
+ try {
+ List<XMLObject> soapResp = MOASAMLSOAPClient.send(sloDescr.getServiceURL(), sloReq);
+
+ LogoutResponse sloResp = null;
+ for (XMLObject el : soapResp) {
+ if (el instanceof LogoutResponse)
+ sloResp = (LogoutResponse) el;
+ }
+
+ if (sloResp == null) {
+ Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
+ + " FAILED. NO LogOut response received.");
+ sloContainer.putFailedOA(sloReq.getIssuer().getValue());
+
+ } else {
+ SAMLVerificationEngine engine = new SAMLVerificationEngine();
+ engine.verifySLOResponse(sloResp,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine());
+
+ }
+
+ SingleLogOutBuilder.checkStatusCode(sloContainer, sloResp);
+
+ } catch (SOAPException e) {
+ Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
+ + " FAILED.", e);
+ sloContainer.putFailedOA(sloReq.getIssuer().getValue());
+
+ } catch (SecurityException | InvalidProtocolRequestException e) {
+ Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue()
+ + " FAILED.", e);
+ sloContainer.putFailedOA(sloReq.getIssuer().getValue());
+
+ }
+ }
+
+ //start service provider front channel logout process
+ try {
+ if (sloContainer.hasFrontChannelOA()) {
+ String relayState = Random.nextRandom();
+
+ Collection<Entry<String, SLOInformationImpl>> sloDescr = sloContainer.getFrontChannelOASessionDescriptions();
+ List<String> sloReqList = new ArrayList<String>();
+ for (Entry<String, SLOInformationImpl> el : sloDescr) {
+ LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(el.getValue());
+ try {
+ sloReqList.add(SingleLogOutBuilder.getFrontChannelSLOMessageURL(el.getValue().getServiceURL(), el.getValue().getBinding(),
+ sloReq, httpReq, httpResp, relayState));
+
+ } catch (Exception e) {
+ Logger.warn("Failed to build SLO request for OA:" + el.getKey());
+ sloContainer.putFailedOA(el.getKey());
+
+ }
+ }
+
+ //put SLO process-information into transaction storage
+ transactionStorage.put(relayState, sloContainer);
+
+ if (MiscUtil.isEmpty(authURL))
+ authURL = pvpReq.getAuthURL();
+
+ String timeOutURL = authURL
+ + "/idpSingleLogout"
+ + "?restart=" + relayState;
+
+ VelocityContext context = new VelocityContext();
+ context.put("redirectURLs", sloReqList);
+ context.put("timeoutURL", timeOutURL);
+ context.put("timeout", SLOTIMEOUT);
+ ssoManager.printSingleLogOutInfo(context, httpResp);
+
+
+ } else {
+ if (pvpReq != null) {
+ //send SLO response to SLO request issuer
+ SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq);
+ LogoutResponse message = SingleLogOutBuilder.buildSLOResponseMessage(sloService, pvpReq, sloContainer.getSloFailedOAs());
+ SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState);
+
+ } else {
+ //print SLO information directly
+ VelocityContext context = new VelocityContext();
+ if (sloContainer.getSloFailedOAs() == null ||
+ sloContainer.getSloFailedOAs().size() == 0)
+ context.put("successMsg",
+ MOAIDMessageProvider.getInstance().getMessage("slo.00", null));
+ else
+ context.put("errorMsg",
+ MOAIDMessageProvider.getInstance().getMessage("slo.01", null));
+ ssoManager.printSingleLogOutInfo(context, httpResp);
+
+ }
+
+ }
+
+ } catch (MOADatabaseException e) {
+ Logger.error("MOA AssertionDatabase ERROR", e);
+ if (pvpReq != null) {
+ SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq);
+ LogoutResponse message = SingleLogOutBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI);
+ SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState);
+
+ }else {
+ //print SLO information directly
+ VelocityContext context = new VelocityContext();
+ context.put("errorMsg",
+ MOAIDMessageProvider.getInstance().getMessage("slo.01", null));
+ ssoManager.printSingleLogOutInfo(context, httpResp);
+
+ }
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = new PrintWriter(response.getOutputStream());
- out.print(form);
- out.flush();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
}
diff --git a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule
index 7e2315fd7..5116c2a08 100644
--- a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule
+++ b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule
@@ -1,2 +1,2 @@
-# The default moaid process
at.gv.egovernment.moa.id.auth.modules.BKUSelectionModuleImpl
+at.gv.egovernment.moa.id.auth.modules.SingleSignOnConsentsModuleImpl \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml
new file mode 100644
index 000000000..a58ad8ac4
--- /dev/null
+++ b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pd:ProcessDefinition id="SSOConsentsEvluationProcess" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
+
+<!--
+ - National authentication with Austrian Citizen Card and mobile signature with our without mandate.
+ - Legacy authentication for foreign citizens using MOCCA supported signature cards.
+-->
+ <pd:Task id="initializeSSOConsentEvaluator" class="GenerateSSOConsentEvaluatorFrameTask"/>
+ <pd:Task id="evaluateSSOConsents" class="EvaluateSSOConsentsTaskImpl" async="true"/>
+
+ <!-- Process is triggered either by GenerateIFrameTemplateServlet (upon bku selection) or by AuthenticationManager (upon legacy authentication start using legacy parameters. -->
+ <pd:StartEvent id="start" />
+
+ <pd:Transition from="start" to="initializeSSOConsentEvaluator" />
+ <pd:Transition from="initializeSSOConsentEvaluator" to="evaluateSSOConsents" />
+ <pd:Transition from="evaluateSSOConsents" to="end" />
+
+ <pd:EndEvent id="end" />
+
+</pd:ProcessDefinition>
diff --git a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml
index 82579977c..dcaeb42c3 100644
--- a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml
+++ b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml
@@ -61,4 +61,10 @@
<bean id="ReceiveInterfederationResponseTask"
class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.ReceiveInterfederationResponseTask"/>
+ <bean id="GenerateSSOConsentEvaluatorFrameTask"
+ class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GenerateSSOConsentEvaluatorFrameTask"/>
+
+ <bean id="EvaluateSSOConsentsTaskImpl"
+ class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.EvaluateSSOConsentsTaskImpl"/>
+
</beans> \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
index 8329db941..92f4c1fa2 100644
--- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
+++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
@@ -37,7 +37,7 @@ auth.16=Fehler bei Abarbeitung der Vollmacht in "{0}"
auth.17=Vollmachtenmodus f\u00FCr nicht-\u00F6ffentlichen Bereich wird nicht unterst\u00FCtzt.
auth.18=Keine MOASessionID vorhanden
auth.19=Die Authentifizierung kann nicht passiv durchgef\u00FChrt werden.
-auth.20=No valid MOA session found. Authentification process is abourted.
+auth.20=No valid MOA session found. Authentication process is aborted.
auth.21=Der Anmeldevorgang wurde durch den Benutzer abgebrochen.
auth.22=Das Protokoll {0} ist deaktiviert.
auth.23=Das BKU-Selektion Template entspricht nicht der Spezifikation von MOA-ID 2.x.
@@ -47,6 +47,7 @@ auth.26=SessionID unbekannt.
auth.27=Federated authentication FAILED! Assertion from {0} IDP is not valid.
auth.28=Transaktion {0} kann nicht weitergef\u00FChrt werden. Wahrscheinlich wurde ein TimeOut erreicht.
auth.29=Federated authentication FAILED! Can not build authentication request for IDP {0}
+auth.30=No valid Single Sign-On session found. Authentication process is aborted.
init.00=MOA ID Authentisierung wurde erfolgreich gestartet
init.01=Fehler beim Aktivieren des IAIK-JCE/JSSE/JDK1.3 Workaround\: SSL ist m\u00F6glicherweise nicht verf\u00FCgbar
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties
index a8583d945..0b00b2d29 100644
--- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties
+++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties
@@ -27,6 +27,7 @@ auth.26=1100
auth.27=4401
auth.28=1100
auth.29=4401
+auth.30=1110
init.00=9199
init.01=9199