summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
commit759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f (patch)
tree2132024fc058b1ef5338bf50df575a3244cc3f9f /eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth
parent4f15bdc45b08724d20c66c9fd74ea6a43a03c32f (diff)
downloadEAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.gz
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.bz2
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.zip
common EGIZ code-style refactoring
Diffstat (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java704
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java414
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java1443
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java302
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java312
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java516
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java453
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java360
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java479
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java290
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java992
11 files changed, 3188 insertions, 3077 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
index 4cefcd8d..7a967d3f 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * 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.
+/*
+ * 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:
+ * 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.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.auth;
import java.io.IOException;
@@ -31,340 +24,371 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.text.StringEscapeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IspConfiguration;
import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
-import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.ISsoManager;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafSsoException;
import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.auth.modules.ModuleRegistration;
import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
-import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
public abstract class AbstractAuthenticationManager implements IAuthenticationManager {
- private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationManager.class);
-
- private static List<String> reqParameterWhiteListeForModules = new ArrayList<String>();
- private static List<String> reqHeaderWhiteListeForModules = new ArrayList<String>();
-
- public static final String MOA_SESSION = "MoaAuthenticationSession";
- public static final String MOA_AUTHENTICATED = "MoaAuthenticated";
-
- public static final int SLOTIMEOUT = 30 * 1000; //30 sec
-
- @Autowired(required=true) protected IConfiguration authConfig;
- @Autowired(required=true) private ProcessEngine processEngine;
- @Autowired(required=true) private IRequestStorage requestStoreage;
- @Autowired(required=true) protected IRevisionLogger revisionsLogger;
- @Autowired(required=false) protected ISSOManager ssoManager;
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addParameterNameToWhiteList(java.lang.String)
- */
- @Override
- public final void addParameterNameToWhiteList(String httpReqParam) {
- if (StringUtils.isNotEmpty(httpReqParam))
- reqParameterWhiteListeForModules.add(httpReqParam);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.String)
- */
- @Override
- public final void addHeaderNameToWhiteList(String httpReqParam) {
- if (StringUtils.isNotEmpty(httpReqParam))
- reqHeaderWhiteListeForModules.add(httpReqParam.toLowerCase());
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.String)
- */
- @Override
- public final boolean doAuthentication(HttpServletRequest httpReq, HttpServletResponse httpResp,
- IRequest pendingReq) throws EAAFException {
-
- if (!(pendingReq instanceof RequestImpl)) {
- log.error("Requests that need authentication MUST be of type 'RequestImpl'");
- throw new RuntimeException("Requests that need authentication HAS TO BE of type 'RequestImpl'");
-
- }
-
- //load OA configuration from pending request
- final ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
-
- //set logging context and log unique OA identifier to revision log
- TransactionIDUtils.setServiceProviderId(oaParam.getUniqueIdentifier());
- revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FOR_SP, pendingReq.getSPEntityId());
-
- //generic authentication request validation
- if (pendingReq.isPassiv() && pendingReq.forceAuth()) {
- // conflict!
- throw new NoPassivAuthenticationException();
- }
-
-
- //check Single Sign-On functionality if SSOManager is available
- boolean isValidSSOSession = false;
- if (ssoManager != null) {
- log.trace("SSOManager is loaded. Starting SSO session validation ... ");
- //check if SSO is allowed for this service provider
- ssoManager.isSSOAllowedForSP(pendingReq, httpReq);
-
- //check if SSO session is active and valid
- isValidSSOSession = ssoManager.checkAndValidateSSOSession(pendingReq, httpReq, httpResp) &&
- pendingReq.needSingleSignOnFunctionality();
-
-
- }
-
- //check if session is already authenticated
- //boolean isSessionAuthenticated = tryPerformAuthentication((RequestImpl) pendingReq, isValidSSOSession);
- //boolean isSessionAuthenticated = isValidSSOSession && StringUtils.isNotEmpty(pendingReq.getSSOSessionIdentifier());
-
-
- //force new authentication authentication process
- if (pendingReq.forceAuth()) {
- startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
- return false;
-
- //perform SSO-Consents evaluation if it it required
- } else if (isValidSSOSession && pendingReq.isNeedUserConsent()) {
- sendSingleSignOnConsentsEvaluation(httpReq, httpResp, (RequestImpl) pendingReq);
- return false;
-
-
- } else if (pendingReq.isPassiv()) {
- if (isValidSSOSession &&
- StringUtils.isNotEmpty(pendingReq.getInternalSSOSessionIdentifier()) ) {
- // Passive authentication ok! --> Populate pending request from SSO session
- ssoManager.populatePendingRequestWithSSOInformation(pendingReq);
- revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
- return true;
-
- } else {
- throw new NoPassivAuthenticationException();
-
- }
-
- } else {
- if (isValidSSOSession &&
- StringUtils.isNotEmpty(pendingReq.getInternalSSOSessionIdentifier())) {
- // Is authenticated .. proceed
- ssoManager.populatePendingRequestWithSSOInformation(pendingReq);
- revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
- return true;
-
- } else {
- // Start authentication!
- startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
- return false;
-
- }
- }
- }
-
- @Override
- public final void performOnlyIDPLogOut(HttpServletRequest request, HttpServletResponse response, IRequest pendingReq) {
-
- log.debug("Close session. Remove pending request ... ");
- requestStoreage.removePendingRequest(pendingReq.getPendingRequestId());
-
-
- if (ssoManager != null) {
- try {
- log.trace("'SSOManager' active. Search for active SSO sessions ... ");
- if (ssoManager.destroySSOSessionOnIDPOnly(request, response, pendingReq))
- log.info("SSO session successfully closed");
- else
- log.info("Closing SSO session NOT successfully");
-
- } catch (final EAAFSSOException e) {
- log.warn("Destroying of SSO session FAILED. Reason: " + e.getMessage(), e);
-
- }
-
- }
-
- }
-
- /**
- * Populate process execution context and start process engine
- *
- * @param httpReq
- * @param httpResp
- * @param pendingReq
- * @throws ServletException
- * @throws IOException
- * @throws EAAFException
- */
- private void startAuthenticationProcess(HttpServletRequest httpReq,
- HttpServletResponse httpResp, RequestImpl pendingReq)
- throws EAAFException {
-
- log.info("Starting authentication ...");
- revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_STARTED);
-
- //create authentication process execution context
- final ExecutionContext executionContext = new ExecutionContextImpl();
-
- //set oaIdentifeir
- executionContext.put(EAAFConstants.PROCESS_ENGINE_SERVICE_PROVIDER_ENTITYID,
- pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
-
- //add X509 SSL client certificate if exist
- if (httpReq.getAttribute("javax.servlet.request.X509Certificate") != null) {
- log.debug("Find SSL-client-certificate on request --> Add it to context");
- executionContext.put(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE,
- ((X509Certificate[])httpReq.getAttribute("javax.servlet.request.X509Certificate")));
- pendingReq.setRawDataToTransaction(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE,
- (httpReq.getAttribute("javax.servlet.request.X509Certificate")));
-
- }
-
- //add additional http request parameter to context
- if (!reqParameterWhiteListeForModules.isEmpty()) {
- final Enumeration<String> reqParamNames = httpReq.getParameterNames();
- while(reqParamNames.hasMoreElements()) {
- final String paramName = reqParamNames.nextElement();
- if (StringUtils.isNotEmpty(paramName) && reqParameterWhiteListeForModules.contains(paramName) )
- executionContext.put(paramName, StringEscapeUtils.escapeHtml4(httpReq.getParameter(paramName)));
- }
- }
-
- //add additional http request parameter to context
- if (!reqHeaderWhiteListeForModules.isEmpty()) {
- final Enumeration<String> reqHeaderNames = httpReq.getHeaderNames();
- while(reqHeaderNames.hasMoreElements()) {
- final String paramName = reqHeaderNames.nextElement();
- if (StringUtils.isNotEmpty(paramName)
- && at.gv.egiz.eaaf.core.impl.utils.ArrayUtils.containsCaseInsensitive(paramName, reqHeaderWhiteListeForModules)
- //reqHeaderWhiteListeForModules.contains(paramName.toLowerCase())
- )
- executionContext.put(paramName.toLowerCase(), StringEscapeUtils.escapeHtml4(httpReq.getHeader(paramName)));
-
- }
- }
-
-
-
- //populate more IDP specific information to execution context
- populateExecutionContext(executionContext, pendingReq, httpReq);
-
- //start process engine
- startProcessEngine(pendingReq, executionContext);
-
- }
-
- /**
- *
- *
- * @throws EAAFException
- */
- abstract protected void populateExecutionContext(ExecutionContext executionContext,
- RequestImpl pendingReq, HttpServletRequest httpReq) throws EAAFException;
-
- /**
- * Starting a user consent evaluation
- *
- * @param request
- * @param response
- * @param pendingReq
- * @throws ServletException
- * @throws IOException
- * @throws EAAFException
- */
- private void sendSingleSignOnConsentsEvaluation(HttpServletRequest request,
- HttpServletResponse response, RequestImpl pendingReq)
- throws EAAFException {
-
- log.debug("Starting SSO user-consents evaluation ...");
-
- //set authenticated flag to false, because user consents is required
- pendingReq.setAuthenticated(false);
-
- //create execution context
- final ExecutionContext executionContext = new ExecutionContextImpl();
- executionContext.put(ISSOManager.PROCESS_ENGINE_SSO_CONSENTS_EVALUATION, true);
-
- //start process engine
- startProcessEngine(pendingReq, executionContext);
-
- }
-
-
- /**
- * Select a specific process and starting process engine
- *
- * @param pendingReq
- * @param executionContext
- * @throws EAAFException
- */
- private void startProcessEngine(RequestImpl pendingReq, ExecutionContext executionContext) throws EAAFException {
- try {
- //put pending-request ID on execurtionContext
- executionContext.put(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID, pendingReq.getPendingRequestId());
-
- // create process instance
- final String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext, pendingReq);
-
- if (processDefinitionId == null) {
- log.warn("No suitable process found for PendingReqId " + pendingReq.getPendingRequestId() );
- throw new EAAFException(
- "process.02",
- new Object[] {pendingReq.getPendingRequestId()});
-
- }
-
- final String processInstanceId = processEngine.createProcessInstance(processDefinitionId, executionContext);
-
- // keep process instance id in protocol pending-request
- pendingReq.setProcessInstanceId(processInstanceId);
-
- //store pending-request
- requestStoreage.storePendingRequest(pendingReq);
-
- // start process
- processEngine.start(pendingReq);
-
- } catch (final ProcessExecutionException e) {
- final Throwable cause = e.getCause();
- if (cause != null && cause instanceof TaskExecutionException) {
- final Throwable taskCause = cause.getCause();
- if (taskCause != null && taskCause instanceof EAAFException) {
- final EAAFException moaTaskCause = (EAAFException) taskCause;
- log.warn(taskCause.getMessage(), taskCause);
- throw moaTaskCause;
-
- }
- }
-
- throw new EAAFException(
- "process.01",
- new Object[] { pendingReq.getProcessInstanceId(), pendingReq.getPendingRequestId() }, e);
- }
-
- }
+ private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationManager.class);
+
+ private static List<String> reqParameterWhiteListeForModules = new ArrayList<>();
+ private static List<String> reqHeaderWhiteListeForModules = new ArrayList<>();
+
+ public static final String MOA_SESSION = "MoaAuthenticationSession";
+ public static final String MOA_AUTHENTICATED = "MoaAuthenticated";
+
+ public static final int SLOTIMEOUT = 30 * 1000; // 30 sec
+
+ @Autowired(required = true)
+ protected IConfiguration authConfig;
+ @Autowired(required = true)
+ private ProcessEngine processEngine;
+ @Autowired(required = true)
+ private IRequestStorage requestStoreage;
+ @Autowired(required = true)
+ protected IRevisionLogger revisionsLogger;
+ @Autowired(required = false)
+ protected ISsoManager ssoManager;
+ @Autowired ModuleRegistration moduleRegistration;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addParameterNameToWhiteList(java.lang
+ * .String)
+ */
+ @Override
+ public final void addParameterNameToWhiteList(final String httpReqParam) {
+ if (StringUtils.isNotEmpty(httpReqParam)) {
+ reqParameterWhiteListeForModules.add(httpReqParam);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.
+ * String)
+ */
+ @Override
+ public final void addHeaderNameToWhiteList(final String httpReqParam) {
+ if (StringUtils.isNotEmpty(httpReqParam)) {
+ reqHeaderWhiteListeForModules.add(httpReqParam.toLowerCase());
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#addHeaderNameToWhiteList(java.lang.
+ * String)
+ */
+ @Override
+ public final boolean doAuthentication(final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp, final IRequest pendingReq) throws EaafException {
+
+ if (!(pendingReq instanceof RequestImpl)) {
+ log.error("Requests that need authentication MUST be of type 'RequestImpl'");
+ throw new RuntimeException(
+ "Requests that need authentication HAS TO BE of type 'RequestImpl'");
+
+ }
+
+ // load OA configuration from pending request
+ final IspConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+
+ // set logging context and log unique OA identifier to revision log
+ TransactionIdUtils.setServiceProviderId(oaParam.getUniqueIdentifier());
+ revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FOR_SP,
+ pendingReq.getSpEntityId());
+
+ // generic authentication request validation
+ if (pendingReq.isPassiv() && pendingReq.forceAuth()) {
+ // conflict!
+ throw new NoPassivAuthenticationException();
+ }
+
+
+ // check Single Sign-On functionality if SSOManager is available
+ boolean isValidSsoSession = false;
+ if (ssoManager != null) {
+ log.trace("SSOManager is loaded. Starting SSO session validation ... ");
+ // check if SSO is allowed for this service provider
+ ssoManager.isSsoAllowedForSp(pendingReq, httpReq);
+
+ // check if SSO session is active and valid
+ isValidSsoSession = ssoManager.checkAndValidateSsoSession(pendingReq, httpReq, httpResp)
+ && pendingReq.needSingleSignOnFunctionality();
+
+
+ }
+
+ // check if session is already authenticated
+ // boolean isSessionAuthenticated = tryPerformAuthentication((RequestImpl) pendingReq,
+ // isValidSSOSession);
+ // boolean isSessionAuthenticated = isValidSSOSession &&
+ // StringUtils.isNotEmpty(pendingReq.getSSOSessionIdentifier());
+
+
+ // force new authentication authentication process
+ if (pendingReq.forceAuth()) {
+ startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
+ return false;
+
+ // perform SSO-Consents evaluation if it it required
+ } else if (isValidSsoSession && pendingReq.isNeedUserConsent()) {
+ sendSingleSignOnConsentsEvaluation(httpReq, httpResp, (RequestImpl) pendingReq);
+ return false;
+
+
+ } else if (pendingReq.isPassiv()) {
+ if (isValidSsoSession
+ && StringUtils.isNotEmpty(pendingReq.getInternalSsoSessionIdentifier())) {
+ // Passive authentication ok! --> Populate pending request from SSO session
+ ssoManager.populatePendingRequestWithSsoInformation(pendingReq);
+ revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
+ return true;
+
+ } else {
+ throw new NoPassivAuthenticationException();
+
+ }
+
+ } else {
+ if (isValidSsoSession
+ && StringUtils.isNotEmpty(pendingReq.getInternalSsoSessionIdentifier())) {
+ // Is authenticated .. proceed
+ ssoManager.populatePendingRequestWithSsoInformation(pendingReq);
+ revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_FINISHED);
+ return true;
+
+ } else {
+ // Start authentication!
+ startAuthenticationProcess(httpReq, httpResp, (RequestImpl) pendingReq);
+ return false;
+
+ }
+ }
+ }
+
+ @Override
+ public final void performOnlyIdpLogOut(final HttpServletRequest request,
+ final HttpServletResponse response, final IRequest pendingReq) {
+
+ log.debug("Close session. Remove pending request ... ");
+ requestStoreage.removePendingRequest(pendingReq.getPendingRequestId());
+
+
+ if (ssoManager != null) {
+ try {
+ log.trace("'SSOManager' active. Search for active SSO sessions ... ");
+ if (ssoManager.destroySsoSessionOnIdpOnly(request, response, pendingReq)) {
+ log.info("SSO session successfully closed");
+ } else {
+ log.info("Closing SSO session NOT successfully");
+ }
+
+ } catch (final EaafSsoException e) {
+ log.warn("Destroying of SSO session FAILED. Reason: " + e.getMessage(), e);
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Populate process execution context and start process engine.
+ *
+ * @param httpReq http request
+ * @param httpResp http response
+ * @param pendingReq current pending request
+ * @throws ServletException In case of a servlet error
+ * @throws IOException In case of an IO error
+ * @throws EaafException In case of EAAF processing error
+ */
+ private void startAuthenticationProcess(final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp, final RequestImpl pendingReq) throws EaafException {
+
+ log.info("Starting authentication ...");
+ revisionsLogger.logEvent(pendingReq, EVENT_AUTHENTICATION_PROCESS_STARTED);
+
+ // create authentication process execution context
+ final ExecutionContext executionContext = new ExecutionContextImpl();
+
+ // set oaIdentifeir
+ executionContext.put(EAAFConstants.PROCESS_ENGINE_SERVICE_PROVIDER_ENTITYID,
+ pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ // add X509 SSL client certificate if exist
+ if (httpReq.getAttribute("javax.servlet.request.X509Certificate") != null) {
+ log.debug("Find SSL-client-certificate on request --> Add it to context");
+ executionContext.put(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE,
+ ((X509Certificate[]) httpReq.getAttribute("javax.servlet.request.X509Certificate")));
+ pendingReq.setRawDataToTransaction(EAAFConstants.PROCESS_ENGINE_SSL_CLIENT_CERTIFICATE,
+ (httpReq.getAttribute("javax.servlet.request.X509Certificate")));
+
+ }
+
+ // add additional http request parameter to context
+ if (!reqParameterWhiteListeForModules.isEmpty()) {
+ final Enumeration<String> reqParamNames = httpReq.getParameterNames();
+ while (reqParamNames.hasMoreElements()) {
+ final String paramName = reqParamNames.nextElement();
+ if (StringUtils.isNotEmpty(paramName)
+ && reqParameterWhiteListeForModules.contains(paramName)) {
+ executionContext.put(paramName,
+ StringEscapeUtils.escapeHtml4(httpReq.getParameter(paramName)));
+ }
+ }
+ }
+
+ // add additional http request parameter to context
+ if (!reqHeaderWhiteListeForModules.isEmpty()) {
+ final Enumeration<String> reqHeaderNames = httpReq.getHeaderNames();
+ while (reqHeaderNames.hasMoreElements()) {
+ final String paramName = reqHeaderNames.nextElement();
+ if (StringUtils.isNotEmpty(paramName) && at.gv.egiz.eaaf.core.impl.utils.ArrayUtils
+ .containsCaseInsensitive(paramName, reqHeaderWhiteListeForModules)
+ // reqHeaderWhiteListeForModules.contains(paramName.toLowerCase())
+ ) {
+ executionContext.put(paramName.toLowerCase(),
+ StringEscapeUtils.escapeHtml4(httpReq.getHeader(paramName)));
+ }
+
+ }
+ }
+
+
+
+ // populate more IDP specific information to execution context
+ populateExecutionContext(executionContext, pendingReq, httpReq);
+
+ // start process engine
+ startProcessEngine(pendingReq, executionContext);
+
+ }
+
+ /**
+ * Add additional parameters into context of process-engine.
+ *
+ * @param executionContext Process-engine context
+ * @param pendingReq Current pending request
+ * @param httpReq http request
+ *
+ * @throws EaafException In case of an error
+ */
+ protected abstract void populateExecutionContext(ExecutionContext executionContext,
+ RequestImpl pendingReq, HttpServletRequest httpReq) throws EaafException;
+
+ /**
+ * Starting a user consent evaluation.
+ *
+ * @param request http request
+ * @param response http response
+ * @param pendingReq current pending request
+ * @throws ServletException In case of a servlet error
+ * @throws IOException In case of an IO error
+ * @throws EaafException In case of a EAAF processing error
+ */
+ private void sendSingleSignOnConsentsEvaluation(final HttpServletRequest request,
+ final HttpServletResponse response, final RequestImpl pendingReq) throws EaafException {
+
+ log.debug("Starting SSO user-consents evaluation ...");
+
+ // set authenticated flag to false, because user consents is required
+ pendingReq.setAuthenticated(false);
+
+ // create execution context
+ final ExecutionContext executionContext = new ExecutionContextImpl();
+ executionContext.put(ISsoManager.PROCESS_ENGINE_SSO_CONSENTS_EVALUATION, true);
+
+ // start process engine
+ startProcessEngine(pendingReq, executionContext);
+
+ }
+
+
+ /**
+ * Select a specific process and starting process engine.
+ *
+ * @param pendingReq current pending request
+ * @param executionContext current context for process-engine
+ * @throws EaafException In case of an process-engine error
+ */
+ private void startProcessEngine(final RequestImpl pendingReq,
+ final ExecutionContext executionContext) throws EaafException {
+ try {
+ // put pending-request ID on execurtionContext
+ executionContext.put(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID,
+ pendingReq.getPendingRequestId());
+
+ // create process instance
+ final String processDefinitionId =
+ moduleRegistration.selectProcess(executionContext, pendingReq);
+
+ if (processDefinitionId == null) {
+ log.warn("No suitable process found for PendingReqId " + pendingReq.getPendingRequestId());
+ throw new EaafException("process.02", new Object[] {pendingReq.getPendingRequestId()});
+
+ }
+
+ final String processInstanceId =
+ processEngine.createProcessInstance(processDefinitionId, executionContext);
+
+ // keep process instance id in protocol pending-request
+ pendingReq.setProcessInstanceId(processInstanceId);
+
+ // store pending-request
+ requestStoreage.storePendingRequest(pendingReq);
+
+ // start process
+ processEngine.start(pendingReq);
+
+ } catch (final ProcessExecutionException e) {
+ final Throwable cause = e.getCause();
+ if (cause != null && cause instanceof TaskExecutionException) {
+ final Throwable taskCause = cause.getCause();
+ if (taskCause != null && taskCause instanceof EaafException) {
+ final EaafException moaTaskCause = (EaafException) taskCause;
+ log.warn(taskCause.getMessage(), taskCause);
+ throw moaTaskCause;
+
+ }
+ }
+
+ throw new EaafException("process.01",
+ new Object[] {pendingReq.getProcessInstanceId(), pendingReq.getPendingRequestId()}, e);
+ }
+
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
index e1598b8f..1afa879f 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java
@@ -1,218 +1,224 @@
-/*******************************************************************************
- * 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.
+/*
+ * 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:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.core.impl.idp.auth;
+ * 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.
+ */
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
+package at.gv.egiz.eaaf.core.impl.idp.auth;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
-import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDao;
import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
-import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
@Service("RequestStorage")
-public class RequestStorage implements IRequestStorage{
- private static final Logger log = LoggerFactory.getLogger(RequestStorage.class);
-
- @Autowired(required=true) ITransactionStorage transactionStorage;
- @Autowired(required=true) ProcessInstanceStoreDAO processInstanceStore;
- @Autowired(required=true) IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy;
-
- @Override
- public IRequest getPendingRequest(String pendingReqID) throws PendingReqIdValidationException {
-
- try {
- final String internalPendingReqId =
- pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(pendingReqID);
- log.debug("PendingReqId is valid");
-
- //get pending-request from storage
- final IRequest pendingRequest = getInternalPendingRequest(internalPendingReqId);
-
- //set transactionID and sessionID to Logger
- TransactionIDUtils.setAllLoggingVariables(pendingRequest);
-
- return pendingRequest;
-
- } catch (final PendingReqIdValidationException e) {
- log.info("PendingRequestId is invalid. Reason: {} ", e.getMessage());
-
- // search invalid pending-request for errorHandling
- IRequest invalidPendingRequest = null;
- try {
- if (StringUtils.isNotEmpty(e.getInvalidInternalPendingReqId()))
- invalidPendingRequest = transactionStorage.get(e.getInvalidInternalPendingReqId(), IRequest.class);
-
- } catch (final EAAFException e1) {
- log.info("No PendingRequst found with pendingRequestID " + pendingReqID);
- return null;
-
- }
-
- e.setInvalidPendingReq(invalidPendingRequest);
- throw e;
-
- } catch (EAAFException | NullPointerException e) {
- log.info("No PendingRequst found with pendingRequestID " + pendingReqID);
- return null;
-
- }
- }
-
- @Override
- public void storePendingRequest(IRequest pendingRequest) throws EAAFException {
- try {
- if (pendingRequest instanceof IRequest) {
- try {
- //validate pending-requestId
- final String internalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId());
-
- //store pending request
- transactionStorage.put(internalPendingRequestId, pendingRequest, -1);
-
- } catch (final PendingReqIdValidationException e) {
- log.warn("Invalid pending-request-Id. Reason: {}", e.getMessage());
- log.warn("Do NOT store pending-request with invalid pending-request-Id. The process will break soon!");
-
- }
-
- } else
- throw new EAAFException("PendigRequest is NOT of type 'IRequest'", null);
-
- } catch (final EAAFException e) {
- log.warn("PendingRequest with ID=" + pendingRequest.getPendingRequestId() +
- " can not stored.", e);
- throw new EAAFStorageException("PendingRequest with Id: " + pendingRequest.getPendingRequestId()
- + " can not be stored", e);
-
- }
-
- }
-
- @Override
- public void removePendingRequest(String pendingReqID) {
-
- if (pendingReqID != null) {
- String internalPendingReqId = null;
- try {
- internalPendingReqId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingReqID);
-
- } catch (final PendingReqIdValidationException e) {
- internalPendingReqId = e.getInvalidInternalPendingReqId();
-
- }
-
- try {
- //remove process-management execution instance#
- if (internalPendingReqId != null) {
- final IRequest pendingReq = getInternalPendingRequest(internalPendingReqId);
- if (pendingReq != null &&
- pendingReq.getProcessInstanceId() != null)
- processInstanceStore.remove(pendingReq.getProcessInstanceId());
-
- //remove pending-request
- transactionStorage.remove(internalPendingReqId);
- }
-
- } catch (final EAAFException e) {
- log.warn("Removing process associated with pending-request:" + pendingReqID + " FAILED.", e);
-
- }
-
- }
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.storage.IRequestStorage#changePendingRequestID(at.gv.egovernment.moa.id.moduls.IRequest)
- */
- @Override
- public String changePendingRequestID(IRequest pendingRequest) throws EAAFException {
- if (pendingRequest instanceof RequestImpl) {
-
- //get old internal pendingReqId
- String oldInternalRequestID = null;
- try {
- oldInternalRequestID =
- pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId());
-
- } catch (final PendingReqIdValidationException e) {
- //it's no problem, because it must be valid before when pending-request was loaded and we change it now
- oldInternalRequestID = e.getInvalidInternalPendingReqId();
-
- }
-
-
- //generate new pendingReqId and get internalPendingReqId
- final String newRequestID = pendingReqIdGenerationStrategy.generateExternalPendingRequestId();
- log.debug("Change pendingRequestID from " + pendingRequest.getPendingRequestId() + " to " + newRequestID);
- ((RequestImpl)pendingRequest).setPendingRequestId(newRequestID);
-
- String newInternalPendingRequestId = null;
- try {
- newInternalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(newRequestID);
-
- } catch (final PendingReqIdValidationException e) {
- throw new EAAFException("internal.99", new Object[]{"Generate invalid pendingRequestId. Something looks WRONG"}, e);
-
- }
-
-
- //change Key in cache
- transactionStorage.changeKey(oldInternalRequestID, newInternalPendingRequestId, pendingRequest);
-
- //only delete oldRequestID, no change.
- return newRequestID;
-
- } else {
- log.error("PendingRequest object is not of type 'RequestImpl.class'");
- throw new EAAFException("PendingRequest object is not of type 'RequestImpl.class'", null);
-
- }
-
- }
-
- private IRequest getInternalPendingRequest(String internalPendingReqId) throws EAAFException {
- final IRequest pendingRequest = transactionStorage.get(internalPendingReqId, IRequest.class);
- if (pendingRequest == null) {
- log.info("No PendingRequst found with pendingRequestID " + internalPendingReqId);
- return null;
-
- }
-
- return pendingRequest;
-
- }
+public class RequestStorage implements IRequestStorage {
+ private static final Logger log = LoggerFactory.getLogger(RequestStorage.class);
+
+ @Autowired(required = true)
+ ITransactionStorage transactionStorage;
+ @Autowired(required = true)
+ ProcessInstanceStoreDao processInstanceStore;
+ @Autowired(required = true)
+ IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy;
+
+ @Override
+ public IRequest getPendingRequest(final String pendingReqID)
+ throws PendingReqIdValidationException {
+
+ try {
+ final String internalPendingReqId =
+ pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(pendingReqID);
+ log.debug("PendingReqId is valid");
+
+ // get pending-request from storage
+ final IRequest pendingRequest = getInternalPendingRequest(internalPendingReqId);
+
+ // set transactionID and sessionID to Logger
+ TransactionIdUtils.setAllLoggingVariables(pendingRequest);
+
+ return pendingRequest;
+
+ } catch (final PendingReqIdValidationException e) {
+ log.info("PendingRequestId is invalid. Reason: {} ", e.getMessage());
+
+ // search invalid pending-request for errorHandling
+ IRequest invalidPendingRequest = null;
+ try {
+ if (StringUtils.isNotEmpty(e.getInvalidInternalPendingReqId())) {
+ invalidPendingRequest =
+ transactionStorage.get(e.getInvalidInternalPendingReqId(), IRequest.class);
+ }
+
+ } catch (final EaafException e1) {
+ log.info("No PendingRequst found with pendingRequestID " + pendingReqID);
+ return null;
+
+ }
+
+ e.setInvalidPendingReq(invalidPendingRequest);
+ throw e;
+
+ } catch (EaafException | NullPointerException e) {
+ log.info("No PendingRequst found with pendingRequestID " + pendingReqID);
+ return null;
+
+ }
+ }
+
+ @Override
+ public void storePendingRequest(final IRequest pendingRequest) throws EaafException {
+ try {
+ // validate pending-requestId
+ final String internalPendingRequestId = pendingReqIdGenerationStrategy
+ .getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId());
+
+ // store pending request
+ transactionStorage.put(internalPendingRequestId, pendingRequest, -1);
+
+ } catch (final PendingReqIdValidationException e) {
+ log.warn("Invalid pending-request-Id. Reason: {}", e.getMessage());
+ log.warn(
+ "Do NOT store pending-request with invalid pending-request-Id. The process will break soon!");
+
+ } catch (final EaafException e) {
+ log.warn(
+ "PendingRequest with ID=" + pendingRequest.getPendingRequestId() + " can not stored.", e);
+ throw new EaafStorageException(
+ "PendingRequest with Id: " + pendingRequest.getPendingRequestId() + " can not be stored",
+ e);
+
+ }
+
+ }
+
+ @Override
+ public void removePendingRequest(final String pendingReqID) {
+
+ if (pendingReqID != null) {
+ String internalPendingReqId = null;
+ try {
+ internalPendingReqId =
+ pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingReqID);
+
+ } catch (final PendingReqIdValidationException e) {
+ internalPendingReqId = e.getInvalidInternalPendingReqId();
+
+ }
+
+ try {
+ // remove process-management execution instance#
+ if (internalPendingReqId != null) {
+ final IRequest pendingReq = getInternalPendingRequest(internalPendingReqId);
+ if (pendingReq != null && pendingReq.getProcessInstanceId() != null) {
+ processInstanceStore.remove(pendingReq.getProcessInstanceId());
+ }
+
+ // remove pending-request
+ transactionStorage.remove(internalPendingReqId);
+ }
+
+ } catch (final EaafException e) {
+ log.warn("Removing process associated with pending-request:" + pendingReqID + " FAILED.",
+ e);
+
+ }
+
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.storage.IRequestStorage#changePendingRequestID(at.gv.egovernment.moa.
+ * id.moduls.IRequest)
+ */
+ @Override
+ public String changePendingRequestID(final IRequest pendingRequest) throws EaafException {
+ if (pendingRequest instanceof RequestImpl) {
+
+ // get old internal pendingReqId
+ String oldInternalRequestID = null;
+ try {
+ oldInternalRequestID = pendingReqIdGenerationStrategy
+ .getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId());
+
+ } catch (final PendingReqIdValidationException e) {
+ // it's no problem, because it must be valid before when pending-request was loaded and we
+ // change it now
+ oldInternalRequestID = e.getInvalidInternalPendingReqId();
+
+ }
+
+
+ // generate new pendingReqId and get internalPendingReqId
+ final String newRequestID = pendingReqIdGenerationStrategy.generateExternalPendingRequestId();
+ log.debug("Change pendingRequestID from " + pendingRequest.getPendingRequestId() + " to "
+ + newRequestID);
+ ((RequestImpl) pendingRequest).setPendingRequestId(newRequestID);
+
+ String newInternalPendingRequestId = null;
+ try {
+ newInternalPendingRequestId =
+ pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(newRequestID);
+
+ } catch (final PendingReqIdValidationException e) {
+ throw new EaafException("internal.99",
+ new Object[] {"Generate invalid pendingRequestId. Something looks WRONG"}, e);
+
+ }
+
+
+ // change Key in cache
+ transactionStorage.changeKey(oldInternalRequestID, newInternalPendingRequestId,
+ pendingRequest);
+
+ // only delete oldRequestID, no change.
+ return newRequestID;
+
+ } else {
+ log.error("PendingRequest object is not of type 'RequestImpl.class'");
+ throw new EaafException("PendingRequest object is not of type 'RequestImpl.class'", null);
+
+ }
+
+ }
+
+ private IRequest getInternalPendingRequest(final String internalPendingReqId)
+ throws EaafException {
+ final IRequest pendingRequest = transactionStorage.get(internalPendingReqId, IRequest.class);
+ if (pendingRequest == null) {
+ log.info("No PendingRequst found with pendingRequestID " + internalPendingReqId);
+ return null;
+
+ }
+
+ return pendingRequest;
+
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
index 2108e041..491fdf4a 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * 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.
+/*
+ * 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:
+ * 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.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.auth.builder;
import java.io.ByteArrayInputStream;
@@ -32,18 +25,6 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map.Entry;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.lang.NonNull;
-import org.springframework.util.Assert;
-import org.springframework.util.Base64Utils;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.data.ExtendedPVPAttributeDefinitions;
@@ -51,674 +32,748 @@ import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions;
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.IConfigurationWithSP;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IspConfiguration;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFParserException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafParserException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import at.gv.egiz.eaaf.core.exceptions.XPathException;
import at.gv.egiz.eaaf.core.impl.data.Pair;
import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser;
import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
-
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.NonNull;
+import org.springframework.util.Assert;
+import org.springframework.util.Base64Utils;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
public abstract class AbstractAuthenticationDataBuilder implements IAuthenticationDataBuilder {
- private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationDataBuilder.class);
-
- /**
- * Identify authProcessData that should be directly mapped into authData
- */
- public static final String GENERIC_AUTHDATA_IDENTIFIER = "authData_";
-
- public static final String CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING = "configuration.bugfix.enable.idl.escaping";
-
- protected Collection<String> includedToGenericAuthData = null;
- @Autowired protected IConfigurationWithSP basicConfig;
-
- @Override
- public IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException {
- IAuthData authData = null;
- final IAuthProcessDataContainer authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class);
-
- try {
- if (authProcessData.isEIDProcess()) {
- log.debug("Building AuthData from new E-ID information ... ");
- authData = getAuthDataInstance(pendingReq);
- Assert.notNull(authData, "AuthData is null");
-
- log.trace("Adding generic AuthData information ... ");
- buildInternalAuthDataGeneric(authData, authProcessData, pendingReq);
-
- log.trace("Build service-specific AuthData information ... ");
- buildServiceSpecificAuthenticationData(authData, pendingReq);
-
- } else {
- log.info("User authentication uses the deprecated. Building AuthData from deprecated information ... ");
- authData = buildDeprecatedAuthData(pendingReq);
- Assert.notNull(authData, "AuthData is null");
-
- }
-
- } catch ( final EAAFAuthenticationException e) {
- throw e;
-
- } catch (XPathException | DOMException | EAAFException e) {
- log.warn("Can not build authentication data from auth. process information");
- throw new EAAFAuthenticationException("builder.11", new Object[]{e.getMessage()}, e);
-
- }
-
- log.trace("AuthData generation finished");
- return authData;
-
- }
-
- /**
- * * @param pendingReq current pendingRequest
- *
- * @param pendingReq current pendingRequest
- * @return {@link IAuthData} but never <code>null</code>
- * @throws EAAFException
- */
- @NonNull
- abstract protected IAuthData getAuthDataInstance(IRequest pendingReq) throws EAAFException;
-
- /**
- * Build service-specific AuthData by using information from E-ID
- * This builder uses vSZ, MDS and Consent as input information
- *
- * @param pendingReq current pendingRequest
- * @return {@link IAuthData} but never <code>null</code>
- * @throws EAAFException
- */
- abstract protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq) throws EAAFException;
-
-
- /**
- * Add generic E-ID information into already existing AuthData
- *
- * @param authData
- * @param authProcessData
- * @param pendingReq
- */
- private void buildInternalAuthDataGeneric(@NonNull IAuthData authData,
- @NonNull IAuthProcessDataContainer authProcessData, @NonNull IRequest pendingReq) {
- Assert.notNull(pendingReq, "PendingRequest is null");
- Assert.notNull(authData, "AuthData is null");
- Assert.notNull(authProcessData, "AuthProcessData is null");
-
- if (!(authData instanceof AuthenticationData)) {
- log.error("AuthData has no suitable type! Requires: {}", AuthenticationData.class.getName());
- throw new RuntimeException("AuthData has no suitable type! Requires: " + AuthenticationData.class.getName());
-
- }
-
- final AuthenticationData internalAuthData = (AuthenticationData)authData;
-
- //TODO: check if it is needed
-// if (authProcessData.getGenericSessionDataStorage() != null &&
-// !authProcessData.getGenericSessionDataStorage().isEmpty())
-// includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
-// else
- includedToGenericAuthData = new ArrayList<String>();
-
- //####################################################
- //set general authData info's
- internalAuthData.setAuthenticationIssuer(pendingReq.getAuthURL());
- internalAuthData.setSsoSession(pendingReq.needSingleSignOnFunctionality());
- internalAuthData.setBaseIDTransferRestrication(pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction());
-
- //####################################################
- //set MDS and vSZ
- internalAuthData.setFamilyName(authProcessData.getGenericDataFromSession(ExtendedPVPAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class));
- internalAuthData.setGivenName(authProcessData.getGenericDataFromSession(ExtendedPVPAttributeDefinitions.GIVEN_NAME_NAME, String.class));
- internalAuthData.setDateOfBirth(authProcessData.getGenericDataFromSession(ExtendedPVPAttributeDefinitions.BIRTHDATE_NAME, String.class));
- internalAuthData.setEncSourceId(authProcessData.getGenericDataFromSession(ExtendedPVPAttributeDefinitions.EID_ENCRYPTED_SOURCEID_NAME, String.class));
- internalAuthData.setEncSourceIdType(authProcessData.getGenericDataFromSession(ExtendedPVPAttributeDefinitions.EID_ENCRYPTED_SOURCEID_TYPE_NAME, String.class));
-
- //####################################################
- //set QAA level
- setQAALevel(internalAuthData, authProcessData, pendingReq);
-
-
- //####################################################
- //set isForeigner flag
- setFlagForeigner(internalAuthData, authProcessData, pendingReq);
-
-
- //####################################################
- //set citizen country-code
- setCitizenCountryCode(internalAuthData, authProcessData, pendingReq);
-
-
- //set generic authProcessData to authdata
- for (final Entry<String, Object> el : authProcessData.getGenericSessionDataStorage().entrySet()) {
- if (el.getKey().startsWith(GENERIC_AUTHDATA_IDENTIFIER)) {
- log.trace("Find generic authProcessData {}. Map it directly to authData", el.getKey());
- try {
- internalAuthData.setGenericData(el.getKey(), el.getValue());
-
- } catch (final EAAFStorageException e) {
- log.warn("Can NOT set authData with key: {}", el.getKey(), null, e);
-
- }
-
- }
-
- }
-
-
- }
-
- /**
- * Parse citzen country-code into AuthData
- *
- * @param internalAuthData
- * @param authProcessData
- * @param pendingReq
- */
- private void setCitizenCountryCode(AuthenticationData authData, IAuthProcessDataContainer authProcessData,
- IRequest pendingReq) {
- includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME);
- final String pvpCCCAttr = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
- if (StringUtils.isNotEmpty(pvpCCCAttr)) {
- authData.setCiticenCountryCode(pvpCCCAttr);
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME);
-
- } else {
- if (authData.isForeigner()) {
- //TODO!!!!
-
- } else {
- authData.setCiticenCountryCode(basicConfig.getBasicConfiguration(
- IConfigurationWithSP.CONFIG_PROPS_AUTH_DEFAULT_COUNTRYCODE,
- EAAFConstants.COUNTRYCODE_AUSTRIA));
-
- }
- }
-
- }
-
- /**
- * parse QAA Level into AuthData
- *
- * @param authData
- * @param authProcessData
- * @param pendingReq
- */
- private void setQAALevel(@NonNull AuthenticationData authData,
- @NonNull IAuthProcessDataContainer authProcessData, @NonNull IRequest pendingReq) {
- includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
- String currentLoA = null;
- if (StringUtils.isNotEmpty(authProcessData.getQAALevel()))
- currentLoA = authProcessData.getQAALevel();
- else {
- currentLoA = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, String.class);
- if (StringUtils.isNotEmpty(currentLoA)) {
- log.debug("Find PVP-Attr '" + PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME + "':" + currentLoA
- + " --> Parse QAA-Level from that attribute.");
-
- }
- }
- if (StringUtils.isNotEmpty(currentLoA)) {
- if (currentLoA.startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) {
- authData.seteIDASLoA(currentLoA);
-
- } else
- log.info("Only eIDAS LoAs are supported by this implementation");
-
- } else {
- log.info("No QAA level found. Set to default level " + EAAFConstants.EIDAS_LOA_LOW);
- authData.seteIDASLoA(EAAFConstants.EIDAS_LOA_LOW);
-
- }
-
- }
-
- /**
- * Parse Foreigner information into AuthData
- *
- * @param authData
- * @param authProcessData
- * @param pendingReq
- */
- private void setFlagForeigner(AuthenticationData authData, IAuthProcessDataContainer authProcessData, IRequest pendingReq) {
- //TODO: change to new eIDAS-token attribute identifier
- if (authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_STORK_TOKEN_NAME) != null) {
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_STORK_TOKEN_FRIENDLY_NAME
- + " --> Set 'isForeigner' flag to TRUE");
- authData.setForeigner(true);
-
- } else {
- authData.setForeigner(authProcessData.isForeigner());
-
- }
- }
-
- /**
- * Build authentication data by using information from citizen-card or mobile-phone signature
- * This builder uses IdentityLink, AuthBlock, full MIS mandate as input information
- *
- * @param pendingReq current pendingRequest
- * @return {@link IAuthData} but never <code>null</code>
- * @throws EAAFException
- */
- @Deprecated
- @NonNull
- abstract protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EAAFException;
-
- @Deprecated
- protected void generateDeprecatedBasicAuthData(AuthenticationData authData, IRequest pendingReq,
- IAuthProcessDataContainer authProcessData) throws EAAFBuilderException, EAAFConfigurationException, XPathException, DOMException, EAAFParserException {
-
- if (authProcessData.getGenericSessionDataStorage() != null &&
- !authProcessData.getGenericSessionDataStorage().isEmpty())
- includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
- else
- includedToGenericAuthData = new ArrayList<String>();
-
- //####################################################
- //set general authData info's
- authData.setAuthenticationIssuer(pendingReq.getAuthURL());
- authData.setSsoSession(pendingReq.needSingleSignOnFunctionality());
- authData.setBaseIDTransferRestrication(pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction());
-
-
- //####################################################
- //parse user info's from identityLink
- IIdentityLink idlFromPVPAttr = null;
- final IIdentityLink identityLink = authProcessData.getIdentityLink();
- if (identityLink != null) {
- parseBasicUserInfosFromIDL(authData, identityLink, includedToGenericAuthData);
-
- } else {
- // identityLink is not direct in MOASession
- final String pvpAttrIDL = authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME, String.class);
- //find PVP-Attr. which contains the IdentityLink
- if (StringUtils.isNotEmpty(pvpAttrIDL)) {
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_IDENTITY_LINK_FRIENDLY_NAME
- + " --> Parse basic user info's from that attribute.");
- InputStream idlStream = null;
- try {
- idlStream = new ByteArrayInputStream(Base64Utils.decodeFromString(pvpAttrIDL));
- idlFromPVPAttr = new SimpleIdentityLinkAssertionParser(idlStream).parseIdentityLink();
- parseBasicUserInfosFromIDL(authData, idlFromPVPAttr, includedToGenericAuthData);
-
- //set identitylink into AuthProcessData
- authProcessData.setIdentityLink(idlFromPVPAttr);;
-
- } catch (final EAAFParserException e) {
- log.warn("Received IdentityLink is not valid", e);
-
- } catch (final Exception e) {
- log.warn("Received IdentityLink is not valid", e);
-
- } finally {
- try {
- includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME);
- if (idlStream != null)
- idlStream.close();
-
- } catch (final IOException e) {
- log.warn("Close InputStream FAILED.", e);
-
- }
- }
- }
-
- //if no basic user info's are set yet, parse info's single PVP-Attributes
- if (StringUtils.isEmpty(authData.getFamilyName())) {
- log.debug("No IdentityLink found or not parseable --> Parse basic user info's from single PVP-Attributes.");
- authData.setFamilyName(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class));
- authData.setGivenName(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.GIVEN_NAME_NAME, String.class));
- authData.setDateOfBirth(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.BIRTHDATE_NAME, String.class));
- authData.setIdentificationValue(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME, String.class));
- authData.setIdentificationType(authProcessData.getGenericDataFromSession(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME, String.class));
-
- //remove corresponding keys from genericSessionData if exists
- includedToGenericAuthData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
- includedToGenericAuthData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
- includedToGenericAuthData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
- includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
- includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
- }
-
- }
-
- if (authData.getIdentificationType() != null &&
- !authData.getIdentificationType().equals(EAAFConstants.URN_PREFIX_BASEID)) {
- log.trace("IdentificationType is not a baseID --> clear it. ");
- authData.setBPK(authData.getIdentificationValue());
- authData.setBPKType(authData.getIdentificationType());
-
- authData.setIdentificationValue(null);
- authData.setIdentificationType(null);
- }
-
-
- //####################################################
- //set QAA level
- setQAALevel(authData, authProcessData, pendingReq);
-
-
- //####################################################
- //set isForeigner flag
- setFlagForeigner(authData, authProcessData, pendingReq);
-
-
- //####################################################
- //set citizen country-code
- setCitizenCountryCode(authData, authProcessData, pendingReq);
-
-
- //####################################################
- // set bPK and IdentityLink
- final String pvpbPKValue = getbPKValueFromPVPAttribute(authProcessData);
- final String pvpbPKTypeAttr = getbPKTypeFromPVPAttribute(authProcessData);
- final Pair<String, String> pvpEncbPKAttr = getEncryptedbPKFromPVPAttribute(authProcessData, authData, pendingReq.getServiceProviderConfiguration());
-
- //check if a unique ID for this citizen exists
- if (StringUtils.isEmpty(authData.getIdentificationValue()) &&
- StringUtils.isEmpty(pvpbPKValue) && StringUtils.isEmpty(authData.getBPK()) &&
- pvpEncbPKAttr == null) {
- log.info("Can not build authData, because moaSession include no bPK, encrypted bPK or baseID");
- throw new EAAFBuilderException("builder.08", new Object[]{"No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME},
- "No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
-
- }
-
- //check if bPK already added to AuthData matches OA
- if (StringUtils.isNotEmpty(authData.getBPK())
- && matchsReceivedbPKToOnlineApplication(pendingReq.getServiceProviderConfiguration(), authData.getBPKType()) ) {
- log.debug("Correct bPK is already included in AuthData.");
-
- //check if bPK received by PVP-Attribute matches OA
- } else if (StringUtils.isNotEmpty(pvpbPKValue) &&
- matchsReceivedbPKToOnlineApplication(pendingReq.getServiceProviderConfiguration(), pvpbPKTypeAttr)) {
- log.debug("Receive correct bPK from PVP-Attribute");
- authData.setBPK(pvpbPKValue);
- authData.setBPKType(pvpbPKTypeAttr);
-
- // baseID is in AuthSesson --> calculate bPK directly
- } else if (StringUtils.isNotEmpty(authData.getIdentificationValue())) {
- log.debug("Citizen baseID is in MOASession --> calculate bPK from this.");
- final Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
- authData.setBPK(result.getFirst());
- authData.setBPKType(result.getSecond());
-
- //check if decrypted bPK exists
- } else if (pvpEncbPKAttr != null) {
- log.debug("Receive bPK as encrypted bPK and decryption was possible.");
- authData.setBPK(pvpEncbPKAttr.getFirst());
- authData.setBPKType(pvpEncbPKAttr.getSecond());
-
- //ask SZR to get bPK
- } else {
- String notValidbPK = authData.getBPK();
- String notValidbPKType = authData.getBPKType();
- if (StringUtils.isEmpty(notValidbPK) &&
- StringUtils.isEmpty(notValidbPKType)) {
- notValidbPK = pvpbPKValue;
- notValidbPKType = pvpbPKTypeAttr;
-
- if (StringUtils.isEmpty(notValidbPK) &&
- StringUtils.isEmpty(notValidbPKType)) {
- log.error("No bPK in MOASession. THIS error should not occur any more.");
- throw new NullPointerException("No bPK in MOASession. THIS error should not occur any more.");
- }
- }
-
- final Pair<String, String> baseIDFromSZR = getbaseIDFromSZR(authData, notValidbPK, notValidbPKType);
- if (baseIDFromSZR != null) {
- log.info("Receive citizen baseID from SRZ. Authentication can be completed");
- authData.setIdentificationValue(baseIDFromSZR.getFirst());
- authData.setIdentificationType(baseIDFromSZR.getSecond());
- final Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
- authData.setBPK(result.getFirst());
- authData.setBPKType(result.getSecond());
-
- } else {
- log.warn("Can not build authData, because moaSession include no valid bPK, encrypted bPK or sourceID");
- throw new EAAFBuilderException("builder.13", new Object[]{pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()},
- "No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME
- + " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
-
- }
- }
-
- //build IdentityLink
- if (authProcessData.getIdentityLink() != null)
- authData.setIdentityLink(buildOAspecificIdentityLink(
- pendingReq.getServiceProviderConfiguration(),
- authProcessData.getIdentityLink(),
- authData.getBPK(),
- authData.getBPKType()));
- else
- log.info("Can NOT set IdentityLink. Msg: No IdentityLink found");
-
- }
-
- //extract a encrypted bPK from PVP attrobute
- @Deprecated
- protected abstract Pair<String, String> getEncryptedbPKFromPVPAttribute(IAuthProcessDataContainer authProcessDataContainer,
- AuthenticationData authData, ISPConfiguration spConfig) throws EAAFBuilderException;
-
- //request baseId from SRZ
- @Deprecated
- protected abstract Pair<String, String> getbaseIDFromSZR(AuthenticationData authData, String notValidbPK,
- String notValidbPKType);
-
- @Deprecated
- protected Pair<String, String> buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) throws EAAFBuilderException {
- final ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
-
- final String baseID = authData.getIdentificationValue();
- final String baseIDType = authData.getIdentificationType();
- Pair<String, String> sectorSpecId = null;
-
- if (EAAFConstants.URN_PREFIX_BASEID.equals(baseIDType)) {
- //SAML1 legacy target parameter work-around
- final String spTargetId = oaParam.getAreaSpecificTargetIdentifier();
- log.debug("Use OA target identifier '" + spTargetId + "' from configuration");
-
- //calculate sector specific unique identifier
- sectorSpecId = new BPKBuilder().generateAreaSpecificPersonIdentifier(baseID, spTargetId);
-
- } else {
- log.error("!!!baseID-element does not include a baseID. This should not be happen any more!!!");
- sectorSpecId = Pair.newInstance(baseID, baseIDType);
-
- }
-
- log.trace("Authenticate user with bPK:" + sectorSpecId.getFirst() + " Type:" + sectorSpecId.getSecond());
- return sectorSpecId;
-
- }
-
- @Deprecated
- protected IIdentityLink buildOAspecificIdentityLink(ISPConfiguration spConfig, IIdentityLink idl, String bPK, String bPKType) throws EAAFConfigurationException, XPathException, DOMException, EAAFParserException {
- if (spConfig.hasBaseIdTransferRestriction()) {
- log.debug("SP: " + spConfig.getUniqueIdentifier() + " has baseId transfer restriction. Remove baseId from IDL ...");
- final Element idlassertion = idl.getSamlAssertion();
- //set bpk/wpbk;
- final Node prIdentification = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
- prIdentification.getFirstChild().setNodeValue(bPK);
- //set bkp/wpbk type
- final Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH);
- prIdentificationType.getFirstChild().setNodeValue(bPKType);
-
- final SimpleIdentityLinkAssertionParser idlparser = new SimpleIdentityLinkAssertionParser(idlassertion);
- return idlparser.parseIdentityLink();
-
- } else
- return idl;
-
- }
-
- /**
- * Check a bPK-Type against a Service-Provider configuration <br>
- * If bPK-Type is <code>null</code> the result is <code>false</code>.
- *
- * @param oaParam Service-Provider configuration, never null
- * @param bPKType bPK-Type to check
- * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise false
- */
- @Deprecated
- protected boolean matchsReceivedbPKToOnlineApplication(ISPConfiguration oaParam, String bPKType) {
- return oaParam.getAreaSpecificTargetIdentifier().equals(bPKType);
-
- }
-
- /**
- * Parse information from an IdentityLink into AuthData object
- *
- * @param authData
- * @param identityLink
- * @param includedGenericSessionData
- */
- @Deprecated
- private void parseBasicUserInfosFromIDL(AuthenticationData authData, IIdentityLink identityLink, Collection<String> includedGenericSessionData) {
- authData.setIdentificationValue(identityLink.getIdentificationValue());
- authData.setIdentificationType(identityLink.getIdentificationType());
-
- /* GivenNames and FamilyNames with simple Apostrophe were escaped with &#39;
- * in IdentityLinkParser since 5 years. This feature was bug-fix for an SL1.0 AuthBlock problem.
- * However, the authentication attributes (SAML2, eIDAS, OpenID-Connect) also includes this escaped values,
- * but there it is not neccesary. We fix this problem in 3.4.3, but the fix can be deactivated
- * for dependency reasons.
- */
- if (basicConfig.getBasicConfigurationBoolean(CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING, false)) {
- authData.setGivenName(identityLink.getGivenName().replaceAll("'", "&#39;"));
- authData.setFamilyName(identityLink.getFamilyName().replaceAll("'", "&#39;"));
-
- } else {
- authData.setGivenName(identityLink.getGivenName());
- authData.setFamilyName(identityLink.getFamilyName());
-
- }
-
- authData.setDateOfBirth(identityLink.getDateOfBirth());
-
-
- //remove corresponding keys from genericSessionData if exists
- includedGenericSessionData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
- includedGenericSessionData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
- includedGenericSessionData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
- includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
- includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
-
- }
-
- /**
- * Get bPK from PVP Attribute 'BPK_NAME', which could be exist in
- * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class)</code></pre>
- *
- * @param session MOASession, but never null
- * @return bPK, which was received by PVP-Attribute, or <code>null</code> if no attribute exists
- */
- @Deprecated
- private String getbPKValueFromPVPAttribute(IAuthProcessDataContainer session) {
- String pvpbPKValueAttr = session.getGenericDataFromSession(PVPAttributeDefinitions.BPK_NAME, String.class);
- if (StringUtils.isNotEmpty(pvpbPKValueAttr)) {
-
- //fix a wrong bPK-value prefix, which was used in some PVP Standardportal implementations
- if (pvpbPKValueAttr.startsWith("bPK:")) {
- log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME
- + " contains a not standardize prefix! Staring attribute value correction process ...");
- pvpbPKValueAttr = pvpbPKValueAttr.substring("bPK:".length());
-
- }
-
- final String[] spitted = pvpbPKValueAttr.split(":");
- if (spitted.length == 2) {
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME);
- return spitted[1];
-
-
-
- } else if (spitted.length > 2) {
- log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME + " has a wrong encoding and can NOT be USED!"
- + " Value:" + pvpbPKValueAttr);
- return null;
-
- } else {
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME + " without prefix. Use it as it is");
- return spitted[0];
-
- }
-
- }
-
- return null;
- }
-
- /**
- * Get bPK-Type from PVP Attribute 'EID_SECTOR_FOR_IDENTIFIER_NAME', which could be exist in
- * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class)</code></pre>
- *
- * @param session MOASession, but never null
- * @return bPKType, which was received by PVP-Attribute, or <code>null</code> if no attribute exists
- */
- @Deprecated
- private String getbPKTypeFromPVPAttribute(IAuthProcessDataContainer session) {
- final String pvpbPKTypeAttr = session.getGenericDataFromSession(PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class);
-
- if (StringUtils.isNotEmpty(pvpbPKTypeAttr)) {
-// //fix a wrong bPK-Type encoding, which was used in some PVP Standardportal implementations
-// if (pvpbPKTypeAttr.startsWith(EAAFConstants.URN_PREFIX_CDID) &&
-// !pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length(),
-// EAAFConstants.URN_PREFIX_CDID.length() + 1).equals("+")) {
-// log.warn("Receive uncorrect encoded bBKType attribute " + pvpbPKTypeAttr + " Starting attribute value correction ... ");
-// pvpbPKTypeAttr = EAAFConstants.URN_PREFIX_CDID + "+" + pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length() + 1);
-//
-// }
- log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME);
- return pvpbPKTypeAttr;
- }
-
- return null;
-
-
- /*
- * INFO: This code could be used to extract the bPKType from 'PVPConstants.BPK_NAME',
- * because the prefix of BPK_NAME attribute contains the postfix of the bPKType
- *
- * Now, all PVP Standardportals should be able to send 'EID_SECTOR_FOR_IDENTIFIER'
- * PVP attributes
- */
-// String pvpbPKValueAttr = session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class);
-// String[] spitted = pvpbPKValueAttr.split(":");
-// if (MiscUtil.isEmpty(authData.getBPKType())) {
-// Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " +
-// "Starting target extraction from bPK/wbPK prefix ...");
-// //exract bPK/wbPK type from bpk attribute value prefix if type is
-// //not transmitted as single attribute
-// Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?");
-// Matcher matcher = pattern.matcher(spitted[0]);
-// if (matcher.matches()) {
-// //find public service bPK
-// authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]);
-// Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType());
-//
-// } else {
-// //find business service wbPK
-// authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]);
-// Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType());
-//
-// }
-// }
-
- }
+ private static final Logger log =
+ LoggerFactory.getLogger(AbstractAuthenticationDataBuilder.class);
+
+ /**
+ * Identify authProcessData that should be directly mapped into authData.
+ */
+ public static final String GENERIC_AUTHDATA_IDENTIFIER = "authData_";
+
+ public static final String CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING =
+ "configuration.bugfix.enable.idl.escaping";
+
+ protected Collection<String> includedToGenericAuthData = null;
+ @Autowired
+ protected IConfigurationWithSP basicConfig;
+
+ @Override
+ public IAuthData buildAuthenticationData(final IRequest pendingReq)
+ throws EaafAuthenticationException {
+ IAuthData authData = null;
+ final IAuthProcessDataContainer authProcessData =
+ pendingReq.getSessionData(AuthProcessDataWrapper.class);
+
+ try {
+ if (authProcessData.isEIDProcess()) {
+ log.debug("Building AuthData from new E-ID information ... ");
+ authData = getAuthDataInstance(pendingReq);
+ Assert.notNull(authData, "AuthData is null");
+
+ log.trace("Adding generic AuthData information ... ");
+ buildInternalAuthDataGeneric(authData, authProcessData, pendingReq);
+
+ log.trace("Build service-specific AuthData information ... ");
+ buildServiceSpecificAuthenticationData(authData, pendingReq);
+
+ } else {
+ log.info(
+ "User authentication uses the deprecated. Building AuthData from deprecated information ... ");
+ authData = buildDeprecatedAuthData(pendingReq);
+ Assert.notNull(authData, "AuthData is null");
+
+ }
+
+ } catch (final EaafAuthenticationException e) {
+ throw e;
+
+ } catch (XPathException | DOMException | EaafException e) {
+ log.warn("Can not build authentication data from auth. process information");
+ throw new EaafAuthenticationException("builder.11", new Object[] {e.getMessage()}, e);
+
+ }
+
+ log.trace("AuthData generation finished");
+ return authData;
+
+ }
+
+ /**
+ * * @param pendingReq current pendingRequest.
+ *
+ * @param pendingReq current pendingRequest
+ * @return {@link IAuthData} but never <code>null</code>
+ * @throws EaafException In case of an error
+ */
+ @NonNull
+ protected abstract IAuthData getAuthDataInstance(IRequest pendingReq) throws EaafException;
+
+ /**
+ * Build service-specific AuthData by using information from E-ID This builder uses vSZ, MDS and
+ * Consent as input information.
+ *
+ * @param pendingReq current pendingRequest
+ * @return {@link IAuthData} but never <code>null</code>
+ * @throws EaafException In case of an error
+ */
+ protected abstract void buildServiceSpecificAuthenticationData(IAuthData authData,
+ IRequest pendingReq) throws EaafException;
+
+
+ /**
+ * Add generic E-ID information into already existing AuthData.
+ *
+ * @param authData AuthData object
+ * @param authProcessData Authentication information holder from current pending request
+ * @param pendingReq current pending request
+ */
+ private void buildInternalAuthDataGeneric(@NonNull final IAuthData authData,
+ @NonNull final IAuthProcessDataContainer authProcessData,
+ @NonNull final IRequest pendingReq) {
+ Assert.notNull(pendingReq, "PendingRequest is null");
+ Assert.notNull(authData, "AuthData is null");
+ Assert.notNull(authProcessData, "AuthProcessData is null");
+
+ if (!(authData instanceof AuthenticationData)) {
+ log.error("AuthData has no suitable type! Requires: {}", AuthenticationData.class.getName());
+ throw new RuntimeException(
+ "AuthData has no suitable type! Requires: " + AuthenticationData.class.getName());
+
+ }
+
+ final AuthenticationData internalAuthData = (AuthenticationData) authData;
+
+ // TODO: check if it is needed
+ // if (authProcessData.getGenericSessionDataStorage() != null &&
+ // !authProcessData.getGenericSessionDataStorage().isEmpty())
+ // includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
+ // else
+ includedToGenericAuthData = new ArrayList<>();
+
+ // ####################################################
+ // set general authData info's
+ internalAuthData.setAuthenticationIssuer(pendingReq.getAuthUrl());
+ internalAuthData.setSsoSession(pendingReq.needSingleSignOnFunctionality());
+ internalAuthData.setBaseIdTransferRestrication(
+ pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction());
+
+ // ####################################################
+ // set MDS and vSZ
+ internalAuthData.setFamilyName(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class));
+ internalAuthData.setGivenName(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.GIVEN_NAME_NAME, String.class));
+ internalAuthData.setDateOfBirth(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.BIRTHDATE_NAME, String.class));
+ internalAuthData.setEncSourceId(authProcessData.getGenericDataFromSession(
+ ExtendedPVPAttributeDefinitions.EID_ENCRYPTED_SOURCEID_NAME, String.class));
+ internalAuthData.setEncSourceIdType(authProcessData.getGenericDataFromSession(
+ ExtendedPVPAttributeDefinitions.EID_ENCRYPTED_SOURCEID_TYPE_NAME, String.class));
+
+ // ####################################################
+ // set QAA level
+ setQaaLevel(internalAuthData, authProcessData, pendingReq);
+
+
+ // ####################################################
+ // set isForeigner flag
+ setFlagForeigner(internalAuthData, authProcessData, pendingReq);
+
+
+ // ####################################################
+ // set citizen country-code
+ setCitizenCountryCode(internalAuthData, authProcessData, pendingReq);
+
+
+ // set generic authProcessData to authdata
+ for (final Entry<String, Object> el : authProcessData.getGenericSessionDataStorage()
+ .entrySet()) {
+ if (el.getKey().startsWith(GENERIC_AUTHDATA_IDENTIFIER)) {
+ log.trace("Find generic authProcessData {}. Map it directly to authData", el.getKey());
+ try {
+ internalAuthData.setGenericData(el.getKey(), el.getValue());
+
+ } catch (final EaafStorageException e) {
+ log.warn("Can NOT set authData with key: {}", el.getKey(), null, e);
+
+ }
+
+ }
+
+ }
+
+
+ }
+
+ /**
+ * Parse citzen country-code into AuthData.
+ *
+ * @param authData Current authentication data
+ * @param authProcessData Authentication information holder from current pending request
+ * @param pendingReq Current pending request
+ */
+ private void setCitizenCountryCode(final AuthenticationData authData,
+ final IAuthProcessDataContainer authProcessData, final IRequest pendingReq) {
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME);
+ final String pvpCccAttr = authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
+ if (StringUtils.isNotEmpty(pvpCccAttr)) {
+ authData.setCiticenCountryCode(pvpCccAttr);
+ log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME);
+
+ } else {
+ if (authData.isForeigner()) {
+ // TODO!!!!
+
+ } else {
+ authData.setCiticenCountryCode(basicConfig.getBasicConfiguration(
+ IConfigurationWithSP.CONFIG_PROPS_AUTH_DEFAULT_COUNTRYCODE,
+ EAAFConstants.COUNTRYCODE_AUSTRIA));
+
+ }
+ }
+
+ }
+
+ /**
+ * parse QAA Level into AuthData.
+ *
+ * @param authData current authentication data
+ * @param authProcessData Authentication information holder from current pending request
+ * @param pendingReq current pending request
+ */
+ private void setQaaLevel(@NonNull final AuthenticationData authData,
+ @NonNull final IAuthProcessDataContainer authProcessData,
+ @NonNull final IRequest pendingReq) {
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
+ String currentLoA = null;
+ if (StringUtils.isNotEmpty(authProcessData.getQAALevel())) {
+ currentLoA = authProcessData.getQAALevel();
+ } else {
+ currentLoA = authProcessData.getGenericDataFromSession(
+ PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, String.class);
+ if (StringUtils.isNotEmpty(currentLoA)) {
+ log.debug(
+ "Find PVP-Attr '" + PVPAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME
+ + "':" + currentLoA + " --> Parse QAA-Level from that attribute.");
+
+ }
+ }
+ if (StringUtils.isNotEmpty(currentLoA)) {
+ if (currentLoA.startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) {
+ authData.setEidasLoa(currentLoA);
+
+ } else {
+ log.info("Only eIDAS LoAs are supported by this implementation");
+ }
+
+ } else {
+ log.info("No QAA level found. Set to default level " + EAAFConstants.EIDAS_LOA_LOW);
+ authData.setEidasLoa(EAAFConstants.EIDAS_LOA_LOW);
+
+ }
+
+ }
+
+
+ private void setFlagForeigner(final AuthenticationData authData,
+ final IAuthProcessDataContainer authProcessData, final IRequest pendingReq) {
+ // TODO: change to new eIDAS-token attribute identifier
+ if (authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.EID_STORK_TOKEN_NAME) != null) {
+ log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_STORK_TOKEN_FRIENDLY_NAME
+ + " --> Set 'isForeigner' flag to TRUE");
+ authData.setForeigner(true);
+
+ } else {
+ authData.setForeigner(authProcessData.isForeigner());
+
+ }
+ }
+
+ /**
+ * Build authentication data by using information from citizen-card or mobile-phone signature This
+ * builder uses IdentityLink, AuthBlock, full MIS mandate as input information.
+ *
+ * @param pendingReq current pendingRequest
+ * @return {@link IAuthData} but never <code>null</code>
+ * @throws EaafException In case of an error
+ */
+ @Deprecated
+ @NonNull
+ protected abstract IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException;
+
+ @Deprecated
+ protected void generateDeprecatedBasicAuthData(final AuthenticationData authData,
+ final IRequest pendingReq, final IAuthProcessDataContainer authProcessData)
+ throws EaafBuilderException, EaafConfigurationException, XPathException, DOMException,
+ EaafParserException {
+
+ if (authProcessData.getGenericSessionDataStorage() != null
+ && !authProcessData.getGenericSessionDataStorage().isEmpty()) {
+ includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
+ } else {
+ includedToGenericAuthData = new ArrayList<>();
+ }
+
+ // ####################################################
+ // set general authData info's
+ authData.setAuthenticationIssuer(pendingReq.getAuthUrl());
+ authData.setSsoSession(pendingReq.needSingleSignOnFunctionality());
+ authData.setBaseIdTransferRestrication(
+ pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction());
+
+
+ // ####################################################
+ // parse user info's from identityLink
+ IIdentityLink idlFromPvpAttr = null;
+ final IIdentityLink identityLink = authProcessData.getIdentityLink();
+ if (identityLink != null) {
+ parseBasicUserInfosFromIdl(authData, identityLink, includedToGenericAuthData);
+
+ } else {
+ // identityLink is not direct in MOASession
+ final String pvpAttrIdl = authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME, String.class);
+ // find PVP-Attr. which contains the IdentityLink
+ if (StringUtils.isNotEmpty(pvpAttrIdl)) {
+ log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.EID_IDENTITY_LINK_FRIENDLY_NAME
+ + " --> Parse basic user info's from that attribute.");
+ InputStream idlStream = null;
+ try {
+ idlStream = new ByteArrayInputStream(Base64Utils.decodeFromString(pvpAttrIdl));
+ idlFromPvpAttr = new SimpleIdentityLinkAssertionParser(idlStream).parseIdentityLink();
+ parseBasicUserInfosFromIdl(authData, idlFromPvpAttr, includedToGenericAuthData);
+
+ // set identitylink into AuthProcessData
+ authProcessData.setIdentityLink(idlFromPvpAttr);
+
+ } catch (final EaafParserException e) {
+ log.warn("Received IdentityLink is not valid", e);
+
+ } catch (final Exception e) {
+ log.warn("Received IdentityLink is not valid", e);
+
+ } finally {
+ try {
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_IDENTITY_LINK_NAME);
+ if (idlStream != null) {
+ idlStream.close();
+ }
+
+ } catch (final IOException e) {
+ log.warn("Close InputStream FAILED.", e);
+
+ }
+ }
+ }
+
+ // if no basic user info's are set yet, parse info's single PVP-Attributes
+ if (StringUtils.isEmpty(authData.getFamilyName())) {
+ log.debug(
+ "No IdentityLink found or not parseable --> Parse basic user info's from single PVP-Attributes.");
+ authData.setFamilyName(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class));
+ authData.setGivenName(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.GIVEN_NAME_NAME, String.class));
+ authData.setDateOfBirth(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.BIRTHDATE_NAME, String.class));
+ authData.setIdentificationValue(authProcessData
+ .getGenericDataFromSession(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME, String.class));
+ authData.setIdentificationType(authProcessData.getGenericDataFromSession(
+ PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME, String.class));
+
+ // remove corresponding keys from genericSessionData if exists
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
+ includedToGenericAuthData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
+ }
+
+ }
+
+ if (authData.getIdentificationType() != null
+ && !authData.getIdentificationType().equals(EAAFConstants.URN_PREFIX_BASEID)) {
+ log.trace("IdentificationType is not a baseID --> clear it. ");
+ authData.setBpk(authData.getIdentificationValue());
+ authData.setBpkType(authData.getIdentificationType());
+
+ authData.setIdentificationValue(null);
+ authData.setIdentificationType(null);
+ }
+
+
+ // ####################################################
+ // set QAA level
+ setQaaLevel(authData, authProcessData, pendingReq);
+
+
+ // ####################################################
+ // set isForeigner flag
+ setFlagForeigner(authData, authProcessData, pendingReq);
+
+
+ // ####################################################
+ // set citizen country-code
+ setCitizenCountryCode(authData, authProcessData, pendingReq);
+
+
+ // ####################################################
+ // set bPK and IdentityLink
+ final String pvpBpkValue = getBpkValueFromPvpAttribute(authProcessData);
+ final String pvpBpkTypeAttr = getBpkTypeFromPvpAttribute(authProcessData);
+ final Pair<String, String> pvpEncBpkAttr = getEncryptedBpkFromPvpAttribute(authProcessData,
+ authData, pendingReq.getServiceProviderConfiguration());
+
+ // check if a unique ID for this citizen exists
+ if (StringUtils.isEmpty(authData.getIdentificationValue()) && StringUtils.isEmpty(pvpBpkValue)
+ && StringUtils.isEmpty(authData.getBpk()) && pvpEncBpkAttr == null) {
+ log.info(
+ "Can not build authData, because moaSession include no bPK, encrypted bPK or baseID");
+ throw new EaafBuilderException("builder.08",
+ new Object[] {"No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME},
+ "No " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
+
+ }
+
+ // check if bPK already added to AuthData matches OA
+ if (StringUtils.isNotEmpty(authData.getBpk()) && matchsReceivedBpkToOnlineApplication(
+ pendingReq.getServiceProviderConfiguration(), authData.getBpkType())) {
+ log.debug("Correct bPK is already included in AuthData.");
+
+ // check if bPK received by PVP-Attribute matches OA
+ } else if (StringUtils.isNotEmpty(pvpBpkValue) && matchsReceivedBpkToOnlineApplication(
+ pendingReq.getServiceProviderConfiguration(), pvpBpkTypeAttr)) {
+ log.debug("Receive correct bPK from PVP-Attribute");
+ authData.setBpk(pvpBpkValue);
+ authData.setBpkType(pvpBpkTypeAttr);
+
+ // baseID is in AuthSesson --> calculate bPK directly
+ } else if (StringUtils.isNotEmpty(authData.getIdentificationValue())) {
+ log.debug("Citizen baseID is in MOASession --> calculate bPK from this.");
+ final Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
+ authData.setBpk(result.getFirst());
+ authData.setBpkType(result.getSecond());
+
+ // check if decrypted bPK exists
+ } else if (pvpEncBpkAttr != null) {
+ log.debug("Receive bPK as encrypted bPK and decryption was possible.");
+ authData.setBpk(pvpEncBpkAttr.getFirst());
+ authData.setBpkType(pvpEncBpkAttr.getSecond());
+
+ // ask SZR to get bPK
+ } else {
+ String notValidbPK = authData.getBpk();
+ String notValidBpkType = authData.getBpkType();
+ if (StringUtils.isEmpty(notValidbPK) && StringUtils.isEmpty(notValidBpkType)) {
+ notValidbPK = pvpBpkValue;
+ notValidBpkType = pvpBpkTypeAttr;
+
+ if (StringUtils.isEmpty(notValidbPK) && StringUtils.isEmpty(notValidBpkType)) {
+ log.error("No bPK in MOASession. THIS error should not occur any more.");
+ throw new NullPointerException(
+ "No bPK in MOASession. THIS error should not occur any more.");
+ }
+ }
+
+ final Pair<String, String> baseIdFromSzr =
+ getbaseIdFromSzr(authData, notValidbPK, notValidBpkType);
+ if (baseIdFromSzr != null) {
+ log.info("Receive citizen baseID from SRZ. Authentication can be completed");
+ authData.setIdentificationValue(baseIdFromSzr.getFirst());
+ authData.setIdentificationType(baseIdFromSzr.getSecond());
+ final Pair<String, String> result = buildOAspecificbPK(pendingReq, authData);
+ authData.setBpk(result.getFirst());
+ authData.setBpkType(result.getSecond());
+
+ } else {
+ log.warn(
+ "Can not build authData, because moaSession include no valid bPK, encrypted bPK or sourceID");
+ throw new EaafBuilderException("builder.13",
+ new Object[] {
+ pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()},
+ "No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or "
+ + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME);
+
+ }
+ }
+
+ // build IdentityLink
+ if (authProcessData.getIdentityLink() != null) {
+ authData
+ .setIdentityLink(buildOAspecificIdentityLink(pendingReq.getServiceProviderConfiguration(),
+ authProcessData.getIdentityLink(), authData.getBpk(), authData.getBpkType()));
+ } else {
+ log.info("Can NOT set IdentityLink. Msg: No IdentityLink found");
+ }
+
+ }
+
+ // extract a encrypted bPK from PVP attrobute
+ @Deprecated
+ protected abstract Pair<String, String> getEncryptedBpkFromPvpAttribute(
+ IAuthProcessDataContainer authProcessDataContainer, AuthenticationData authData,
+ IspConfiguration spConfig) throws EaafBuilderException;
+
+ // request baseId from SRZ
+ @Deprecated
+ protected abstract Pair<String, String> getbaseIdFromSzr(AuthenticationData authData,
+ String notValidBpk, String notValidBpkType);
+
+ @Deprecated
+ protected Pair<String, String> buildOAspecificbPK(final IRequest pendingReq,
+ final AuthenticationData authData) throws EaafBuilderException {
+ final IspConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+
+ final String baseID = authData.getIdentificationValue();
+ final String baseIdType = authData.getIdentificationType();
+ Pair<String, String> sectorSpecId = null;
+
+ if (EAAFConstants.URN_PREFIX_BASEID.equals(baseIdType)) {
+ // SAML1 legacy target parameter work-around
+ final String spTargetId = oaParam.getAreaSpecificTargetIdentifier();
+ log.debug("Use OA target identifier '" + spTargetId + "' from configuration");
+
+ new BpkBuilder();
+ // calculate sector specific unique identifier
+ sectorSpecId = BpkBuilder.generateAreaSpecificPersonIdentifier(baseID, spTargetId);
+
+ } else {
+ log.error(
+ "!!!baseID-element does not include a baseID. This should not be happen any more!!!");
+ sectorSpecId = Pair.newInstance(baseID, baseIdType);
+
+ }
+
+ log.trace("Authenticate user with bPK:" + sectorSpecId.getFirst() + " Type:"
+ + sectorSpecId.getSecond());
+ return sectorSpecId;
+
+ }
+
+ @Deprecated
+ protected IIdentityLink buildOAspecificIdentityLink(final IspConfiguration spConfig,
+ final IIdentityLink idl, final String bpk, final String bpkType)
+ throws EaafConfigurationException, XPathException, DOMException, EaafParserException {
+ if (spConfig.hasBaseIdTransferRestriction()) {
+ log.debug("SP: " + spConfig.getUniqueIdentifier()
+ + " has baseId transfer restriction. Remove baseId from IDL ...");
+ final Element idlassertion = idl.getSamlAssertion();
+ // set bpk/wpbk;
+ final Node prIdentification = XPathUtils.selectSingleNode(idlassertion,
+ SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
+ prIdentification.getFirstChild().setNodeValue(bpk);
+ // set bkp/wpbk type
+ final Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion,
+ SimpleIdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH);
+ prIdentificationType.getFirstChild().setNodeValue(bpkType);
+
+ final SimpleIdentityLinkAssertionParser idlparser =
+ new SimpleIdentityLinkAssertionParser(idlassertion);
+ return idlparser.parseIdentityLink();
+
+ } else {
+ return idl;
+ }
+
+ }
+
+ /**
+ * Check a bPK-Type against a Service-Provider configuration <br>
+ * If bPK-Type is <code>null</code> the result is <code>false</code>.
+ *
+ * @param oaParam Service-Provider configuration, never null
+ * @param bpkType bPK-Type to check
+ * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise false
+ */
+ @Deprecated
+ protected boolean matchsReceivedBpkToOnlineApplication(final IspConfiguration oaParam,
+ final String bpkType) {
+ return oaParam.getAreaSpecificTargetIdentifier().equals(bpkType);
+
+ }
+
+ /**
+ * Parse information from an IdentityLink into AuthData object.
+ *
+ * @param authData current authentication data
+ * @param identityLink User's identityLink
+ * @param includedGenericSessionData Generic AuthSession Data from PVP attributes
+ */
+ @Deprecated
+ private void parseBasicUserInfosFromIdl(final AuthenticationData authData,
+ final IIdentityLink identityLink, final Collection<String> includedGenericSessionData) {
+ authData.setIdentificationValue(identityLink.getIdentificationValue());
+ authData.setIdentificationType(identityLink.getIdentificationType());
+
+ /*
+ * GivenNames and FamilyNames with simple Apostrophe were escaped with &#39; in
+ * IdentityLinkParser since 5 years. This feature was bug-fix for an SL1.0 AuthBlock problem.
+ * However, the authentication attributes (SAML2, eIDAS, OpenID-Connect) also includes this
+ * escaped values, but there it is not neccesary. We fix this problem in 3.4.3, but the fix can
+ * be deactivated for dependency reasons.
+ */
+ if (basicConfig.getBasicConfigurationBoolean(CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING,
+ false)) {
+ authData.setGivenName(identityLink.getGivenName().replaceAll("'", "&#39;"));
+ authData.setFamilyName(identityLink.getFamilyName().replaceAll("'", "&#39;"));
+
+ } else {
+ authData.setGivenName(identityLink.getGivenName());
+ authData.setFamilyName(identityLink.getFamilyName());
+
+ }
+
+ authData.setDateOfBirth(identityLink.getDateOfBirth());
+
+
+ // remove corresponding keys from genericSessionData if exists
+ includedGenericSessionData.remove(PVPAttributeDefinitions.PRINCIPAL_NAME_NAME);
+ includedGenericSessionData.remove(PVPAttributeDefinitions.GIVEN_NAME_NAME);
+ includedGenericSessionData.remove(PVPAttributeDefinitions.BIRTHDATE_NAME);
+ includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_NAME);
+ includedGenericSessionData.remove(PVPAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
+
+ }
+
+ /**
+ * Get bPK from PVP Attribute 'BPK_NAME', which could be exist in MOASession as 'GenericData'. <br>
+ *
+ * <pre>
+ * <code>session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class)</code>
+ * </pre>
+ *
+ * @param session MOASession, but never null
+ * @return bPK, which was received by PVP-Attribute, or <code>null</code> if no attribute exists
+ */
+ @Deprecated
+ private String getBpkValueFromPvpAttribute(final IAuthProcessDataContainer session) {
+ String pvpBpkValueAttr =
+ session.getGenericDataFromSession(PVPAttributeDefinitions.BPK_NAME, String.class);
+ if (StringUtils.isNotEmpty(pvpBpkValueAttr)) {
+
+ // fix a wrong bPK-value prefix, which was used in some PVP Standardportal implementations
+ if (pvpBpkValueAttr.startsWith("bPK:")) {
+ log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME
+ + " contains a not standardize prefix! Staring attribute value correction process ...");
+ pvpBpkValueAttr = pvpBpkValueAttr.substring("bPK:".length());
+
+ }
+
+ final String[] spitted = pvpBpkValueAttr.split(":");
+ if (spitted.length == 2) {
+ log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME);
+ return spitted[1];
+
+
+
+ } else if (spitted.length > 2) {
+ log.warn("Attribute " + PVPAttributeDefinitions.BPK_NAME
+ + " has a wrong encoding and can NOT be USED!" + " Value:" + pvpBpkValueAttr);
+ return null;
+
+ } else {
+ log.debug("Find PVP-Attr: " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME
+ + " without prefix. Use it as it is");
+ return spitted[0];
+
+ }
+
+ }
+
+ return null;
+ }
+
+ /**
+ * Get bPK-Type from PVP Attribute 'EID_SECTOR_FOR_IDENTIFIER_NAME', which could be exist in
+ * MOASession as 'GenericData'. <br>
+ *
+ * <pre>
+ * <code>session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class)</code>
+ * </pre>
+ *
+ * @param session MOASession, but never null
+ * @return bPKType, which was received by PVP-Attribute, or <code>null</code> if no attribute
+ * exists
+ */
+ @Deprecated
+ private String getBpkTypeFromPvpAttribute(final IAuthProcessDataContainer session) {
+ final String pvpBpkTypeAttr = session.getGenericDataFromSession(
+ PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class);
+
+ if (StringUtils.isNotEmpty(pvpBpkTypeAttr)) {
+ // //fix a wrong bPK-Type encoding, which was used in some PVP Standardportal implementations
+ // if (pvpbPKTypeAttr.startsWith(EAAFConstants.URN_PREFIX_CDID) &&
+ // !pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length(),
+ // EAAFConstants.URN_PREFIX_CDID.length() + 1).equals("+")) {
+ // log.warn("Receive uncorrect encoded bBKType attribute " + pvpbPKTypeAttr + " Starting
+ // attribute value correction ... ");
+ // pvpbPKTypeAttr = EAAFConstants.URN_PREFIX_CDID + "+" +
+ // pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length() + 1);
+ //
+ // }
+ log.debug(
+ "Find PVP-Attr: " + PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME);
+ return pvpBpkTypeAttr;
+ }
+
+ return null;
+
+
+ /*
+ * INFO: This code could be used to extract the bPKType from 'PVPConstants.BPK_NAME', because
+ * the prefix of BPK_NAME attribute contains the postfix of the bPKType
+ *
+ * Now, all PVP Standardportals should be able to send 'EID_SECTOR_FOR_IDENTIFIER' PVP
+ * attributes
+ */
+ // String pvpbPKValueAttr = session.getGenericDataFromSession(PVPConstants.BPK_NAME,
+ // String.class);
+ // String[] spitted = pvpbPKValueAttr.split(":");
+ // if (MiscUtil.isEmpty(authData.getBPKType())) {
+ // Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " +
+ // "Starting target extraction from bPK/wbPK prefix ...");
+ // //exract bPK/wbPK type from bpk attribute value prefix if type is
+ // //not transmitted as single attribute
+ // Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?");
+ // Matcher matcher = pattern.matcher(spitted[0]);
+ // if (matcher.matches()) {
+ // //find public service bPK
+ // authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]);
+ // Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType());
+ //
+ // } else {
+ // //find business service wbPK
+ // authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]);
+ // Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType());
+ //
+ // }
+ // }
+
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java
deleted file mode 100644
index 602546a2..00000000
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BPKBuilder.java
+++ /dev/null
@@ -1,302 +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.
- ******************************************************************************/
-/*
- * Copyright 2003 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.egiz.eaaf.core.impl.idp.auth.builder;
-
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.Base64Utils;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException;
-import at.gv.egiz.eaaf.core.impl.data.Pair;
-
-/**
- * Builder for the bPK, as defined in
- * <code>&quot;Ableitung f&uml;r die bereichsspezifische Personenkennzeichnung&quot;</code>
- * version <code>1.0.1</code> from <code>&quot;reference.e-government.gv.at&quot;</code>.
- *
- */
-public class BPKBuilder {
- private static final Logger log = LoggerFactory.getLogger(BPKBuilder.class);
-
- /**
- * Calculates an area specific unique person-identifier from a baseID
- *
- * @param baseID baseId from user but never null
- * @param targetIdentifier target identifier for area specific identifier calculation but never null
- * @return Pair consists of (unique person identifier for this target, targetArea) but never null
- * @throws EAAFBuilderException if some input data are not valid
- */
- public static Pair<String, String> generateAreaSpecificPersonIdentifier(String baseID, String targetIdentifier) throws EAAFBuilderException {
- return generateAreaSpecificPersonIdentifier(baseID, EAAFConstants.URN_PREFIX_BASEID, targetIdentifier);
-
- }
-
- /**
- * Calculates an area specific unique person-identifier from an unique identifier with a specific type
- *
- * @param baseID baseId from user but never null
- * @param baseIdType Type of the baseID but never null
- * @param targetIdentifier target identifier for area specific identifier calculation but never null
- * @return Pair consists of (unique person identifier for this target, targetArea) but never null
- * @throws EAAFBuilderException if some input data are not valid
- */
- public static Pair<String, String> generateAreaSpecificPersonIdentifier(String baseID, String baseIdType, String targetIdentifier) throws EAAFBuilderException{
- if (StringUtils.isEmpty(baseID))
- throw new EAAFBuilderException("builder.00", new Object[]{"baseID is empty or null"},
- "BaseId is empty or null");
-
- if (StringUtils.isEmpty(baseIdType))
- throw new EAAFBuilderException("builder.00", new Object[]{"the type of baseID is empty or null"},
- "Type of baseId is empty or null");
-
- if (StringUtils.isEmpty(targetIdentifier))
- throw new EAAFBuilderException("builder.00", new Object[]{"SP specific target identifier is empty or null"},
- "SP specific target identifier is empty or null");
-
- if (baseIdType.equals(EAAFConstants.URN_PREFIX_BASEID)) {
- log.trace("Find baseID. Starting unique identifier caluclation for this target");
-
- if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_CDID) ||
- targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_WBPK)) {
- log.trace("Calculate bPK, wbPK, or STORK identifier for target: " + targetIdentifier);
- return Pair.newInstance(calculatebPKwbPK(baseID + "+" + targetIdentifier), targetIdentifier);
-
- } else if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) {
- log.trace("Calculate eIDAS identifier for target: " + targetIdentifier);
- final String[] splittedTarget = targetIdentifier.split("\\+");
- final String cititzenCountryCode = splittedTarget[1];
- final String eIDASOutboundCountry = splittedTarget[2];
-
- if (cititzenCountryCode.equalsIgnoreCase(eIDASOutboundCountry)) {
- log.warn("Suspect configuration FOUND!!! CitizenCountry equals DestinationCountry");
-
- }
- return buildeIDASIdentifer(baseID, baseIdType, cititzenCountryCode, eIDASOutboundCountry);
-
-
- } else
- throw new EAAFBuilderException("builder.00",
- new Object[]{"Target identifier: " + targetIdentifier + " is NOT allowed or unknown"},
- "Target identifier: " + targetIdentifier + " is NOT allowed or unknown");
-
- } else {
- log.trace("BaseID is not of type " + EAAFConstants.URN_PREFIX_BASEID + ". Check type against requested target ...");
- if (baseIdType.equals(targetIdentifier)) {
- log.debug("Unique identifier is already area specific. Is nothing todo");
- return Pair.newInstance(baseID, targetIdentifier);
-
- } else {
- log.warn("Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required!");
- throw new EAAFBuilderException("builder.00",
- new Object[]{"Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required"},
- "Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier + " is required");
-
- }
- }
- }
-
-
- /**
- * Builds the eIDAS from the given parameters.
- *
- * @param baseID baseID of the citizen
- * @param baseIDType Type of the baseID
- * @param sourceCountry CountryCode of that country, which build the eIDAs ID
- * @param destinationCountry CountryCode of that country, which receives the eIDAs ID
- *
- * @return Pair<eIDAs, bPKType> in a BASE64 encoding
- * @throws EAAFBuilderException if some input data are not valid
- */
- private static Pair<String, String> buildeIDASIdentifer(String baseID, String baseIDType, String sourceCountry, String destinationCountry)
- throws EAAFBuilderException {
- String bPK = null;
- String bPKType = null;
-
- // check if we have been called by public sector application
- if (baseIDType.startsWith(EAAFConstants.URN_PREFIX_BASEID)) {
- bPKType = EAAFConstants.URN_PREFIX_EIDAS + sourceCountry + "+" + destinationCountry;
- log.debug("Building eIDAS identification from: [identValue]+" + bPKType);
- bPK = calculatebPKwbPK(baseID + "+" + bPKType);
-
- } else { // if not, sector identification value is already calculated by BKU
- log.debug("eIDAS eIdentifier already provided by BKU");
- bPK = baseID;
- }
-
- if ((StringUtils.isEmpty(bPK) ||
- StringUtils.isEmpty(sourceCountry) ||
- StringUtils.isEmpty(destinationCountry))) {
- throw new EAAFBuilderException("builder.00",
- new Object[]{"eIDAS-ID", "Unvollständige Parameterangaben: identificationValue=" +
- bPK + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry}
- ,"eIDAS-ID: Unvollständige Parameterangaben: identificationValue=" +
- bPK + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry);
- }
-
- log.trace("eIDAS pseudonym generation finished. ");
- final String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bPK;
-
- return Pair.newInstance(eIdentifier, bPKType);
- }
-
- public static String encryptBPK(String bpk, String target, PublicKey publicKey) throws EAAFBuilderException {
- final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
- if (target.startsWith(EAAFConstants.URN_PREFIX_CDID))
- target = target.substring((EAAFConstants.URN_PREFIX_CDID).length());
-
- final String input = "V1::urn:publicid:gv.at:cdid+" + target + "::"
- + bpk + "::"
- + sdf.format(new Date());
- //System.out.println(input);
- byte[] result;
- try {
- final byte[] inputBytes = input.getBytes("ISO-8859-1");
- result = encrypt(inputBytes, publicKey);
- return new String(Base64Utils.encode(result), "ISO-8859-1").replaceAll("\r\n", "");
- //return new String(Base64Utils.encode(result, "ISO-8859-1")).replaceAll("\r\n", "");
-
-
- } catch (final Exception e) {
- throw new EAAFBuilderException("bPK encryption FAILED", null,
- e.getMessage(), e);
-
- }
- }
-
- public static String decryptBPK(String encryptedBpk, String target, PrivateKey privateKey) throws EAAFBuilderException {
- String decryptedString;
- try {
- //byte[] encryptedBytes = Base64Utils.decode(encryptedBpk, false, "ISO-8859-1");
- final byte[] encryptedBytes = Base64Utils.decode(encryptedBpk.getBytes("ISO-8859-1"));
- final byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
- decryptedString = new String(decryptedBytes, "ISO-8859-1");
-
- } catch (final Exception e) {
- throw new EAAFBuilderException("bPK decryption FAILED", null,
- e.getMessage(), e);
-
- }
-
- String tmp = decryptedString.substring(decryptedString.indexOf('+') + 1);
- final String sector = tmp.substring(0, tmp.indexOf("::"));
- tmp = tmp.substring(tmp.indexOf("::") + 2);
- final String bPK = tmp.substring(0, tmp.indexOf("::"));
-
- if (target.startsWith(EAAFConstants.URN_PREFIX_CDID + "+"))
- target = target.substring((EAAFConstants.URN_PREFIX_CDID + "+").length());
-
- if (target.equals(sector))
- return bPK;
-
- else {
- log.error("Decrypted bPK does not match to request bPK target.");
- return null;
- }
- }
-
- private static String calculatebPKwbPK(String basisbegriff) throws EAAFBuilderException {
- try {
- final MessageDigest md = MessageDigest.getInstance("SHA-1");
- final byte[] hash = md.digest(basisbegriff.getBytes("ISO-8859-1"));
- final String hashBase64 = new String(Base64Utils.encode(hash), "ISO-8859-1").replaceAll("\r\n", ""); //Base64Utils.encode(hash);
- return hashBase64;
-
- } catch (final Exception ex) {
- throw new EAAFBuilderException("builder.00", new Object[]{"bPK/wbPK", ex.toString()},
- ex.getMessage(), ex);
-
- }
-
- }
-
- private static byte[] encrypt(byte[] inputBytes, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
- byte[] result;
- Cipher cipher = null;
- try {
- cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
-
- } catch(final NoSuchAlgorithmException e) {
- cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
- }
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- result = cipher.doFinal(inputBytes);
-
- return result;
- }
-
- private static byte[] decrypt(byte[] encryptedBytes, PrivateKey privateKey)
- throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
- byte[] result;
- Cipher cipher = null;
- try {
- cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
-
- } catch(final NoSuchAlgorithmException e) {
- cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
-
- }
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- result = cipher.doFinal(encryptedBytes);
- return result;
-
- }
-}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java
new file mode 100644
index 00000000..765a6669
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java
@@ -0,0 +1,312 @@
+/*
+ * 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.egiz.eaaf.core.impl.idp.auth.builder;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Base64Utils;
+
+/**
+ * Builder for the bPK, as defined in
+ * <code>&quot;Ableitung f&uml;r die bereichsspezifische Personenkennzeichnung&quot;</code> version
+ * <code>1.0.1</code> from <code>&quot;reference.e-government.gv.at&quot;</code>.
+ *
+ */
+public class BpkBuilder {
+ private static final Logger log = LoggerFactory.getLogger(BpkBuilder.class);
+
+ /**
+ * Calculates an area specific unique person-identifier from a baseID.
+ *
+ * @param baseID baseId from user but never null
+ * @param targetIdentifier target identifier for area specific identifier calculation but never
+ * null
+ * @return Pair consists of (unique person identifier for this target, targetArea) but never null
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ public static Pair<String, String> generateAreaSpecificPersonIdentifier(final String baseID,
+ final String targetIdentifier) throws EaafBuilderException {
+ return generateAreaSpecificPersonIdentifier(baseID, EAAFConstants.URN_PREFIX_BASEID,
+ targetIdentifier);
+
+ }
+
+ /**
+ * Calculates an area specific unique person-identifier from an unique identifier with a specific
+ * type.
+ *
+ * @param baseID baseId from user but never null
+ * @param baseIdType Type of the baseID but never null
+ * @param targetIdentifier target identifier for area specific identifier calculation but never
+ * null
+ * @return Pair consists of (unique person identifier for this target, targetArea) but never null
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ public static Pair<String, String> generateAreaSpecificPersonIdentifier(final String baseID,
+ final String baseIdType, final String targetIdentifier) throws EaafBuilderException {
+ if (StringUtils.isEmpty(baseID)) {
+ throw new EaafBuilderException("builder.00", new Object[] {"baseID is empty or null"},
+ "BaseId is empty or null");
+ }
+
+ if (StringUtils.isEmpty(baseIdType)) {
+ throw new EaafBuilderException("builder.00",
+ new Object[] {"the type of baseID is empty or null"}, "Type of baseId is empty or null");
+ }
+
+ if (StringUtils.isEmpty(targetIdentifier)) {
+ throw new EaafBuilderException("builder.00",
+ new Object[] {"SP specific target identifier is empty or null"},
+ "SP specific target identifier is empty or null");
+ }
+
+ if (baseIdType.equals(EAAFConstants.URN_PREFIX_BASEID)) {
+ log.trace("Find baseID. Starting unique identifier caluclation for this target");
+
+ if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_CDID)
+ || targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_WBPK)) {
+ log.trace("Calculate bPK, wbPK, or STORK identifier for target: " + targetIdentifier);
+ return Pair.newInstance(calculatebPKwbPK(baseID + "+" + targetIdentifier),
+ targetIdentifier);
+
+ } else if (targetIdentifier.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) {
+ log.trace("Calculate eIDAS identifier for target: " + targetIdentifier);
+ final String[] splittedTarget = targetIdentifier.split("\\+");
+ final String cititzenCountryCode = splittedTarget[1];
+ final String eidasOutboundCountry = splittedTarget[2];
+
+ if (cititzenCountryCode.equalsIgnoreCase(eidasOutboundCountry)) {
+ log.warn("Suspect configuration FOUND!!! CitizenCountry equals DestinationCountry");
+
+ }
+ return buildEidasIdentifer(baseID, baseIdType, cititzenCountryCode, eidasOutboundCountry);
+
+
+ } else {
+ throw new EaafBuilderException("builder.00",
+ new Object[] {"Target identifier: " + targetIdentifier + " is NOT allowed or unknown"},
+ "Target identifier: " + targetIdentifier + " is NOT allowed or unknown");
+ }
+
+ } else {
+ log.trace("BaseID is not of type " + EAAFConstants.URN_PREFIX_BASEID
+ + ". Check type against requested target ...");
+ if (baseIdType.equals(targetIdentifier)) {
+ log.debug("Unique identifier is already area specific. Is nothing todo");
+ return Pair.newInstance(baseID, targetIdentifier);
+
+ } else {
+ log.warn("Get unique identifier for target: " + baseIdType + " but target: "
+ + targetIdentifier + " is required!");
+ throw new EaafBuilderException("builder.00",
+ new Object[] {"Get unique identifier for target: " + baseIdType + " but target: "
+ + targetIdentifier + " is required"},
+ "Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier
+ + " is required");
+
+ }
+ }
+ }
+
+
+ /**
+ * Builds the eIDAS from the given parameters.
+ *
+ * @param baseId baseID of the citizen
+ * @param baseIdType Type of the baseID
+ * @param sourceCountry CountryCode of that country, which build the eIDAs ID
+ * @param destinationCountry CountryCode of that country, which receives the eIDAs ID
+ *
+ * @return Pair eIDAs/bPKType in a BASE64 encoding
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ private static Pair<String, String> buildEidasIdentifer(final String baseId,
+ final String baseIdType, final String sourceCountry, final String destinationCountry)
+ throws EaafBuilderException {
+ String bpk = null;
+ String bpkType = null;
+
+ // check if we have been called by public sector application
+ if (baseIdType.startsWith(EAAFConstants.URN_PREFIX_BASEID)) {
+ bpkType = EAAFConstants.URN_PREFIX_EIDAS + sourceCountry + "+" + destinationCountry;
+ log.debug("Building eIDAS identification from: [identValue]+" + bpkType);
+ bpk = calculatebPKwbPK(baseId + "+" + bpkType);
+
+ } else { // if not, sector identification value is already calculated by BKU
+ log.debug("eIDAS eIdentifier already provided by BKU");
+ bpk = baseId;
+ }
+
+ if ((StringUtils.isEmpty(bpk) || StringUtils.isEmpty(sourceCountry)
+ || StringUtils.isEmpty(destinationCountry))) {
+ throw new EaafBuilderException("builder.00",
+ new Object[] {"eIDAS-ID",
+ "Unvollständige Parameterangaben: identificationValue=" + bpk + ", Zielland="
+ + destinationCountry + ", Ursprungsland=" + sourceCountry},
+ "eIDAS-ID: Unvollständige Parameterangaben: identificationValue=" + bpk + ", Zielland="
+ + destinationCountry + ", Ursprungsland=" + sourceCountry);
+ }
+
+ log.trace("eIDAS pseudonym generation finished. ");
+ final String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bpk;
+
+ return Pair.newInstance(eIdentifier, bpkType);
+ }
+
+ /**
+ * Create an encrypted bPK.
+ *
+ * @param bpk unencrypted bPK
+ * @param target bPK target
+ * @param publicKey Public-Key used for encryption
+ * @return encrypted bPK
+ * @throws EaafBuilderException In case of an error
+ */
+ public static String encryptBpk(final String bpk, String target, final PublicKey publicKey)
+ throws EaafBuilderException {
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ if (target.startsWith(EAAFConstants.URN_PREFIX_CDID)) {
+ target = target.substring((EAAFConstants.URN_PREFIX_CDID).length());
+ }
+
+ final String input =
+ "V1::urn:publicid:gv.at:cdid+" + target + "::" + bpk + "::" + sdf.format(new Date());
+ // System.out.println(input);
+ byte[] result;
+ try {
+ final byte[] inputBytes = input.getBytes("ISO-8859-1");
+ result = encrypt(inputBytes, publicKey);
+ return new String(Base64Utils.encode(result), "ISO-8859-1").replaceAll("\r\n", "");
+ // return new String(Base64Utils.encode(result, "ISO-8859-1")).replaceAll("\r\n", "");
+
+
+ } catch (final Exception e) {
+ throw new EaafBuilderException("bPK encryption FAILED", null, e.getMessage(), e);
+
+ }
+ }
+
+ /**
+ * Decrypt an encrypted bPK.
+ *
+ * @param encryptedBpk encrypted bPK
+ * @param target bPK target
+ * @param privateKey private-key for decryption
+ * @return bPK
+ * @throws EaafBuilderException In case of an error
+ */
+ public static String decryptBpk(final String encryptedBpk, String target,
+ final PrivateKey privateKey) throws EaafBuilderException {
+ String decryptedString;
+ try {
+ // byte[] encryptedBytes = Base64Utils.decode(encryptedBpk, false, "ISO-8859-1");
+ final byte[] encryptedBytes = Base64Utils.decode(encryptedBpk.getBytes("ISO-8859-1"));
+ final byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
+ decryptedString = new String(decryptedBytes, "ISO-8859-1");
+
+ } catch (final Exception e) {
+ throw new EaafBuilderException("bPK decryption FAILED", null, e.getMessage(), e);
+
+ }
+
+ String tmp = decryptedString.substring(decryptedString.indexOf('+') + 1);
+ final String sector = tmp.substring(0, tmp.indexOf("::"));
+ tmp = tmp.substring(tmp.indexOf("::") + 2);
+ final String bPK = tmp.substring(0, tmp.indexOf("::"));
+
+ if (target.startsWith(EAAFConstants.URN_PREFIX_CDID + "+")) {
+ target = target.substring((EAAFConstants.URN_PREFIX_CDID + "+").length());
+ }
+
+ if (target.equals(sector)) {
+ return bPK;
+ } else {
+ log.error("Decrypted bPK does not match to request bPK target.");
+ return null;
+ }
+ }
+
+ private static String calculatebPKwbPK(final String basisbegriff) throws EaafBuilderException {
+ try {
+ final MessageDigest md = MessageDigest.getInstance("SHA-1");
+ final byte[] hash = md.digest(basisbegriff.getBytes("ISO-8859-1"));
+ final String hashBase64 =
+ new String(Base64Utils.encode(hash), "ISO-8859-1").replaceAll("\r\n", ""); // Base64Utils.encode(hash);
+ return hashBase64;
+
+ } catch (final Exception ex) {
+ throw new EaafBuilderException("builder.00", new Object[] {"bPK/wbPK", ex.toString()},
+ ex.getMessage(), ex);
+
+ }
+
+ }
+
+ private static byte[] encrypt(final byte[] inputBytes, final PublicKey publicKey)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+ byte[] result;
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+
+ } catch (final NoSuchAlgorithmException e) {
+ cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+ }
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ result = cipher.doFinal(inputBytes);
+
+ return result;
+ }
+
+ private static byte[] decrypt(final byte[] encryptedBytes, final PrivateKey privateKey)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+ byte[] result;
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+
+ } catch (final NoSuchAlgorithmException e) {
+ cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+
+ }
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ result = cipher.doFinal(encryptedBytes);
+ return result;
+
+ }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
index e096b8e6..7c143ca2 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java
@@ -1,24 +1,20 @@
/*******************************************************************************
- * 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.
+ * 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:
+ * 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.
+ * 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.
*******************************************************************************/
/*******************************************************************************
*******************************************************************************/
@@ -29,226 +25,276 @@ package at.gv.egiz.eaaf.core.impl.idp.auth.data;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.EaafAuthProcessDataConstants;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.core.api.idp.EAAFAuthProcessDataConstants;
-import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
-import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
-import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
-
-public class AuthProcessDataWrapper implements IAuthProcessDataContainer, EAAFAuthProcessDataConstants {
- private static final Logger log = LoggerFactory.getLogger(AuthProcessDataWrapper.class);
-
- protected Map<String, Object> authProcessData;
-
- public AuthProcessDataWrapper(Map<String, Object> authProcessData) {
- this.authProcessData = authProcessData;
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIssueInstant()
- */
- @Override
- public String getIssueInstant() {
- return wrapStringObject(VALUE_ISSUEINSTANT, null, String.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIssueInstant(java.lang.String)
- */
- @Override
- public void setIssueInstant(String issueInstant) {
- authProcessData.put(VALUE_ISSUEINSTANT, issueInstant);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isAuthenticated()
- */
- @Override
- public boolean isAuthenticated() {
- return wrapStringObject(FLAG_IS_AUTHENTICATED, false, Boolean.class);
-
- }
-
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setAuthenticated(boolean)
- */
- @Override
- public void setAuthenticated(boolean authenticated) {
- authProcessData.put(FLAG_IS_AUTHENTICATED, authenticated);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIdentityLink()
- */
- @Override
- public IIdentityLink getIdentityLink() {
- return wrapStringObject(VALUE_IDENTITYLINK, null, IIdentityLink.class);
-
- }
-
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIdentityLink(at.gv.egovernment.moa.id.auth.data.IdentityLink)
- */
- @Override
- public void setIdentityLink(IIdentityLink identityLink) {
- authProcessData.put(VALUE_IDENTITYLINK, identityLink);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isMandateUsed()
- */
- @Override
- public boolean isMandateUsed() {
- return wrapStringObject(FLAG_USE_MANDATE, false, Boolean.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setUseMandates(boolean)
- */
- @Override
- public void setUseMandates(boolean useMandates) {
- authProcessData.put(FLAG_USE_MANDATE, useMandates);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getQAALevel()
- */
- @Override
- public String getQAALevel() {
- return wrapStringObject(VALUE_QAALEVEL, null, String.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setQAALevel(java.lang.String)
- */
- @Override
- public void setQAALevel(String qAALevel) {
- authProcessData.put(VALUE_QAALEVEL, qAALevel);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isForeigner()
- */
- @Override
- public boolean isForeigner() {
- return wrapStringObject(FLAG_IS_FOREIGNER, false, Boolean.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setForeigner(boolean)
- */
- @Override
- public void setForeigner(boolean isForeigner) {
- authProcessData.put(FLAG_IS_FOREIGNER, isForeigner);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isOW()
- */
- @Override
- public boolean isOW() {
- return wrapStringObject(FLAG_IS_ORGANWALTER, false, Boolean.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setOW(boolean)
- */
- @Override
- public void setOW(boolean isOW) {
- authProcessData.put(FLAG_IS_ORGANWALTER, isOW);
-
- }
-
- @Override
- public boolean isEIDProcess() {
- return wrapStringObject(FLAG_IS_NEW_EID_PROCESS, false, Boolean.class);
- }
-
- @Override
- public void setEIDProcess(boolean value) {
- authProcessData.put(FLAG_IS_NEW_EID_PROCESS, value);
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getSessionCreated()
- */
- @Override
- public Date getSessionCreated() {
- return wrapStringObject(EAAFConstants.AUTH_DATA_CREATED, null, Date.class);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericSessionDataStorage()
- */
- @Override
- public Map<String, Object> getGenericSessionDataStorage() {
- final Map<String, Object> result = new HashMap<String, Object>();
- for (final String el : authProcessData.keySet()) {
- if (el.startsWith(GENERIC_PREFIX))
- result.put(el.substring(GENERIC_PREFIX.length()), authProcessData.get(el));
-
- }
-
- return result;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.String)
- */
- @Override
- public Object getGenericDataFromSession(String key) {
- return authProcessData.get(GENERIC_PREFIX + key);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.String, java.lang.Class)
- */
- @Override
- public <T> T getGenericDataFromSession(String key, Class<T> clazz) {
- return wrapStringObject(GENERIC_PREFIX + key, null, clazz);
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setGenericDataToSession(java.lang.String, java.lang.Object)
- */
- @Override
- public void setGenericDataToSession(String key, Object object) throws EAAFStorageException {
- authProcessData.put(GENERIC_PREFIX + key, object);
-
- }
-
- protected <T> T wrapStringObject(String key, Object defaultValue, Class<T> clazz) {
- if (StringUtils.isNotEmpty(key)) {
- final Object obj = authProcessData.get(key);
- if (obj != null && clazz.isInstance(obj))
- return (T) obj;
- }
-
- if (defaultValue == null)
- return null;
-
- else if (clazz.isInstance(defaultValue))
- return (T)defaultValue;
-
- else {
- log.error("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:" + clazz.getName());
- throw new IllegalStateException("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:" + clazz.getName());
-
- }
- }
+public class AuthProcessDataWrapper
+ implements IAuthProcessDataContainer, EaafAuthProcessDataConstants {
+ private static final Logger log = LoggerFactory.getLogger(AuthProcessDataWrapper.class);
+
+ protected Map<String, Object> authProcessData;
+
+ public AuthProcessDataWrapper(final Map<String, Object> authProcessData) {
+ this.authProcessData = authProcessData;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIssueInstant()
+ */
+ @Override
+ public String getIssueInstant() {
+ return wrapStringObject(VALUE_ISSUEINSTANT, null, String.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIssueInstant(java.lang.String)
+ */
+ @Override
+ public void setIssueInstant(final String issueInstant) {
+ authProcessData.put(VALUE_ISSUEINSTANT, issueInstant);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isAuthenticated()
+ */
+ @Override
+ public boolean isAuthenticated() {
+ return wrapStringObject(FLAG_IS_AUTHENTICATED, false, Boolean.class);
+
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setAuthenticated(boolean)
+ */
+ @Override
+ public void setAuthenticated(final boolean authenticated) {
+ authProcessData.put(FLAG_IS_AUTHENTICATED, authenticated);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getIdentityLink()
+ */
+ @Override
+ public IIdentityLink getIdentityLink() {
+ return wrapStringObject(VALUE_IDENTITYLINK, null, IIdentityLink.class);
+
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setIdentityLink(at.gv.egovernment.moa
+ * .id.auth.data.IdentityLink)
+ */
+ @Override
+ public void setIdentityLink(final IIdentityLink identityLink) {
+ authProcessData.put(VALUE_IDENTITYLINK, identityLink);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isMandateUsed()
+ */
+ @Override
+ public boolean isMandateUsed() {
+ return wrapStringObject(FLAG_USE_MANDATE, false, Boolean.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setUseMandates(boolean)
+ */
+ @Override
+ public void setUseMandates(final boolean useMandates) {
+ authProcessData.put(FLAG_USE_MANDATE, useMandates);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getQAALevel()
+ */
+ @Override
+ public String getQAALevel() {
+ return wrapStringObject(VALUE_QAALEVEL, null, String.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setQAALevel(java.lang.String)
+ */
+ @Override
+ public void setQAALevel(final String qAALevel) {
+ authProcessData.put(VALUE_QAALEVEL, qAALevel);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isForeigner()
+ */
+ @Override
+ public boolean isForeigner() {
+ return wrapStringObject(FLAG_IS_FOREIGNER, false, Boolean.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setForeigner(boolean)
+ */
+ @Override
+ public void setForeigner(final boolean isForeigner) {
+ authProcessData.put(FLAG_IS_FOREIGNER, isForeigner);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#isOW()
+ */
+ @Override
+ public boolean isOW() {
+ return wrapStringObject(FLAG_IS_ORGANWALTER, false, Boolean.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setOW(boolean)
+ */
+ @Override
+ public void setOW(final boolean isOW) {
+ authProcessData.put(FLAG_IS_ORGANWALTER, isOW);
+
+ }
+
+ @Override
+ public boolean isEIDProcess() {
+ return wrapStringObject(FLAG_IS_NEW_EID_PROCESS, false, Boolean.class);
+ }
+
+ @Override
+ public void setEIDProcess(final boolean value) {
+ authProcessData.put(FLAG_IS_NEW_EID_PROCESS, value);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getSessionCreated()
+ */
+ @Override
+ public Date getSessionCreated() {
+ return wrapStringObject(EAAFConstants.AUTH_DATA_CREATED, null, Date.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericSessionDataStorage()
+ */
+ @Override
+ public Map<String, Object> getGenericSessionDataStorage() {
+ final Map<String, Object> result = new HashMap<>();
+ for (final Map.Entry<String,Object> el : authProcessData.entrySet()) {
+ if (el.getKey().startsWith(GENERIC_PREFIX)) {
+ result.put(el.getKey().substring(GENERIC_PREFIX.length()), el.getValue());
+ }
+
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.
+ * String)
+ */
+ @Override
+ public Object getGenericDataFromSession(final String key) {
+ return authProcessData.get(GENERIC_PREFIX + key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getGenericDataFromSession(java.lang.
+ * String, java.lang.Class)
+ */
+ @Override
+ public <T> T getGenericDataFromSession(final String key, final Class<T> clazz) {
+ return wrapStringObject(GENERIC_PREFIX + key, null, clazz);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#setGenericDataToSession(java.lang.
+ * String, java.lang.Object)
+ */
+ @Override
+ public void setGenericDataToSession(final String key, final Object object)
+ throws EaafStorageException {
+ authProcessData.put(GENERIC_PREFIX + key, object);
+
+ }
+
+ protected <T> T wrapStringObject(final String key, final Object defaultValue,
+ final Class<T> clazz) {
+ if (StringUtils.isNotEmpty(key)) {
+ final Object obj = authProcessData.get(key);
+ if (obj != null && clazz.isInstance(obj)) {
+ return (T) obj;
+ }
+ }
+
+ if (defaultValue == null) {
+ return null;
+ } else if (clazz.isInstance(defaultValue)) {
+ return (T) defaultValue;
+ } else {
+ log.error("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:"
+ + clazz.getName());
+ throw new IllegalStateException("DefaultValue: " + defaultValue.getClass().getName()
+ + " is not of Type:" + clazz.getName());
+
+ }
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
index 367643ec..a1faa0a4 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java
@@ -1,306 +1,375 @@
/*******************************************************************************
- * 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.
+ * 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.
******************************************************************************/
/*
- * Copyright 2003 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.
+ * Copyright 2003 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/
+ * 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.
+ * 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.
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
*/
package at.gv.egiz.eaaf.core.impl.idp.auth.data;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.PublicKey;
-
import javax.xml.transform.TransformerException;
-
-import org.w3c.dom.Element;
-
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
-import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
+import org.w3c.dom.Element;
/**
- * Data contained in an identity link issued by BMI, relevant to the MOA ID component.
- * <br><code>"IdentityLink"</code> is the translation of <code>"Personenbindung"</code>.
- *
+ * Data contained in an identity link issued by BMI, relevant to the MOA ID component. <br>
+ * <code>"IdentityLink"</code> is the translation of <code>"Personenbindung"</code>.
+ *
* @author Paul Ivancsics
* @version $Id$
*/
-public class IdentityLink implements Serializable, IIdentityLink{
-
- private static final long serialVersionUID = 1L;
-
- /**
- * <code>"identificationValue"</code> is the translation of <code>"Stammzahl"</code>.
- */
- private String identificationValue;
- /**
- * <code>"identificationType"</code> type of the identificationValue in the IdentityLink.
- */
- private String identificationType;
- /**
- * first name
- */
- private String givenName;
- /**
- * family name
- */
- private String familyName;
-
- /**
- * date of birth
- */
- private String dateOfBirth;
+public class IdentityLink implements Serializable, IIdentityLink {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * <code>"identificationValue"</code> is the translation of <code>"Stammzahl"</code>.
+ */
+ private String identificationValue;
+ /**
+ * <code>"identificationType"</code> type of the identificationValue in the IdentityLink.
+ */
+ private String identificationType;
+ /**
+ * first name
+ */
+ private String givenName;
+ /**
+ * family name
+ */
+ private String familyName;
+
+ /**
+ * date of birth
+ */
+ private String dateOfBirth;
/**
* the original saml:Assertion-Element
*/
- private Element samlAssertion;
+ private transient Element samlAssertion;
/**
* the serializes saml:Assertion
*/
private String serializedSamlAssertion;
- /**
- * Element /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/pr:Person
- */
- private Element prPerson;
/**
- * we need for each dsig:Reference Element all
- * transformation elements
+ * Element
+ * /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/pr:Person
+ */
+ private transient Element prPerson = null;
+ /**
+ * we need for each dsig:Reference Element all transformation elements
*/
- private Element[] dsigReferenceTransforms;
-
+ private transient Element[] dsigReferenceTransforms = null;
+
/**
* The issuing time of the identity link SAML assertion.
*/
private String issueInstant;
/**
- * we need all public keys stored in
- * the identity link
+ * we need all public keys stored in the identity link
*/
private PublicKey[] publicKey;
- /**
- * Constructor for IdentityLink
- */
- public IdentityLink() {
- }
+ /**
+ * Constructor for IdentityLink
+ */
+ public IdentityLink() {}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDateOfBirth()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDateOfBirth()
+ */
@Override
-public String getDateOfBirth() {
+ public String getDateOfBirth() {
return dateOfBirth;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getFamilyName()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getFamilyName()
+ */
@Override
-public String getFamilyName() {
+ public String getFamilyName() {
return familyName;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getGivenName()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getGivenName()
+ */
@Override
-public String getGivenName() {
+ public String getGivenName() {
return givenName;
}
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getName()
- */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getName()
+ */
@Override
@Deprecated
public String getName() {
return givenName + " " + familyName;
-
+
}
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationValue()
- */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationValue()
+ */
@Override
-public String getIdentificationValue() {
+ public String getIdentificationValue() {
return identificationValue;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationType()
- */
- @Override
- public String getIdentificationType() {
- return identificationType;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIdentificationType()
+ */
+ @Override
+ public String getIdentificationType() {
+ return identificationType;
+ }
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDateOfBirth(java.lang.String)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDateOfBirth(java.lang.String)
+ */
@Override
-public void setDateOfBirth(String dateOfBirth) {
+ public void setDateOfBirth(final String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setFamilyName(java.lang.String)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setFamilyName(java.lang.String)
+ */
@Override
-public void setFamilyName(String familyName) {
+ public void setFamilyName(final String familyName) {
this.familyName = familyName;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setGivenName(java.lang.String)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setGivenName(java.lang.String)
+ */
@Override
-public void setGivenName(String givenName) {
+ public void setGivenName(final String givenName) {
this.givenName = givenName;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationValue(java.lang.String)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationValue(java.lang.String)
+ */
@Override
-public void setIdentificationValue(String identificationValue) {
+ public void setIdentificationValue(final String identificationValue) {
this.identificationValue = identificationValue;
}
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationType(java.lang.String)
- */
- @Override
- public void setIdentificationType(String identificationType) {
- this.identificationType = identificationType;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSamlAssertion()
- */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIdentificationType(java.lang.String)
+ */
@Override
-public Element getSamlAssertion() {
- return samlAssertion;
+ public void setIdentificationType(final String identificationType) {
+ this.identificationType = identificationType;
}
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSerializedSamlAssertion()
- */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSamlAssertion()
+ */
@Override
-public String getSerializedSamlAssertion() {
+ public Element getSamlAssertion() {
+ if (this.samlAssertion == null) {
+ try {
+ this.samlAssertion = DomUtils.parseXmlNonValidating(
+ new ByteArrayInputStream(serializedSamlAssertion.getBytes("UTF-8")));
+
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+
+ }
+ }
+
+ return this.samlAssertion;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getSerializedSamlAssertion()
+ */
+ @Override
+ public String getSerializedSamlAssertion() {
return serializedSamlAssertion;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setSamlAssertion(org.w3c.dom.Element)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setSamlAssertion(org.w3c.dom.Element)
+ */
@Override
-public void setSamlAssertion(Element samlAssertion) throws TransformerException, IOException {
+ public void setSamlAssertion(final Element samlAssertion)
+ throws TransformerException, IOException {
this.samlAssertion = samlAssertion;
- this.serializedSamlAssertion = DOMUtils.serializeNode(samlAssertion);
+ this.serializedSamlAssertion = DomUtils.serializeNode(samlAssertion);
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDsigReferenceTransforms()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getDsigReferenceTransforms()
+ */
@Override
-public Element[] getDsigReferenceTransforms() {
- return dsigReferenceTransforms;
+ public Element[] getDsigReferenceTransforms() {
+ if (dsigReferenceTransforms != null) {
+ return dsigReferenceTransforms.clone();
+
+ } else {
+ return null;
+
+ }
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDsigReferenceTransforms(org.w3c.dom.Element[])
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.data.IIdentityLink#setDsigReferenceTransforms(org.w3c.dom.Element
+ * [])
+ */
@Override
-public void setDsigReferenceTransforms(Element[] dsigReferenceTransforms) {
- this.dsigReferenceTransforms = dsigReferenceTransforms;
+ public void setDsigReferenceTransforms(final Element[] dsigReferenceTransforms) {
+ if (dsigReferenceTransforms != null) {
+ this.dsigReferenceTransforms = dsigReferenceTransforms.clone();
+
+ }
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPublicKey()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPublicKey()
+ */
@Override
-public PublicKey[] getPublicKey() {
- return publicKey;
+ public PublicKey[] getPublicKey() {
+ if (publicKey != null) {
+ return publicKey.clone();
+
+ } else {
+ return null;
+
+ }
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPublicKey(java.security.PublicKey[])
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPublicKey(java.security.PublicKey[])
+ */
@Override
-public void setPublicKey(PublicKey[] publicKey) {
- this.publicKey = publicKey;
+ public void setPublicKey(final PublicKey[] publicKey) {
+ if (publicKey != null) {
+ this.publicKey = publicKey.clone();
+
+ }
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPrPerson()
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getPrPerson()
+ */
@Override
-public Element getPrPerson() {
+ public Element getPrPerson() {
+ if (prPerson == null) {
+ prPerson = (Element) XPathUtils.selectSingleNode(
+ getSamlAssertion(), SimpleIdentityLinkAssertionParser.PERSON_XPATH);
+
+ }
+
return prPerson;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPrPerson(org.w3c.dom.Element)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setPrPerson(org.w3c.dom.Element)
+ */
@Override
-public void setPrPerson(Element prPerson) {
+ public void setPrPerson(final Element prPerson) {
this.prPerson = prPerson;
}
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIssueInstant()
- */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#getIssueInstant()
+ */
@Override
-public String getIssueInstant() {
+ public String getIssueInstant() {
return issueInstant;
}
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIssueInstant(java.lang.String)
- */
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.data.IIdentityLink#setIssueInstant(java.lang.String)
+ */
@Override
-public void setIssueInstant(String issueInstant) {
+ public void setIssueInstant(final String issueInstant) {
this.issueInstant = issueInstant;
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
index 658e6a42..220469d3 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/SimpleIdentityLinkAssertionParser.java
@@ -1,46 +1,36 @@
/*******************************************************************************
- * 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.
+ * 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.
******************************************************************************/
/*
- * Copyright 2003 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.
+ * Copyright 2003 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/
+ * 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.
+ * 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.
+ * 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.
*/
@@ -50,22 +40,19 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
-
-import org.springframework.util.Base64Utils;
-import org.w3c.dom.Element;
-import org.w3c.dom.traversal.NodeIterator;
-
import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
-import at.gv.egiz.eaaf.core.exceptions.EAAFParserException;
-import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
+import at.gv.egiz.eaaf.core.exceptions.EaafParserException;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
+import org.springframework.util.Base64Utils;
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
/**
- * Parses MDS from an identity link <code>&lt;saml:Assertion&gt;</code>
- * <br>
+ * Parses MDS from an identity link <code>&lt;saml:Assertion&gt;</code> <br>
* <b>This IDL parser extract NO key information!</b>
-
+ *
*/
public class SimpleIdentityLinkAssertionParser {
@@ -79,246 +66,163 @@ public class SimpleIdentityLinkAssertionParser {
private static final String SAML = XMLNamespaceConstants.SAML_PREFIX + ":";
/** Xpath prefix for reaching XML-DSIG Namespaces */
private static final String DSIG = XMLNamespaceConstants.DSIG_PREFIX + ":";
- /** Xpath prefix for reaching ECDS Namespaces */
- private static final String ECDSA = XMLNamespaceConstants.ECDSA_PREFIX + ":";
- /** Xpath expression to the root element */
- private static final String ROOT = "";
- /** Xpath expression to the SAMLSubjectConfirmationData element */
+ /** Xpath expression to the root element */
+ private static final String ROOT = "";
+ /** Xpath expression to the SAMLSubjectConfirmationData element */
private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH =
- ROOT
- + SAML
- + "AttributeStatement/"
- + SAML
- + "Subject/"
- + SAML
- + "SubjectConfirmation/"
- + SAML
- + "SubjectConfirmationData";
+ ROOT + SAML + "AttributeStatement/" + SAML + "Subject/" + SAML + "SubjectConfirmation/" + SAML
+ + "SubjectConfirmationData";
/** Xpath expression to the PersonData element */
- private static final String PERSON_XPATH =
- SAML_SUBJECT_CONFIRMATION_DATA_XPATH
- + "/"
- + PDATA
- + "Person";
- /** Xpath expression to the PersonData GivenName element */
+ public static final String PERSON_XPATH =
+ SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person";
+ /** Xpath expression to the PersonData GivenName element */
public static final String PERSON_GIVEN_NAME_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "Name/"
- + PDATA
- + "GivenName";
+ PERSON_XPATH + "/" + PDATA + "Name/" + PDATA + "GivenName";
/** Xpath expression to the PersonData FamilyName element */
public static final String PERSON_FAMILY_NAME_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "Name/"
- + PDATA
- + "FamilyName";
+ PERSON_XPATH + "/" + PDATA + "Name/" + PDATA + "FamilyName";
/** Xpath expression to the PersonData DateOfBirth element */
public static final String PERSON_DATE_OF_BIRTH_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "DateOfBirth";
- /** Xpath expression to the Identification element */
- private static final String PERSON_IDENT_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "Identification";
-
- /** Xpath expression to the Identification Value element */
+ PERSON_XPATH + "/" + PDATA + "DateOfBirth";
+ /** Xpath expression to the Identification Value element */
public static final String PERSON_IDENT_VALUE_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "Identification/"
- + PDATA
- + "Value";
+ PERSON_XPATH + "/" + PDATA + "Identification/" + PDATA + "Value";
- /** Xpath expression to the Identification Value element */
- public static final String PERSON_IDENT_TYPE_XPATH =
- PERSON_XPATH
- + "/"
- + PDATA
- + "Identification/"
- + PDATA
- + "Type";
+ /** Xpath expression to the Identification Value element */
+ public static final String PERSON_IDENT_TYPE_XPATH =
+ PERSON_XPATH + "/" + PDATA + "Identification/" + PDATA + "Type";
- /** Xpath expression to the RSAKeyValue element */
- private static final String RSA_KEY_VALUE_XPATH =
- ROOT
- + SAML
- + "AttributeStatement/"
- + SAML
- + "Attribute/"
- + SAML
- + "AttributeValue/"
- + DSIG
- + "RSAKeyValue";
+ /** Xpath expression to the DSIG X509Certificate element */
+ private static final String DSIG_CERTIFICATES_XPATH = ROOT + DSIG + "Signature/" + DSIG
+ + "KeyInfo/" + DSIG + "X509Data/" + DSIG + "X509Certificate";
+ /** Xpath expression to the DSIG Transforms element */
+ private static final String DSIG_REFERENCE_TRANSFORMATION_XPATH =
+ ROOT + DSIG + "Signature/" + DSIG + "SignedInfo/" + DSIG + "Reference/" + DSIG + "Transforms";
- /** Xpath expression to the ECKeyValue element */
- private static final String ECDSA_KEY_VALUE_XPATH =
- ROOT
- + SAML
- + "AttributeStatement/"
- + SAML
- + "Attribute/"
- + SAML
- + "AttributeValue/"
- + ECDSA
- + "ECDSAKeyValue";
+ /** The IssueInstant attribute of the SAML assertion */
+ private static final String ISSUE_INSTANT_ATTR = "IssueInstant";
-
- /** Xpath expression to the RSA Modulus element */
- private static final String RSA_KEY_MODULUS_XPATH = DSIG + "Modulus";
- /** Xpath expression to the RSA Exponent element */
- private static final String RSA_KEY_EXPONENT_XPATH = DSIG + "Exponent";
- /** Xpath expression to the DSIG X509Certificate element */
- private static final String DSIG_CERTIFICATES_XPATH =
- ROOT
- + DSIG
- + "Signature/"
- + DSIG
- + "KeyInfo/"
- + DSIG
- + "X509Data/"
- + DSIG
- + "X509Certificate";
- /** Xpath expression to the DSIG Transforms element */
- private static final String DSIG_REFERENCE_TRANSFORMATION_XPATH =
- ROOT
- + DSIG
- + "Signature/"
- + DSIG
- + "SignedInfo/"
- + DSIG
- + "Reference/"
- + DSIG
- + "Transforms";
-
- /** The IssueInstant attribute of the SAML assertion */
- private static final String ISSUE_INSTANT_ATTR = "IssueInstant";
-
- public static final String ASSERTIONID = "AssertionID";
-
- /**This is the root element of the XML-Document provided by the Security Layer Card*/
+ public static final String ASSERTIONID = "AssertionID";
+
+ /** This is the root element of the XML-Document provided by the Security Layer Card */
private Element assertionElem;
/**
- * Constructor for <code>IdentityLinkAssertionParser</code>.
- * A DOM-representation of the incoming String will be created
+ * Constructor for <code>IdentityLinkAssertionParser</code>. A DOM-representation of the incoming
+ * String will be created
+ *
* @param xmlAssertion <code>&lt;saml:Assertion&gt;</code> as String
- * @throws EAAFParserException on any parsing error
+ * @throws EaafParserException on any parsing error
*/
- public SimpleIdentityLinkAssertionParser(String xmlAssertion) throws EAAFParserException {
+ public SimpleIdentityLinkAssertionParser(final String xmlAssertion) throws EaafParserException {
try {
- InputStream s = new ByteArrayInputStream(xmlAssertion.getBytes("UTF-8"));
- assertionElem = DOMUtils.parseXmlValidating(s);
-
- }
- catch (Throwable t) {
- throw new EAAFParserException("parser.01", new Object[] { t.toString()}, t);
-
+ final InputStream s = new ByteArrayInputStream(xmlAssertion.getBytes("UTF-8"));
+ assertionElem = DomUtils.parseXmlValidating(s);
+
+ } catch (final Throwable t) {
+ throw new EaafParserException("parser.01", new Object[] {t.toString()}, t);
+
}
}
-
+
/**
* Sets the <@link assertionElem>.
+ *
* @param xmlAssertion the assertion element
- * @throws EAAFParserException on any parsing error
+ * @throws EaafParserException on any parsing error
*/
- public SimpleIdentityLinkAssertionParser(Element xmlAssertion) throws EAAFParserException {
+ public SimpleIdentityLinkAssertionParser(final Element xmlAssertion) throws EaafParserException {
assertionElem = xmlAssertion;
}
/**
- * Constructor for <code>IdentityLinkAssertionParser</code>.
- * A DOM-representation of the incoming Inputstream will be created
+ * Constructor for <code>IdentityLinkAssertionParser</code>. A DOM-representation of the incoming
+ * Inputstream will be created
+ *
* @param xmlAssertion <code>&lt;saml:Assertion&gt;</code> as InputStream
- * @throws EAAFParserException on any parsing error
+ * @throws EaafParserException on any parsing error
*/
- public SimpleIdentityLinkAssertionParser(InputStream xmlAssertion) throws EAAFParserException {
+ public SimpleIdentityLinkAssertionParser(final InputStream xmlAssertion)
+ throws EaafParserException {
try {
- assertionElem = DOMUtils.parseXmlValidating(xmlAssertion);
-
- }
- catch (Throwable t) {
- throw new EAAFParserException("parser.01", new Object[] { t.toString() }, t);
-
+ assertionElem = DomUtils.parseXmlValidating(xmlAssertion);
+
+ } catch (final Throwable t) {
+ throw new EaafParserException("parser.01", new Object[] {t.toString()}, t);
+
}
}
/**
* Parses the identity link from the <code>&lt;saml:Assertion&gt;</code>
+ *
* @return Identity link
- * @throws EAAFParserException on any parsing error
+ * @throws EaafParserException on any parsing error
*/
- public IIdentityLink parseIdentityLink() throws EAAFParserException {
+ public IIdentityLink parseIdentityLink() throws EaafParserException {
IIdentityLink identityLink;
try {
identityLink = new IdentityLink();
identityLink.setSamlAssertion(assertionElem);
identityLink.setIssueInstant(assertionElem.getAttribute(ISSUE_INSTANT_ATTR));
- identityLink.setPrPerson((Element)
- XPathUtils.selectSingleNode(assertionElem, PERSON_XPATH));
+ identityLink.setPrPerson((Element) XPathUtils.selectSingleNode(assertionElem, PERSON_XPATH));
identityLink.setIdentificationValue(
- XPathUtils.getElementValue(assertionElem, PERSON_IDENT_VALUE_XPATH, ""));
- identityLink.setIdentificationType(
- XPathUtils.getElementValue(assertionElem, PERSON_IDENT_TYPE_XPATH, ""));
-
- String givenname = XPathUtils.getElementValue(assertionElem, PERSON_GIVEN_NAME_XPATH, "");
- String familyname = XPathUtils.getElementValue(assertionElem, PERSON_FAMILY_NAME_XPATH, "");
+ XPathUtils.getElementValue(assertionElem, PERSON_IDENT_VALUE_XPATH, ""));
+ identityLink.setIdentificationType(
+ XPathUtils.getElementValue(assertionElem, PERSON_IDENT_TYPE_XPATH, ""));
+
+ final String givenname =
+ XPathUtils.getElementValue(assertionElem, PERSON_GIVEN_NAME_XPATH, "");
+ final String familyname =
+ XPathUtils.getElementValue(assertionElem, PERSON_FAMILY_NAME_XPATH, "");
+
+ // replace ' in name with &#39;
+ // givenname = givenname.replaceAll("'", "&#39;");
+ // familyname = familyname.replaceAll("'", "&#39;");
- // replace ' in name with &#39;
-// givenname = givenname.replaceAll("'", "&#39;");
-// familyname = familyname.replaceAll("'", "&#39;");
-
identityLink.setGivenName(givenname);
identityLink.setFamilyName(familyname);
identityLink.setDateOfBirth(
- XPathUtils.getElementValue(assertionElem, PERSON_DATE_OF_BIRTH_XPATH, ""));
- NodeIterator dsigRefTransforms =
- XPathUtils.selectNodeIterator(assertionElem, DSIG_REFERENCE_TRANSFORMATION_XPATH);
- List transElems = new ArrayList();
- Element transformsElem;
- while ((transformsElem = (Element) dsigRefTransforms.nextNode()) != null) {
- transElems.add(transformsElem);
- }
- Element[] result = new Element[transElems.size()];
- transElems.toArray(result);
- identityLink.setDsigReferenceTransforms(result);
-
- //identityLink.setPublicKey(getPublicKeys());
-
- }
- catch (Throwable t) {
- throw new EAAFParserException("parser.01", new Object[] { t.toString() }, t);
+ XPathUtils.getElementValue(assertionElem, PERSON_DATE_OF_BIRTH_XPATH, ""));
+ final NodeIterator dsigRefTransforms =
+ XPathUtils.selectNodeIterator(assertionElem, DSIG_REFERENCE_TRANSFORMATION_XPATH);
+ final List transElems = new ArrayList();
+ Element transformsElem;
+ while ((transformsElem = (Element) dsigRefTransforms.nextNode()) != null) {
+ transElems.add(transformsElem);
+ }
+ final Element[] result = new Element[transElems.size()];
+ transElems.toArray(result);
+ identityLink.setDsigReferenceTransforms(result);
+
+ // identityLink.setPublicKey(getPublicKeys());
+
+ } catch (final Throwable t) {
+ throw new EaafParserException("parser.01", new Object[] {t.toString()}, t);
}
return identityLink;
}
/**
- * Parses a string array of decoded base64 certificates from
- * the <code>&lt;InfoboxReadResponse&gt;</code> found in the dsig-signature
- * @return String[] with raw-certificates from the dsig-signature keyinfo
- * @throws Exception
- */
+ * Parses a string array of decoded base64 certificates from the
+ * <code>&lt;InfoboxReadResponse&gt;</code> found in the dsig-signature
+ *
+ * @return String[] with raw-certificates from the dsig-signature keyinfo
+ * @throws Exception
+ */
public String[] getCertificates() throws Exception {
- List certs = new ArrayList();
- NodeIterator rsaIter =
- XPathUtils.selectNodeIterator(assertionElem, DSIG_CERTIFICATES_XPATH);
+ final List certs = new ArrayList();
+ final NodeIterator rsaIter =
+ XPathUtils.selectNodeIterator(assertionElem, DSIG_CERTIFICATES_XPATH);
Element certElem;
while ((certElem = (Element) rsaIter.nextNode()) != null) {
- String content = DOMUtils.getText(certElem);
- certs.add(new String(Base64Utils.decodeFromString(content)));
-
+ final String content = DomUtils.getText(certElem);
+ certs.add(new String(Base64Utils.decodeFromString(content), "UTF-8"));
+
}
- String[] result = new String[certs.size()];
+ final String[] result = new String[certs.size()];
certs.toArray(result);
return result;
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
index ce9ba57c..c785e1cb 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * 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.
+/*
+ * 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:
+ * 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.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.auth.modules;
import java.io.ByteArrayOutputStream;
@@ -34,21 +27,8 @@ import java.util.Iterator;
import java.util.List;
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;
-import org.apache.commons.fileupload.FileUploadException;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.lang3.ArrayUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.ResourceLoader;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
@@ -56,216 +36,233 @@ 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.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController;
import at.gv.egiz.eaaf.core.impl.idp.process.springweb.AbstractTask;
-import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder;
+import at.gv.egiz.eaaf.core.impl.utils.DataUrlBuilder;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
/**
- * Task based counterpart to {@link AuthServlet}, providing the same utility methods (error handling, parameter parsing
- * etc.).</p> The code has been taken from {@link AuthServlet}.
+ * Task based counterpart to {@link AuthServlet}, providing the same utility methods (error
+ * handling, parameter parsing etc.).
+ * </p>
+ * The code has been taken from {@link AuthServlet}.
*/
public abstract class AbstractAuthServletTask extends AbstractTask {
- private static final Logger log = LoggerFactory.getLogger(AbstractAuthServletTask.class);
-
- @Autowired(required=true) IProtocolAuthenticationService protAuchService;
- @Autowired(required=true) protected IRequestStorage requestStoreage;
- @Autowired(required=true) protected IConfiguration authConfig;
- @Autowired(required=true) protected ResourceLoader resourceLoader;
-
- @Autowired protected IRevisionLogger revisionsLogger;
-
- protected static final String ERROR_CODE_PARAM = "errorid";
-
- protected IRequest pendingReq = null;
-
- @Override
- public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
- HttpServletResponse response) throws TaskExecutionException;
-
-
- @Override
- protected final IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request,
- HttpServletResponse response) throws TaskExecutionException {
- //set pending-request object
- this.pendingReq = pendingReq;
-
- //add latest pendingRequestId on execution context
- executionContext.put(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID, pendingReq.getPendingRequestId());
-
- //execute task specific action
- execute(executionContext, request, response);
-
- //return pending-request object
- return this.pendingReq;
- }
-
- /**
- * Redirect the authentication process to protocol specific finalization endpoint.
- * @param executionContext
- *
- * @param pendingReq Actually processed protocol specific authentication request
- * @param httpResp
- * @throws IOException
- * @throws EAAFException
- */
- protected void performRedirectToProtocolFinialization(ExecutionContext executionContext, IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp) throws EAAFException, IOException {
- final 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(httpReq, httpResp, pendingReq);
-
- } else {
- log.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
- requestStoreage.storePendingRequest(pendingReq);
- performRedirectToItself(pendingReq, httpResp, ProtocolFinalizationController.ENDPOINT_FINALIZEPROTOCOL);
-
- }
-
-
-
- }
-
- /**
- * Redirect the authentication process to IDP itself
- *
- * @param pendingReq Actually processed protocol specific authentication request
- * @param httpResp
- * @param idpEndPoint Servlet EndPoint that should receive the redirect
- */
- protected void performRedirectToItself(IRequest pendingReq, HttpServletResponse httpResp, String idpEndPoint) {
- final String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(),
- idpEndPoint, pendingReq.getPendingRequestId());
-
- httpResp.setContentType("text/html");
- httpResp.setStatus(302);
- httpResp.addHeader("Location", redirectURL);
- log.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).
- *
- * @param req
- * servlet request
- *
- * @return mapping parameter name -> value
- *
- * @throws IOException
- * if parsing request parameters fails.
- *
- * @throws FileUploadException
- * if parsing request parameters fails.
- */
- protected Map<String, String> getParameters(HttpServletRequest req) throws IOException,
- FileUploadException {
-
- final Map<String, String> parameters = new HashMap<String, String>();
-
- if (ServletFileUpload.isMultipartContent(req)) {
- // request is encoded as mulitpart/form-data
- final FileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = null;
- upload = new ServletFileUpload(factory);
- List items = null;
- items = upload.parseRequest(req);
- for (int i = 0; i < items.size(); i++) {
- final FileItem item = (FileItem) items.get(i);
- if (item.isFormField()) {
- // Process only form fields - no file upload items
- parameters.put(item.getFieldName(), item.getString("UTF-8"));
-
- //log requests on trace
- if (log.isTraceEnabled()) {
- final String logString = item.getString("UTF-8");
-
- // TODO use RegExp
- final String startS = "<pr:Identification><pr:Value>";
- final String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>";
- String logWithMaskedBaseid = logString;
- final int start = logString.indexOf(startS);
- if (start > -1) {
- final int end = logString.indexOf(endS);
- if (end > -1) {
- logWithMaskedBaseid = logString.substring(0, start);
- logWithMaskedBaseid += startS;
- logWithMaskedBaseid += "xxxxxxxxxxxxxxxxxxxxxxxx";
- logWithMaskedBaseid += logString.substring(end,
- logString.length());
- }
- }
-
- log.debug("Processed multipart/form-data request parameter: \nName: "
- + item.getFieldName()
- + "\nValue: "
- + logWithMaskedBaseid);
- }
-
- }
- }
- }
-
- else {
- final Iterator<Entry<String, String[]>> requestParamIt = req.getParameterMap().entrySet().iterator();
- while (requestParamIt.hasNext()) {
- final Entry<String, String[]> entry = requestParamIt.next();
- final String key = entry.getKey();
- final String[] values = entry.getValue();
- // take the last value from the value array since the legacy code above also does it this way
- parameters.put(key, ArrayUtils.isEmpty(values) ? null : values[values.length-1]);
- }
-
- }
-
- return parameters;
- }
-
- /**
- * Reads bytes up to a delimiter, consuming the delimiter.
- *
- * @param in
- * input stream
- * @param delimiter
- * delimiter character
- * @return String constructed from the read bytes
- * @throws IOException
- */
- protected String readBytesUpTo(InputStream in, char delimiter)
- throws IOException {
- final ByteArrayOutputStream bout = new ByteArrayOutputStream();
- boolean done = false;
- int b;
- while (!done && (b = in.read()) >= 0) {
- if (b == delimiter)
- done = true;
- else
- bout.write(b);
- }
- return bout.toString();
- }
-
- /**
- * Adds a parameter to a URL.
- *
- * @param url
- * the URL
- * @param paramname
- * parameter name
- * @param paramvalue
- * parameter value
- * @return the URL with parameter added
- */
- protected static String addURLParameter(String url, String paramname,
- String paramvalue) {
- final String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
+ private static final Logger log = LoggerFactory.getLogger(AbstractAuthServletTask.class);
+
+ @Autowired(required = true)
+ IProtocolAuthenticationService protAuchService;
+ @Autowired(required = true)
+ protected IRequestStorage requestStoreage;
+ @Autowired(required = true)
+ protected IConfiguration authConfig;
+ @Autowired(required = true)
+ protected ResourceLoader resourceLoader;
+
+ @Autowired
+ protected IRevisionLogger revisionsLogger;
+
+ protected static final String ERROR_CODE_PARAM = "errorid";
+
+ protected IRequest pendingReq = null;
+
+ @Override
+ public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response) throws TaskExecutionException;
+
+
+ @Override
+ protected final IRequest internalExecute(final IRequest pendingReq,
+ final ExecutionContext executionContext, final HttpServletRequest request,
+ final HttpServletResponse response) throws TaskExecutionException {
+ // set pending-request object
+ this.pendingReq = pendingReq;
+
+ // add latest pendingRequestId on execution context
+ executionContext.put(EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID,
+ pendingReq.getPendingRequestId());
+
+ // execute task specific action
+ execute(executionContext, request, response);
+
+ // return pending-request object
+ return this.pendingReq;
+ }
+
+ /**
+ * Redirect the authentication process to protocol specific finalization endpoint.
+ *
+ * @param executionContext
+ *
+ * @param pendingReq Actually processed protocol specific authentication request
+ * @param httpResp http response object
+ * @throws IOException In case of a general error
+ * @throws EaafException In case of an application error
+ */
+ protected void performRedirectToProtocolFinialization(final ExecutionContext executionContext,
+ final IRequest pendingReq, final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp) throws EaafException, IOException {
+ final 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(httpReq, httpResp, pendingReq);
+
+ } else {
+ log.info("AuthProcess finished. Redirect to Protocol Dispatcher.");
+ requestStoreage.storePendingRequest(pendingReq);
+ performRedirectToItself(pendingReq, httpResp,
+ ProtocolFinalizationController.ENDPOINT_FINALIZEPROTOCOL);
+
+ }
+
+
+
+ }
+
+ /**
+ * Redirect the authentication process to IDP itself.
+ *
+ * @param pendingReq Actually processed protocol specific authentication request
+ * @param httpResp http response
+ * @param idpEndPoint Servlet EndPoint that should receive the redirect
+ */
+ protected void performRedirectToItself(final IRequest pendingReq,
+ final HttpServletResponse httpResp, final String idpEndPoint) {
+ final String redirectUrl = new DataUrlBuilder().buildDataUrl(pendingReq.getAuthUrl(),
+ idpEndPoint, pendingReq.getPendingRequestId());
+
+ httpResp.setContentType("text/html");
+ httpResp.setStatus(302);
+ httpResp.addHeader("Location", redirectUrl);
+ log.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).
+ *
+ * @param req servlet request
+ *
+ * @return mapping parameter name -> value
+ *
+ * @throws IOException if parsing request parameters fails.
+ *
+ * @throws FileUploadException if parsing request parameters fails.
+ */
+ protected Map<String, String> getParameters(final HttpServletRequest req)
+ throws IOException, FileUploadException {
+
+ final Map<String, String> parameters = new HashMap<>();
+
+ if (ServletFileUpload.isMultipartContent(req)) {
+ // request is encoded as mulitpart/form-data
+ final FileItemFactory factory = new DiskFileItemFactory();
+ ServletFileUpload upload = null;
+ upload = new ServletFileUpload(factory);
+ List items = null;
+ items = upload.parseRequest(req);
+ for (int i = 0; i < items.size(); i++) {
+ final FileItem item = (FileItem) items.get(i);
+ if (item.isFormField()) {
+ // Process only form fields - no file upload items
+ parameters.put(item.getFieldName(), item.getString("UTF-8"));
+
+ // log requests on trace
+ if (log.isTraceEnabled()) {
+ final String logString = item.getString("UTF-8");
+
+ // TODO use RegExp
+ final String startS = "<pr:Identification><pr:Value>";
+ final String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>";
+ String logWithMaskedBaseid = logString;
+ final int start = logString.indexOf(startS);
+ if (start > -1) {
+ final int end = logString.indexOf(endS);
+ if (end > -1) {
+ logWithMaskedBaseid = logString.substring(0, start);
+ logWithMaskedBaseid += startS;
+ logWithMaskedBaseid += "xxxxxxxxxxxxxxxxxxxxxxxx";
+ logWithMaskedBaseid += logString.substring(end, logString.length());
+ }
+ }
+
+ log.debug("Processed multipart/form-data request parameter: \nName: "
+ + item.getFieldName() + "\nValue: " + logWithMaskedBaseid);
+ }
+
+ }
+ }
+
+ } else {
+ final Iterator<Entry<String, String[]>> requestParamIt =
+ req.getParameterMap().entrySet().iterator();
+ while (requestParamIt.hasNext()) {
+ final Entry<String, String[]> entry = requestParamIt.next();
+ final String key = entry.getKey();
+ final String[] values = entry.getValue();
+ // take the last value from the value array since the legacy code above also does it this
+ // way
+ parameters.put(key, ArrayUtils.isEmpty(values) ? null : values[values.length - 1]);
+ }
+
+ }
+
+ return parameters;
+ }
+
+ /**
+ * Reads bytes up to a delimiter, consuming the delimiter.
+ *
+ * @param in input stream
+ * @param delimiter delimiter character
+ * @return String constructed from the read bytes
+ * @throws IOException In case of a general error
+ */
+ protected String readBytesUpTo(final InputStream in, final char delimiter) throws IOException {
+ final ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ boolean done = false;
+ int b;
+ while (!done && (b = in.read()) >= 0) {
+ if (b == delimiter) {
+ done = true;
+ } else {
+ bout.write(b);
+ }
+ }
+ return bout.toString("UTF-8");
+
+ }
+
+ /**
+ * Adds a parameter to a URL.
+ *
+ * @param url the URL
+ * @param paramname parameter name
+ * @param paramvalue parameter value
+ * @return the URL with parameter added
+ */
+ protected static String addUrlParameter(final String url, final String paramname,
+ final String paramvalue) {
+ final String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0) {
+ return url + "?" + param;
+ } else {
+ return url + "&" + param;
+ }
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
index 6789c802..b04b000e 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java
@@ -1,43 +1,38 @@
-/*******************************************************************************
- * 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.
+/*
+ * 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:
+ * 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.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.auth.modules;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
-
import javax.annotation.PostConstruct;
-
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParserException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,135 +40,124 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
-import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParserException;
-
/**
- * This class handles registering modules. The modules are detected either with
- * the ServiceLoader mechanism or via Spring. All detected modules are ranked
- * according to their priority.
+ * This class handles registering modules. The modules are detected either with the ServiceLoader
+ * mechanism or via Spring. All detected modules are ranked according to their priority.
*/
public class ModuleRegistration {
- private static ModuleRegistration instance = new ModuleRegistration();
-
- private final List<AuthModule> priorizedModules = new ArrayList<>();
-
- @Autowired
- private ApplicationContext ctx;
-
- @Autowired
- private ProcessEngine processEngine;
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- public static ModuleRegistration getInstance() {
- return instance;
- }
-
- private ModuleRegistration() {
- }
-
- @PostConstruct
- private void init() {
- // load modules via the ServiceLoader
- initServiceLoaderModules();
-
- // load modules via Spring
- initSpringModules();
-
- // order modules according to their priority
- sortModules();
-
- instance = this;
- }
-
- /**
- * Discovers modules which use the ServiceLoader mechanism.
- */
- private void initServiceLoaderModules() {
- log.info("Looking for auth modules.");
- final ServiceLoader<AuthModule> loader = ServiceLoader.load(AuthModule.class);
- final Iterator<AuthModule> modules = loader.iterator();
- while (modules.hasNext()) {
- final AuthModule module = modules.next();
- log.info("Detected module {}", module.getClass().getName());
- registerModuleProcessDefinitions(module);
- priorizedModules.add(module);
- }
- }
-
- /**
- * Discovers modules which use Spring.
- */
- private void initSpringModules() {
- log.debug("Discovering Spring modules.");
- final Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);
- for (final AuthModule module : modules.values()) {
- registerModuleProcessDefinitions(module);
- priorizedModules.add(module);
- }
- }
-
- /**
- * Registers the resource uris for the module.
- *
- * @param module
- * the module.
- */
- private void registerModuleProcessDefinitions(AuthModule module) {
- for (final String uri : module.getProcessDefinitions()) {
- final Resource resource = ctx.getResource(uri);
- if (resource.isReadable()) {
- log.info("Registering process definition '{}'.", uri);
- try (InputStream processDefinitionInputStream = resource.getInputStream()) {
- processEngine.registerProcessDefinition(processDefinitionInputStream);
- } catch (final IOException e) {
- log.error("Process definition '{}' could NOT be read.", uri, e);
- } catch (final ProcessDefinitionParserException e) {
- log.error("Error while parsing process definition '{}'", uri, e);
- }
- } else {
- log.error("Process definition '{}' cannot be read.", uri);
- }
- }
- }
-
- /**
- * Order the modules in descending order according to their priority.
- */
- private void sortModules() {
- Collections.sort(priorizedModules, new Comparator<AuthModule>() {
- @Override
- public int compare(AuthModule thisAuthModule, AuthModule otherAuthModule) {
- final int thisOrder = thisAuthModule.getPriority();
- final int otherOrder = otherAuthModule.getPriority();
- return (thisOrder < otherOrder ? 1 : (thisOrder == otherOrder ? 0 : -1));
- }
- });
- }
-
- /**
- * Returns the process description id of the first process, in the highest ranked
- * module, which is able to work with the given execution context.
- *
- * @param context
- * the {@link ExecutionContext}.
- * @param pendingReq the current processed {@link IRequest}
- * @return the process id or {@code null}
- */
- public String selectProcess(ExecutionContext context, IRequest pendingReq) {
- for (final AuthModule module : priorizedModules) {
- final String id = module.selectProcess(context, pendingReq);
- if (StringUtils.isNotEmpty(id)) {
- log.debug("Process with id '{}' selected, for context '{}'.", id, context);
- return id;
- }
- }
- log.info("No process is able to handle context '{}'.", context);
- return null;
- }
+ //private static ModuleRegistration instance = new ModuleRegistration();
+
+ private final List<AuthModule> priorizedModules = new ArrayList<>();
+
+ @Autowired
+ private ApplicationContext ctx;
+
+ @Autowired
+ private ProcessEngine processEngine;
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+// public static ModuleRegistration getInstance() {
+// return ctx.;
+// }
+
+ private ModuleRegistration() {
+
+ }
+
+ @PostConstruct
+ private void init() {
+ // load modules via the ServiceLoader
+ initServiceLoaderModules();
+
+ // load modules via Spring
+ initSpringModules();
+
+ // order modules according to their priority
+ sortModules();
+
+ //instance = this;
+ }
+
+ /**
+ * Discovers modules which use the ServiceLoader mechanism.
+ */
+ private void initServiceLoaderModules() {
+ log.info("Looking for auth modules.");
+ final ServiceLoader<AuthModule> loader = ServiceLoader.load(AuthModule.class);
+ final Iterator<AuthModule> modules = loader.iterator();
+ while (modules.hasNext()) {
+ final AuthModule module = modules.next();
+ log.info("Detected module {}", module.getClass().getName());
+ registerModuleProcessDefinitions(module);
+ priorizedModules.add(module);
+ }
+ }
+
+ /**
+ * Discovers modules which use Spring.
+ */
+ private void initSpringModules() {
+ log.debug("Discovering Spring modules.");
+ final Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);
+ for (final AuthModule module : modules.values()) {
+ registerModuleProcessDefinitions(module);
+ priorizedModules.add(module);
+ }
+ }
+
+ /**
+ * Registers the resource uris for the module.
+ *
+ * @param module the module.
+ */
+ private void registerModuleProcessDefinitions(final AuthModule module) {
+ for (final String uri : module.getProcessDefinitions()) {
+ final Resource resource = ctx.getResource(uri);
+ if (resource.isReadable()) {
+ log.info("Registering process definition '{}'.", uri);
+ try (InputStream processDefinitionInputStream = resource.getInputStream()) {
+ processEngine.registerProcessDefinition(processDefinitionInputStream);
+ } catch (final IOException e) {
+ log.error("Process definition '{}' could NOT be read.", uri, e);
+ } catch (final ProcessDefinitionParserException e) {
+ log.error("Error while parsing process definition '{}'", uri, e);
+ }
+ } else {
+ log.error("Process definition '{}' cannot be read.", uri);
+ }
+ }
+ }
+
+ /**
+ * Order the modules in descending order according to their priority.
+ */
+ private void sortModules() {
+ Collections.sort(priorizedModules, (thisAuthModule, otherAuthModule) -> {
+ final int thisOrder = thisAuthModule.getPriority();
+ final int otherOrder = otherAuthModule.getPriority();
+ return (thisOrder < otherOrder ? 1 : (thisOrder == otherOrder ? 0 : -1));
+ });
+ }
+
+ /**
+ * Returns the process description id of the first process, in the highest ranked module, which is
+ * able to work with the given execution context.
+ *
+ * @param context the {@link ExecutionContext}.
+ * @param pendingReq the current processed {@link IRequest}
+ * @return the process id or {@code null}
+ */
+ public String selectProcess(final ExecutionContext context, final IRequest pendingReq) {
+ for (final AuthModule module : priorizedModules) {
+ final String id = module.selectProcess(context, pendingReq);
+ if (StringUtils.isNotEmpty(id)) {
+ log.debug("Process with id '{}' selected, for context '{}'.", id, context);
+ return id;
+ }
+ }
+ log.info("No process is able to handle context '{}'.", context);
+ return null;
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java
index 2edf8a75..a5030851 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java
@@ -1,25 +1,22 @@
-/*******************************************************************************
- * Copyright 2019 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2019 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * 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.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.auth.services;
import java.io.IOException;
@@ -27,499 +24,518 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
-
import javax.naming.ConfigurationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.text.StringEscapeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.lang.NonNull;
-import org.springframework.lang.Nullable;
-import org.springframework.stereotype.Service;
-
import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
-import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
-import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
+import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.api.gui.IGuiFormBuilder;
import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
import at.gv.egiz.eaaf.core.api.idp.IAction;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder;
import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IspConfiguration;
import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager;
-import at.gv.egiz.eaaf.core.api.idp.auth.ISSOManager;
+import at.gv.egiz.eaaf.core.api.idp.auth.ISsoManager;
import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
-import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFSSOException;
-import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafSsoException;
+import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;
import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
-import at.gv.egiz.eaaf.core.impl.gui.AbstractGUIFormBuilderConfiguration;
+import at.gv.egiz.eaaf.core.impl.gui.AbstractGuiFormBuilderConfiguration;
import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
-import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
+import at.gv.egiz.eaaf.core.impl.utils.HttpUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.lang.NonNull;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Service;
@Service
public class ProtocolAuthenticationService implements IProtocolAuthenticationService {
- private static final Logger log = LoggerFactory.getLogger(ProtocolAuthenticationService.class);
-
- private static final List<String> ERROR_LOGGER_ON_INFO_LEVEL =
- Arrays.asList(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP
- );
-
- @Autowired(required=true) private ApplicationContext applicationContext;
- @Autowired(required=true) private IAuthenticationManager authmanager;
- @Autowired(required=true) private IAuthenticationDataBuilder authDataBuilder;
- @Autowired(required=true) private IGUIBuilderConfigurationFactory guiConfigFactory;
- @Autowired(required=true) private IStatusMessenger statusMessager;
- @Autowired(required=true) private IRequestStorage requestStorage;
- @Autowired(required=true) IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy;
-
- @Autowired(required=false) private ISSOManager ssoManager;
- @Autowired private IStatisticLogger statisticLogger;
- @Autowired private IRevisionLogger revisionsLogger;
-
-
- private IGUIFormBuilder guiBuilder;
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#performAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
- */
- @Override
- public void performAuthentication(final HttpServletRequest req, final HttpServletResponse resp,
- final IRequest pendingReq) throws IOException, EAAFException {
- try {
- if (pendingReq.isNeedAuthentication()) {
- //request needs authentication --> start authentication process ...
-
- //set pendingRequestId to support asynchrony message-processing
- ((RequestImpl)pendingReq).setPendingRequestId(pendingReqIdGenerationStrategy.generateExternalPendingRequestId());
-
- //load Parameters from OnlineApplicationConfiguration
- final ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
-
- if (oaParam == null)
- throw new EAAFAuthenticationException(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
- new Object[] { pendingReq.getSPEntityId() });
-
- if (authmanager.doAuthentication(req, resp, pendingReq)) {
- //pending request is already authenticated --> protocol-specific postProcessing can start directly
- finalizeAuthentication(req, resp, pendingReq);
-
- //transaction is finished, log transaction finished event
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
-
- }
-
- } else {
- executeProtocolSpecificAction(req, resp, pendingReq, null);
-
- }
-
- } catch (final Exception e) {
- buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
- }
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#finalizeAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
- */
- @Override
- public void finalizeAuthentication(final HttpServletRequest req, final HttpServletResponse resp, final IRequest pendingReq) throws EAAFException, IOException{
- log.debug("Finalize PendingRequest with ID " + pendingReq.getPendingRequestId());
- try {
-
- //check if pending-request has 'abortedByUser' flag set
- if (pendingReq.isAbortedByUser()) {
- //send authentication aborted error to Service Provider
- buildProtocolSpecificErrorResponse(
- new EAAFAuthenticationException(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP,
- new Object[] {}),
- req, resp, pendingReq);
-
- //do not remove the full active SSO-Session
- // in case of only one Service-Provider authentication request is aborted
- if ( !pendingReq.needSingleSignOnFunctionality()) {
- requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
-
- }
-
- //check if pending-request are authenticated
- } else if (pendingReq.isAuthenticated() && !pendingReq.isNeedUserConsent()) {
- internalFinalizeAuthenticationProcess(req, resp, pendingReq);
-
- } else {
- //suspect state: pending-request is not aborted but also are not authenticated
- log.warn("PendingRequest flag for 'authenticated':{} and 'needConsent':{}", pendingReq.isAuthenticated(), pendingReq.isNeedUserConsent());
- if (pendingReq.isNeedUserConsent()) {
- log.error("PendingRequest NEEDS user-consent. Can NOT fininalize authentication --> Abort authentication process!");
-
- } else {
- log.error("PendingRequest is NOT authenticated --> Abort authentication process!");
-
- }
-
- handleErrorNoRedirect(
- new EAAFException(
- "auth.20",
- null), req, resp, true);
-
- }
-
- } catch (final Exception e) {
- log.error("Finalize authentication protocol FAILED." , e);
- buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
-
- }
-
- //remove pending-request
- if (pendingReq != null) {
- requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
-
- }
- }
-
-
- @Override
- public void buildProtocolSpecificErrorResponse(final Throwable throwable, final HttpServletRequest req,
- final HttpServletResponse resp, final IRequest protocolRequest) throws EAAFException, IOException {
- try {
-
- final Class<?> clazz = Class.forName(protocolRequest.requestedModule());
-
- if (clazz == null ||
- !IModulInfo.class.isAssignableFrom(clazz)) {
- log.error("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
- throw new Exception("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
-
- }
-
- final IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
-
- if (handlingModule.generateErrorMessage(
- throwable, req, resp, protocolRequest)) {
-
- //log Error to technical log
- logExceptionToTechnicalLog(throwable);
-
- //log Error Message
- statisticLogger.logErrorOperation(throwable, protocolRequest);
-
- //write revision log entries
- revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR, protocolRequest.getUniqueTransactionIdentifier());
-
- return;
-
- } else {
- handleErrorNoRedirect(throwable, req, resp, true);
-
- }
-
- } catch (final Throwable e) {
- handleErrorNoRedirect(throwable, req, resp, true);
-
- }
-
- }
-
- @Override
- public void handleErrorNoRedirect(final Throwable throwable, final HttpServletRequest req,
- final HttpServletResponse resp, final boolean writeExceptionToStatisticLog) throws IOException, EAAFException {
-
- //log Exception into statistic database
- if (writeExceptionToStatisticLog)
- statisticLogger.logErrorOperation(throwable);
-
- //write errror to console
- logExceptionToTechnicalLog(throwable);
-
- //return error to Web browser
- if (throwable instanceof EAAFException || throwable instanceof ProcessExecutionException)
- internalMOAIDExceptionHandler(req, resp, (Exception)throwable, false);
-
- else {
- //write generic message for general exceptions
- final String msg = statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null);
- writeHTMLErrorResponse(req, resp, msg, "9199", null, (Exception) throwable);
-
- }
-
- }
-
-
- public void setGuiBuilder(IGUIFormBuilder guiBuilder) {
- this.guiBuilder = guiBuilder;
- }
-
- /**
- * Finalize the requested protocol operation
- *
- * @param httpReq HttpServletRequest
- * @param httpResp HttpServletResponse
- * @param protocolRequest Authentication request which is actually in process
- * @param moaSession MOASession object, which is used to generate the protocol specific authentication information
- * @throws Exception
- */
- protected void internalFinalizeAuthenticationProcess(final HttpServletRequest req, final HttpServletResponse resp,
- final IRequest pendingReq) throws Exception {
-
- String newSSOSessionId = null;
-
- //if Single Sign-On functionality is enabled for this request
- if (pendingReq.needSingleSignOnFunctionality()) {
- if (ssoManager != null) {
- newSSOSessionId = ssoManager.createNewSSOSessionCookie(req, resp, pendingReq);
- if (StringUtils.isEmpty(pendingReq.getInternalSSOSessionIdentifier()))
- ssoManager.createNewSSOSession(pendingReq, newSSOSessionId);
-
- } else
- log.warn("SSO is requested but there is not SSO Session-Manager available");
-
- }
-
- //build authenticationdata from session information and OA configuration
- final IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);
-
- //execute the protocol-specific action
- final SLOInformationInterface sloInformation = executeProtocolSpecificAction(req, resp, pendingReq, authData);
-
- //Store OA specific SSO session information if an SSO cookie is set
- if (StringUtils.isNotEmpty(newSSOSessionId)) {
- try {
- ssoManager.updateSSOSession(pendingReq, newSSOSessionId, sloInformation);
-
- } catch (final EAAFSSOException e) {
- log.warn("SSO Session information can not be stored -> SSO is not enabled!");
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
-
- } else {
- //remove MOASession from database
- authmanager.performOnlyIDPLogOut(req, resp, pendingReq);
-
- }
-
- //Advanced statistic logging
- statisticLogger.logSuccessOperation(pendingReq, authData, StringUtils.isNotEmpty(newSSOSessionId));
-
- }
-
- /**
- * Executes the requested protocol action
- *
- * @param httpReq HttpServletRequest
- * @param httpResp HttpServletResponse
- * @param protocolRequest Authentication request which is actually in process
- * @param authData Service-provider specific authentication data
- *
- * @return Return Single LogOut information or null if protocol supports no SSO
- *
- * @throws Exception
- */
- private SLOInformationInterface executeProtocolSpecificAction(final HttpServletRequest httpReq, final HttpServletResponse httpResp,
- final IRequest pendingReq, final IAuthData authData) throws Exception {
- try {
- // request needs no authentication --> start request processing
- final Class<?> clazz = Class.forName(pendingReq.requestedAction());
- if (clazz == null ||
- !IAction.class.isAssignableFrom(clazz)) {
- log.error("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
- throw new Exception("Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
-
- }
-
- final IAction protocolAction = (IAction) applicationContext.getBean(clazz);
- return protocolAction.processRequest(pendingReq, httpReq, httpResp, authData);
-
- } catch (final ClassNotFoundException e) {
- log.error("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
- throw new Exception("Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
- }
-
- }
-
- /**
- * Write a Exception to the MOA-ID-Auth internal technical log
- *
- * @param loggedException Exception to log
- */
- protected void logExceptionToTechnicalLog(final Throwable loggedException) {
- if (!( loggedException instanceof EAAFException
- || loggedException instanceof ProcessExecutionException )) {
- log.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
-
- } else {
- if (loggedException instanceof EAAFAuthenticationException &&
- ERROR_LOGGER_ON_INFO_LEVEL.contains(
- ((EAAFAuthenticationException) loggedException).getErrorId())) {
- if (log.isDebugEnabled() || log.isTraceEnabled()) {
- log.info(loggedException.getMessage(), loggedException);
-
- } else {
- log.info(loggedException.getMessage());
-
- }
-
- } else {
- if (log.isDebugEnabled() || log.isTraceEnabled()) {
- log.warn(loggedException.getMessage(), loggedException);
-
- } else {
- log.warn(loggedException.getMessage());
-
- }
- }
- }
- }
-
- private void writeHTMLErrorResponse(@NonNull final HttpServletRequest httpReq, @NonNull final HttpServletResponse httpResp,
- @NonNull final String msg, @NonNull final String errorCode, @Nullable final Object[] params, @NonNull final Exception error) throws IOException, EAAFException {
-
- try {
- final IGUIBuilderConfiguration config
- = guiConfigFactory.getDefaultErrorGUI(HTTPUtils.extractAuthURLFromRequest(httpReq));
-
-
- String[] errorCodeParams = null;
- if (params == null)
- errorCodeParams = new String[] {};
- else {
- errorCodeParams = new String[params.length];
- for (int i=0; i<params.length; i++) {
- if (params[i] != null)
- errorCodeParams[i] = params[i].toString();
- else
- errorCodeParams[i] = "null";
-
- }
- }
-
-
-
- //add errorcode and errormessage
- if (config instanceof ModifyableGuiBuilderConfiguration) {
- ((ModifyableGuiBuilderConfiguration)config)
- .putCustomParameter(AbstractGUIFormBuilderConfiguration.PARAM_GROUP_MSG,
- PARAM_GUI_ERROMSG, msg);
- ((ModifyableGuiBuilderConfiguration)config)
- .putCustomParameter(AbstractGUIFormBuilderConfiguration.PARAM_GROUP_MSG,
- PARAM_GUI_ERRORCODE, errorCode);
- ((ModifyableGuiBuilderConfiguration)config)
- .putCustomParameterWithOutEscaption(AbstractGUIFormBuilderConfiguration.PARAM_GROUP_MSG,
- PARAM_GUI_ERRORCODEPARAMS, ArrayUtils.toString(errorCodeParams));
-
- //add stacktrace if debug is enabled
- if (log.isTraceEnabled()) {
- ((ModifyableGuiBuilderConfiguration)config)
- .putCustomParameter(AbstractGUIFormBuilderConfiguration.PARAM_GROUP_MSG,
- PARAM_GUI_ERRORSTACKTRACE, getStacktraceFromException(error));
-
- }
-
- } else
- log.info("Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
-
-
-
- guiBuilder.build(httpReq, httpResp, config, "Error-Message");
-
- } catch (final GUIBuildException e) {
- log.warn("Can not build error-message GUI.", e);
- throw new EAAFException("9199", null, e);
-
-
- }
-
- }
-
- private String getStacktraceFromException(final Exception ex) {
- final StringWriter errors = new StringWriter();
- ex.printStackTrace(new PrintWriter(errors));
- return errors.toString();
-
- }
-
- private void internalMOAIDExceptionHandler(final HttpServletRequest req, final HttpServletResponse resp, final Exception e, final boolean writeExceptionToStatisicLog) throws IOException, EAAFException {
- if (e instanceof ProtocolNotActiveException) {
- resp.getWriter().write(e.getMessage());
- resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
- resp.sendError(HttpServletResponse.SC_FORBIDDEN,
- StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
-
- } else if (e instanceof AuthnRequestValidatorException) {
- final AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
- //log Error Message
- if (writeExceptionToStatisicLog)
- statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
-
- //write error message
- //writeBadRequestErrorResponse(req, resp, (EAAFException) e);
- writeHTMLErrorResponse(req, resp,
- e.getMessage(),
- statusMessager.getResponseErrorCode(e),
- null,
- e);
-
- } else if (e instanceof InvalidProtocolRequestException) {
- //send error response
- //writeBadRequestErrorResponse(req, resp, (EAAFException) e);
- writeHTMLErrorResponse(req, resp,
- e.getMessage(),
- statusMessager.getResponseErrorCode(e),
- null,
- e);
-
- } else if (e instanceof ConfigurationException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp,
- e.getMessage(),
- statusMessager.getResponseErrorCode(e),
- null,
- e);
-
- } else if (e instanceof EAAFException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp,
- e.getMessage(),
- statusMessager.getResponseErrorCode(e),
- ((EAAFException) e).getParams(),
- e);
-
- } else if (e instanceof ProcessExecutionException) {
- //send HTML formated error message
- writeHTMLErrorResponse(req, resp,
- e.getMessage(),
- statusMessager.getResponseErrorCode(e),
- null,
- e);
-
- }
-
- }
-
-
+ private static final Logger log = LoggerFactory.getLogger(ProtocolAuthenticationService.class);
+
+ private static final List<String> ERROR_LOGGER_ON_INFO_LEVEL =
+ Arrays.asList(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP);
+
+ @Autowired(required = true)
+ private ApplicationContext applicationContext;
+ @Autowired(required = true)
+ private IAuthenticationManager authmanager;
+ @Autowired(required = true)
+ private IAuthenticationDataBuilder authDataBuilder;
+ @Autowired(required = true)
+ private IGuiBuilderConfigurationFactory guiConfigFactory;
+ @Autowired(required = true)
+ private IStatusMessenger statusMessager;
+ @Autowired(required = true)
+ private IRequestStorage requestStorage;
+ @Autowired(required = true)
+ IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy;
+
+ @Autowired(required = false)
+ private ISsoManager ssoManager;
+ @Autowired
+ private IStatisticLogger statisticLogger;
+ @Autowired
+ private IRevisionLogger revisionsLogger;
+
+
+ private IGuiFormBuilder guiBuilder;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#
+ * performAuthentication(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
+ */
+ @Override
+ public void performAuthentication(final HttpServletRequest req, final HttpServletResponse resp,
+ final IRequest pendingReq) throws IOException, EaafException {
+ try {
+ if (pendingReq.isNeedAuthentication()) {
+ // request needs authentication --> start authentication process ...
+
+ // set pendingRequestId to support asynchrony message-processing
+ ((RequestImpl) pendingReq)
+ .setPendingRequestId(pendingReqIdGenerationStrategy.generateExternalPendingRequestId());
+
+ // load Parameters from OnlineApplicationConfiguration
+ final IspConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+
+ if (oaParam == null) {
+ throw new EaafAuthenticationException(
+ IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
+ new Object[] {pendingReq.getSpEntityId()});
+ }
+
+ if (authmanager.doAuthentication(req, resp, pendingReq)) {
+ // pending request is already authenticated --> protocol-specific postProcessing can start
+ // directly
+ finalizeAuthentication(req, resp, pendingReq);
+
+ // transaction is finished, log transaction finished event
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED,
+ pendingReq.getUniqueTransactionIdentifier());
+
+ }
+
+ } else {
+ executeProtocolSpecificAction(req, resp, pendingReq, null);
+
+ }
+
+ } catch (final Exception e) {
+ buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+ authmanager.performOnlyIdpLogOut(req, resp, pendingReq);
+
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.impl.idp.auth.services.IProtocolAuthenticationService#
+ * finalizeAuthentication(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse, at.gv.egiz.eaaf.core.api.IRequest)
+ */
+ @Override
+ public void finalizeAuthentication(final HttpServletRequest req, final HttpServletResponse resp,
+ final IRequest pendingReq) throws EaafException, IOException {
+ log.debug("Finalize PendingRequest with ID " + pendingReq.getPendingRequestId());
+ try {
+
+ // check if pending-request has 'abortedByUser' flag set
+ if (pendingReq.isAbortedByUser()) {
+ // send authentication aborted error to Service Provider
+ buildProtocolSpecificErrorResponse(
+ new EaafAuthenticationException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_USERSTOP,
+ new Object[] {}),
+ req, resp, pendingReq);
+
+ // do not remove the full active SSO-Session
+ // in case of only one Service-Provider authentication request is aborted
+ if (!pendingReq.needSingleSignOnFunctionality()) {
+ requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+
+ }
+
+ // check if pending-request are authenticated
+ } else if (pendingReq.isAuthenticated() && !pendingReq.isNeedUserConsent()) {
+ internalFinalizeAuthenticationProcess(req, resp, pendingReq);
+
+ } else {
+ // suspect state: pending-request is not aborted but also are not authenticated
+ log.warn("PendingRequest flag for 'authenticated':{} and 'needConsent':{}",
+ pendingReq.isAuthenticated(), pendingReq.isNeedUserConsent());
+ if (pendingReq.isNeedUserConsent()) {
+ log.error(
+ "PendingRequest NEEDS user-consent. Can NOT fininalize authentication --> Abort authentication process!");
+
+ } else {
+ log.error("PendingRequest is NOT authenticated --> Abort authentication process!");
+
+ }
+
+ handleErrorNoRedirect(new EaafException("auth.20", null), req, resp, true);
+
+ }
+
+ } catch (final Exception e) {
+ log.error("Finalize authentication protocol FAILED.", e);
+ buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+
+ }
+
+ // remove pending-request
+ requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED,
+ pendingReq.getUniqueTransactionIdentifier());
+
+ }
+
+
+ @Override
+ public void buildProtocolSpecificErrorResponse(final Throwable throwable,
+ final HttpServletRequest req, final HttpServletResponse resp, final IRequest protocolRequest)
+ throws EaafException, IOException {
+ try {
+
+ final Class<?> clazz = Class.forName(protocolRequest.requestedModule());
+
+ if (clazz == null || !IModulInfo.class.isAssignableFrom(clazz)) {
+ log.error(
+ "Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+ throw new Exception(
+ "Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+
+ }
+
+ final IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
+
+ if (handlingModule.generateErrorMessage(throwable, req, resp, protocolRequest)) {
+
+ // log Error to technical log
+ logExceptionToTechnicalLog(throwable);
+
+ // log Error Message
+ statisticLogger.logErrorOperation(throwable, protocolRequest);
+
+ // write revision log entries
+ revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR,
+ protocolRequest.getUniqueTransactionIdentifier());
+
+ return;
+
+ } else {
+ handleErrorNoRedirect(throwable, req, resp, true);
+
+ }
+
+ } catch (final Throwable e) {
+ handleErrorNoRedirect(throwable, req, resp, true);
+
+ }
+
+ }
+
+ @Override
+ public void handleErrorNoRedirect(final Throwable throwable, final HttpServletRequest req,
+ final HttpServletResponse resp, final boolean writeExceptionToStatisticLog)
+ throws IOException, EaafException {
+
+ // log Exception into statistic database
+ if (writeExceptionToStatisticLog) {
+ statisticLogger.logErrorOperation(throwable);
+ }
+
+ // write errror to console
+ logExceptionToTechnicalLog(throwable);
+
+ // return error to Web browser
+ if (throwable instanceof EaafException || throwable instanceof ProcessExecutionException) {
+ internalMoaidExceptionHandler(req, resp, (Exception) throwable, false);
+ } else {
+ // write generic message for general exceptions
+ final String msg =
+ statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null);
+ writeHtmlErrorResponse(req, resp, msg, "9199", null, (Exception) throwable);
+
+ }
+
+ }
+
+
+ public void setGuiBuilder(final IGuiFormBuilder guiBuilder) {
+ this.guiBuilder = guiBuilder;
+ }
+
+ /**
+ * 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 In case of an error
+ */
+ protected void internalFinalizeAuthenticationProcess(final HttpServletRequest req,
+ final HttpServletResponse resp, final IRequest pendingReq) throws Exception {
+
+ String newSsoSessionId = null;
+
+ // if Single Sign-On functionality is enabled for this request
+ if (pendingReq.needSingleSignOnFunctionality()) {
+ if (ssoManager != null) {
+ newSsoSessionId = ssoManager.createNewSsoSessionCookie(req, resp, pendingReq);
+ if (StringUtils.isEmpty(pendingReq.getInternalSsoSessionIdentifier())) {
+ ssoManager.createNewSsoSession(pendingReq, newSsoSessionId);
+ }
+
+ } else {
+ log.warn("SSO is requested but there is not SSO Session-Manager available");
+ }
+
+ }
+
+ // build authenticationdata from session information and OA configuration
+ final IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);
+
+ // execute the protocol-specific action
+ final SloInformationInterface sloInformation =
+ executeProtocolSpecificAction(req, resp, pendingReq, authData);
+
+ // Store OA specific SSO session information if an SSO cookie is set
+ if (StringUtils.isNotEmpty(newSsoSessionId)) {
+ try {
+ ssoManager.updateSsoSession(pendingReq, newSsoSessionId, sloInformation);
+
+ } catch (final EaafSsoException e) {
+ log.warn("SSO Session information can not be stored -> SSO is not enabled!");
+ authmanager.performOnlyIdpLogOut(req, resp, pendingReq);
+
+ }
+
+ } else {
+ // remove MOASession from database
+ authmanager.performOnlyIdpLogOut(req, resp, pendingReq);
+
+ }
+
+ // Advanced statistic logging
+ statisticLogger.logSuccessOperation(pendingReq, authData,
+ StringUtils.isNotEmpty(newSsoSessionId));
+
+ }
+
+ /**
+ * Executes the requested protocol action.
+ *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param protocolRequest Authentication request which is actually in process
+ * @param authData Service-provider specific authentication data
+ *
+ * @return Return Single LogOut information or null if protocol supports no SSO
+ *
+ * @throws Exception in case of an error
+ */
+ private SloInformationInterface executeProtocolSpecificAction(final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp, final IRequest pendingReq, final IAuthData authData)
+ throws Exception {
+ try {
+ // request needs no authentication --> start request processing
+ final Class<?> clazz = Class.forName(pendingReq.requestedAction());
+ if (clazz == null || !IAction.class.isAssignableFrom(clazz)) {
+ log.error(
+ "Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+ throw new Exception(
+ "Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
+
+ }
+
+ final IAction protocolAction = (IAction) applicationContext.getBean(clazz);
+ return protocolAction.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ } catch (final ClassNotFoundException e) {
+ log.error(
+ "Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+ throw new Exception(
+ "Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.");
+ }
+
+ }
+
+ /**
+ * Write a Exception to the MOA-ID-Auth internal technical log.
+ *
+ * @param loggedException Exception to log
+ */
+ protected void logExceptionToTechnicalLog(final Throwable loggedException) {
+ if (!(loggedException instanceof EaafException
+ || loggedException instanceof ProcessExecutionException)) {
+ log.error("Receive an internal error: Message=" + loggedException.getMessage(),
+ loggedException);
+
+ } else {
+ if (loggedException instanceof EaafAuthenticationException && ERROR_LOGGER_ON_INFO_LEVEL
+ .contains(((EaafAuthenticationException) loggedException).getErrorId())) {
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.info(loggedException.getMessage(), loggedException);
+
+ } else {
+ log.info(loggedException.getMessage());
+
+ }
+
+ } else {
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.warn(loggedException.getMessage(), loggedException);
+
+ } else {
+ log.warn(loggedException.getMessage());
+
+ }
+ }
+ }
+ }
+
+ private void writeHtmlErrorResponse(@NonNull final HttpServletRequest httpReq,
+ @NonNull final HttpServletResponse httpResp, @NonNull final String msg,
+ @NonNull final String errorCode, @Nullable final Object[] params,
+ @NonNull final Exception error) throws IOException, EaafException {
+
+ try {
+ final IGuiBuilderConfiguration config =
+ guiConfigFactory.getDefaultErrorGui(HttpUtils.extractAuthUrlFromRequest(httpReq));
+
+
+ String[] errorCodeParams = null;
+ if (params == null) {
+ errorCodeParams = new String[] {};
+ } else {
+ errorCodeParams = new String[params.length];
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] != null) {
+ errorCodeParams[i] = params[i].toString();
+ } else {
+ errorCodeParams[i] = "null";
+ }
+
+ }
+ }
+
+
+
+ // add errorcode and errormessage
+ if (config instanceof ModifyableGuiBuilderConfiguration) {
+ ((ModifyableGuiBuilderConfiguration) config).putCustomParameter(
+ AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERROMSG, msg);
+ ((ModifyableGuiBuilderConfiguration) config).putCustomParameter(
+ AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERRORCODE, errorCode);
+ ((ModifyableGuiBuilderConfiguration) config).putCustomParameterWithOutEscaption(
+ AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERRORCODEPARAMS,
+ ArrayUtils.toString(errorCodeParams));
+
+ // add stacktrace if debug is enabled
+ if (log.isTraceEnabled()) {
+ ((ModifyableGuiBuilderConfiguration) config).putCustomParameter(
+ AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERRORSTACKTRACE,
+ getStacktraceFromException(error));
+
+ }
+
+ } else {
+ log.info(
+ "Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
+ }
+
+
+
+ guiBuilder.build(httpReq, httpResp, config, "Error-Message");
+
+ } catch (final GuiBuildException e) {
+ log.warn("Can not build error-message GUI.", e);
+ throw new EaafException("9199", null, e);
+
+
+ }
+
+ }
+
+ private String getStacktraceFromException(final Exception ex) {
+ final StringWriter errors = new StringWriter();
+ ex.printStackTrace(new PrintWriter(errors));
+ return errors.toString();
+
+ }
+
+ private void internalMoaidExceptionHandler(final HttpServletRequest req,
+ final HttpServletResponse resp, final Exception e, final boolean writeExceptionToStatisicLog)
+ throws IOException, EaafException {
+ if (e instanceof ProtocolNotActiveException) {
+ resp.getWriter().write(e.getMessage());
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN,
+ StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
+
+ } else if (e instanceof AuthnRequestValidatorException) {
+ final AuthnRequestValidatorException ex = (AuthnRequestValidatorException) e;
+ // log Error Message
+ if (writeExceptionToStatisicLog) {
+ statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
+ }
+
+ // write error message
+ // writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+ writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
+ null, e);
+
+ } else if (e instanceof InvalidProtocolRequestException) {
+ // send error response
+ // writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+ writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
+ null, e);
+
+ } else if (e instanceof ConfigurationException) {
+ // send HTML formated error message
+ writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
+ null, e);
+
+ } else if (e instanceof EaafException) {
+ // send HTML formated error message
+ writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
+ ((EaafException) e).getParams(), e);
+
+ } else if (e instanceof ProcessExecutionException) {
+ // send HTML formated error message
+ writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
+ null, e);
+
+ }
+
+ }
+
+
}