summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java/at/gv
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core/src/main/java/at/gv')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java2
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGuiFormBuilderConfiguration.java11
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java84
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java37
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/RequestStorage.java15
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java95
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java391
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java28
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/EidAuthProcessDataWrapper.java34
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/IdentityLink.java29
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java48
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/ModuleRegistration.java2
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java111
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java164
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java441
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/AttributeBuilderRegistration.java88
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java10
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BpkAttributeBuilder.java37
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidCcsUrl.java3
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIdentityStatusLevelAttributeBuiler.java10
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIssuingNationAttributeBuilder.java2
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSectorForIdAttributeBuilder.java4
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSignerCertificate.java7
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PiiTransactionIdAttributeBuilder.java37
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateModeAttributeBuilder.java (renamed from eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpUsesMandates.java)6
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateProfilesAttributeBuilder.java51
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/TransactionIdAttributeBuilder.java33
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java58
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java6
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java181
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/AbstractLocaleAuthServletTask.java25
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java30
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java1
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java26
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java2
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DomUtils.java7
36 files changed, 1250 insertions, 866 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java
index b3e0c88f..08c48435 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java
@@ -3,8 +3,6 @@ package at.gv.egiz.eaaf.core.api.utils;
import java.io.IOException;
import java.io.InputStream;
-import com.google.gson.JsonParseException;
-
import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException;
public interface IJsonMapper {
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGuiFormBuilderConfiguration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGuiFormBuilderConfiguration.java
index b0718f85..f8e64c1a 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGuiFormBuilderConfiguration.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/gui/AbstractGuiFormBuilderConfiguration.java
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.eaaf.core.api.gui.GroupDefinition;
import at.gv.egiz.eaaf.core.api.gui.GroupDefinition.Type;
import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfiguration;
+import lombok.Setter;
/**
* Abstract Configuration implementation for GUI Builders.
@@ -63,6 +64,9 @@ public abstract class AbstractGuiFormBuilderConfiguration implements IGuiBuilder
private String authUrl = null;
private String viewName = null;
private String formSubmitEndpoint = null;
+
+ @Setter
+ private boolean writeAsynch = true;
private final Map<String, Object> params = new HashMap<>();
@@ -137,6 +141,13 @@ public abstract class AbstractGuiFormBuilderConfiguration implements IGuiBuilder
}
+
+ @Override
+ public final boolean isWriteAsynch() {
+ return this.writeAsynch;
+
+ }
+
/**
* Define the parameters, which should be evaluated in the template. <br>
* <b>IMPORTANT:</b> external HTML escapetion is required, because it is NOT
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
index 677e3c46..4fe22feb 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/AuthenticationData.java
@@ -26,16 +26,18 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
-import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BpkBuilder;
+import at.gv.egiz.eaaf.core.impl.builder.BpkBuilder;
+import lombok.extern.slf4j.Slf4j;
/**
* Service-Provider specific authentication data.
@@ -43,12 +45,12 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BpkBuilder;
* @author tlenz
*
*/
+@Slf4j
public class AuthenticationData implements IAuthData, Serializable {
- private static final Logger log = LoggerFactory.getLogger(AuthenticationData.class);
-
private static final long serialVersionUID = -1042697056735596866L;
public static final String IDENTITY_LINK_DATE_FORMAT = "yyyy-MM-dd";
+ public static final String IDENTITY_LINK_DATE_REGEX = "([0-9]{4})-([0-9]{2})-([0-9]{2})";
public static final String ISSUE_INSTANT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private boolean isBaseIdTransferRestrication = true;
@@ -66,7 +68,7 @@ public class AuthenticationData implements IAuthData, Serializable {
private String familyName;
private String givenName;
- private Date dateOfBirth;
+ private String dateOfBirth;
private String encSourceId;
private String encSourceIdType;
@@ -135,7 +137,6 @@ public class AuthenticationData implements IAuthData, Serializable {
}
@Override
- @Deprecated
public String getBpk() {
return bpk;
}
@@ -145,28 +146,41 @@ public class AuthenticationData implements IAuthData, Serializable {
*
* @param bpk The bPK to set
*/
- @Deprecated
public void setBpk(final String bpk) {
this.bpk = bpk;
}
@Override
- public Date getDateOfBirth() {
- return getDateCopyOrNull(this.dateOfBirth);
+ public String getDateOfBirth() {
+ return this.dateOfBirth;
}
@Override
- public String getFormatedDateOfBirth() {
- final DateFormat pvpDateFormat = new SimpleDateFormat(IDENTITY_LINK_DATE_FORMAT);
- if (getDateOfBirth() != null) {
- return pvpDateFormat.format(getDateOfBirth());
- } else {
- return "2999-12-31";
- }
-
+ public String getDateOfBirthFormated(String pattern) {
+ if (StringUtils.isNotEmpty(getDateOfBirth())) {
+ try {
+ final DateFormat dateFormat = new SimpleDateFormat(IDENTITY_LINK_DATE_FORMAT);
+ Date parsedDate = dateFormat.parse(getDateOfBirth());
+ final String dateString = dateFormat.format(parsedDate);
+ if (getDateOfBirth().equals(dateString)) {
+ final DateFormat destDateFormat = new SimpleDateFormat(pattern);
+ return destDateFormat.format(parsedDate);
+
+ } else {
+ log.info("DateOfBirth has an unusal format. Can not be converted to: {}", pattern);
+
+ }
+
+ } catch (ParseException | IllegalArgumentException e) {
+ log.error("Can not parse DateOfBirth.", e);
+
+ }
+ }
+ return null;
+
}
-
+
@Override
public String getFamilyName() {
return this.familyName;
@@ -220,26 +234,16 @@ public class AuthenticationData implements IAuthData, Serializable {
*
* @param dateOfBirth The dateOfBirth to set
*/
- public void setDateOfBirth(final Date dateOfBirth) {
- this.dateOfBirth = getDateCopyOrNull(dateOfBirth);
- }
-
- /**
- * Set the date of birth.
- *
- * @param dateOfBirth date of birth String as "yyyy-MM-dd"
- */
- public void setDateOfBirth(final String dateOfBirth) {
- try {
- if (StringUtils.isNotEmpty(dateOfBirth)) {
- final DateFormat identityLinkFormat = new SimpleDateFormat(IDENTITY_LINK_DATE_FORMAT);
- this.dateOfBirth = identityLinkFormat.parse(dateOfBirth);
-
+ public void setDateOfBirth(@Nullable final String dateOfBirth) {
+ if (dateOfBirth != null) {
+ if (Pattern.matches(IDENTITY_LINK_DATE_REGEX, dateOfBirth)) {
+ this.dateOfBirth = dateOfBirth;
+
+ } else {
+ log.error("DateOfBirth: {} does NOT match to pattern: {}",
+ dateOfBirth, IDENTITY_LINK_DATE_REGEX);
+
}
-
- } catch (final ParseException e) {
- log.warn("Parse dateOfBirht from IdentityLink FAILED", e);
-
}
}
@@ -282,7 +286,6 @@ public class AuthenticationData implements IAuthData, Serializable {
}
@Override
- @Deprecated
public String getBpkType() {
return bpkType;
}
@@ -292,10 +295,9 @@ public class AuthenticationData implements IAuthData, Serializable {
*
* @param bpkType bPK type
*/
- @Deprecated
public void setBpkType(final String bpkType) {
this.bpkType = BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(bpkType);
-
+
}
@Override
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 d2365e4a..89977308 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
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import javax.annotation.PostConstruct;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -34,6 +35,7 @@ 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 at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
@@ -66,6 +68,9 @@ public abstract class AbstractAuthenticationManager implements IAuthenticationMa
public static final int SLOTIMEOUT = 30 * 1000; // 30 sec
+ @Autowired
+ private ApplicationContext ctx;
+
@Autowired(required = true)
protected IConfiguration authConfig;
@Autowired(required = true)
@@ -76,31 +81,35 @@ public abstract class AbstractAuthenticationManager implements IAuthenticationMa
protected IRevisionLogger revisionsLogger;
@Autowired(required = false)
protected ISsoManager ssoManager;
- @Autowired
+
ModuleRegistration moduleRegistration;
- /*
- * (non-Javadoc)
+ @PostConstruct
+ private void initializer() {
+ moduleRegistration = ctx.getBean(ModuleRegistration.class);
+
+ }
+
+ /**
+ * Add a request parameter to whitelist. All parameters that are part of the
+ * white list are added into {@link ExecutionContext}
*
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#
- * addParameterNameToWhiteList(java.lang .String)
+ * @param httpReqParam http parameter name, but never null
*/
- @Override
- public final void addParameterNameToWhiteList(final String httpReqParam) {
+ public static final void addParameterNameToWhiteList(final String httpReqParam) {
if (StringUtils.isNotEmpty(httpReqParam)) {
reqParameterWhiteListeForModules.add(httpReqParam);
}
}
- /*
- * (non-Javadoc)
+ /**
+ * Add a request header to whitelist. All parameters that are part of the white
+ * list are added into {@link ExecutionContext}
*
- * @see at.gv.egiz.eaaf.core.impl.idp.auth.IAuthenticationManager#
- * addHeaderNameToWhiteList(java.lang. String)
+ * @param httpReqParam http header name, but never null
*/
- @Override
- public final void addHeaderNameToWhiteList(final String httpReqParam) {
+ public static final void addHeaderNameToWhiteList(final String httpReqParam) {
if (StringUtils.isNotEmpty(httpReqParam)) {
reqHeaderWhiteListeForModules.add(httpReqParam.toLowerCase());
}
@@ -348,7 +357,7 @@ public abstract class AbstractAuthenticationManager implements IAuthenticationMa
if (processDefinitionId == null) {
log.warn("No suitable process found for PendingReqId " + pendingReq.getPendingRequestId());
- throw new EaafException("process.02", new Object[] { pendingReq.getPendingRequestId() });
+ throw new EaafException("process.02", null);
}
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 0834aa7c..db13bf71 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
@@ -69,10 +69,21 @@ public class RequestStorage implements IRequestStorage {
// search invalid pending-request for errorHandling
IRequest invalidPendingRequest = null;
- try {
+ try {
if (StringUtils.isNotEmpty(e.getInvalidInternalPendingReqId())) {
+ log.debug("Searching for expired pendingRequest with Id: {} ... ", e.getInvalidInternalPendingReqId());
invalidPendingRequest =
transactionStorage.get(e.getInvalidInternalPendingReqId(), IRequest.class);
+
+ // If pendingReq. was found, set transactionID and sessionID to Logger
+ TransactionIdUtils.setAllLoggingVariables(invalidPendingRequest);
+
+ log.debug("{} expired pendingReq. Set it into Exception ...",
+ invalidPendingRequest != null ? "Find" : "Find NO ");
+
+ } else {
+ log.debug("Get no internal pendingRequestId. Expired pendingRequest can not be set");
+
}
} catch (final EaafException e1) {
@@ -213,7 +224,7 @@ public class RequestStorage implements IRequestStorage {
throws EaafException {
final IRequest pendingRequest = transactionStorage.get(internalPendingReqId, IRequest.class);
if (pendingRequest == null) {
- log.info("No PendingRequst found with pendingRequestID " + internalPendingReqId);
+ log.debug("No PendingRequst found with pendingRequestID " + internalPendingReqId);
return null;
}
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 c2f85fef..142dcf28 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
@@ -22,9 +22,9 @@ package at.gv.egiz.eaaf.core.impl.idp.auth.builder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Map.Entry;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -54,6 +54,7 @@ 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.builder.BpkBuilder;
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;
@@ -72,9 +73,13 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
public static final String CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING =
"configuration.bugfix.enable.idl.escaping";
- protected Collection<String> includedToGenericAuthData = null;
+ private static final String GENERIC_ATTR_CONTAINER = "processAuthParam;";
+
@Autowired
protected IConfigurationWithSP basicConfig;
+
+ //protected ThreadLocal<Set<String>> includedToGenericAuthData = null;
+
@Override
public IAuthData buildAuthenticationData(final IRequest pendingReq)
@@ -137,7 +142,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
*/
protected abstract void buildServiceSpecificAuthenticationData(IAuthData authData,
IRequest pendingReq) throws EaafException;
-
+
/**
* Add generic E-ID information into already existing AuthData.
*
@@ -169,7 +174,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
// includedToGenericAuthData =
// authProcessData.getGenericSessionDataStorage().keySet();
// else
- includedToGenericAuthData = new ArrayList<>();
+ initializeThreadLocalVariable(authProcessData, new HashSet<>());
// ####################################################
// set general authData info's
@@ -204,24 +209,51 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
setCitizenCountryCode(internalAuthData, authProcessData);
// 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);
+ authProcessData.getGenericSessionDataStream()
+ .filter(el -> el.getKey().startsWith(GENERIC_AUTHDATA_IDENTIFIER))
+ .forEach(el -> {
+ 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);
- }
+ }
+ });
+ }
+ /**
+ * Initialize Thread-Local holder for generic attributes set in authenticated session.
+ *
+ * @param authProcessData Current authentication data holder
+ * @param data {@link Collection} of generic attribute-names
+ * @throws EaafAuthenticationException In case of an error
+ */
+ protected void initializeThreadLocalVariable(@NonNull final IAuthProcessDataContainer authProcessData,
+ Set<String> data)
+ throws EaafAuthenticationException {
+ try {
+ authProcessData.setGenericDataToSession(GENERIC_ATTR_CONTAINER, data);
+
+ } catch (EaafStorageException e) {
+ throw new EaafAuthenticationException("builder.11", new Object[] { e.getMessage() }, e);
+
}
-
+
}
-
+
+ /**
+ * Initialize Thread-Local holder for generic attributes set in authenticated session.
+ *
+ * @param set {@link Collection} of generic attribute-names
+ */
+ @SuppressWarnings("unchecked")
+ protected Set<String> getThreadLocalVariable(@NonNull final IAuthProcessDataContainer authProcessData) {
+ return authProcessData.getGenericDataFromSession(GENERIC_ATTR_CONTAINER, Set.class);
+
+ }
+
/**
* Parse citzen country-code into AuthData.
*
@@ -232,7 +264,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
*/
private void setCitizenCountryCode(final AuthenticationData authData,
final IAuthProcessDataContainer authProcessData) throws EaafAuthenticationException {
- includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME);
final String pvpCccAttr = authProcessData
.getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
if (StringUtils.isNotEmpty(pvpCccAttr)) {
@@ -265,7 +297,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
*/
private void setQaaLevel(@NonNull final AuthenticationData authData,
@NonNull final IAuthProcessDataContainer authProcessData) {
- includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
String currentLoA = null;
if (StringUtils.isNotEmpty(authProcessData.getQaaLevel())) {
currentLoA = authProcessData.getQaaLevel();
@@ -331,9 +363,10 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
if (authProcessData.getGenericSessionDataStorage() != null
&& !authProcessData.getGenericSessionDataStorage().isEmpty()) {
- includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet();
+ initializeThreadLocalVariable(authProcessData,
+ authProcessData.getGenericSessionDataStorage().keySet());
} else {
- includedToGenericAuthData = new ArrayList<>();
+ initializeThreadLocalVariable(authProcessData, new HashSet<>());
}
// ####################################################
@@ -348,7 +381,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
IIdentityLink idlFromPvpAttr = null;
final IIdentityLink identityLink = authProcessData.getIdentityLink();
if (identityLink != null) {
- parseBasicUserInfosFromIdl(authData, identityLink, includedToGenericAuthData);
+ parseBasicUserInfosFromIdl(authData, identityLink, getThreadLocalVariable(authProcessData));
} else {
// identityLink is not direct in MOASession
@@ -362,7 +395,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
try {
idlStream = new ByteArrayInputStream(Base64Utils.decodeFromString(pvpAttrIdl));
idlFromPvpAttr = new SimpleIdentityLinkAssertionParser(idlStream).parseIdentityLink();
- parseBasicUserInfosFromIdl(authData, idlFromPvpAttr, includedToGenericAuthData);
+ parseBasicUserInfosFromIdl(authData, idlFromPvpAttr, getThreadLocalVariable(authProcessData));
// set identitylink into AuthProcessData
authProcessData.setIdentityLink(idlFromPvpAttr);
@@ -375,7 +408,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
} finally {
try {
- includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_IDENTITY_LINK_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.EID_IDENTITY_LINK_NAME);
if (idlStream != null) {
idlStream.close();
}
@@ -403,11 +436,11 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
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);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.GIVEN_NAME_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.BIRTHDATE_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.EID_SOURCE_PIN_NAME);
+ getThreadLocalVariable(authProcessData).remove(PvpAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME);
}
}
@@ -625,7 +658,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati
*/
@Deprecated
private void parseBasicUserInfosFromIdl(final AuthenticationData authData,
- final IIdentityLink identityLink, final Collection<String> includedGenericSessionData) {
+ final IIdentityLink identityLink, final Set<String> includedGenericSessionData) {
authData.setIdentificationValue(identityLink.getIdentificationValue());
authData.setIdentificationType(identityLink.getIdentificationType());
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 fed4af32..00000000
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between
- * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European
- * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
- * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the Licence
- * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the Licence for the specific language governing permissions and limitations under
- * the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text file for details on the
- * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
- * works that you distribute must include a readable copy of the "NOTICE" text file.
-*/
-
-package at.gv.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 java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
-import org.apache.commons.lang3.StringUtils;
-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;
-import lombok.extern.slf4j.Slf4j;
-
-
-/**
- * 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>.
- *
- */
-@Slf4j
-public class BpkBuilder {
-
- private static final String ERROR_MSG_WRONG_TARGET_FORMAT = "bPK-target format must be full URI";
-
- /**
- * 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)) {
- log.trace("Calculate bPK identifier for target: " + targetIdentifier);
- return Pair.newInstance(calculatebPKwbPK(baseID + "+" + targetIdentifier),
- targetIdentifier);
-
- } else if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
- log.trace("Calculate wbPK identifier for target: " + targetIdentifier);
- return Pair.newInstance(calculatebPKwbPK(
- baseID + "+" + normalizeBpkTargetIdentifierToCalculationFormat(targetIdentifier)),
- normalizeBpkTargetIdentifierToCommonFormat(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");
-
- }
- }
- }
-
-
-
- /**
- * Create an encrypted bPK.
- *
- * @param bpk unencrypted bPK
- * @param target bPK target in full form
- * @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_WITH_COLON)) {
- throw new EaafBuilderException("builder.32",
- null, ERROR_MSG_WRONG_TARGET_FORMAT);
-
- }
-
- target = normalizeBpkTargetIdentifierToCalculationFormat(target);
-
- final String input =
- "V1::" + 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 in full form
- * @param privateKey private-key for decryption
- * @return bPK Pair consists of (unique person identifier for this target,
- * targetArea) but never null
- * @throws EaafBuilderException In case of an error
- */
- public static Pair<String, String> decryptBpk(final String encryptedBpk, String target,
- final PrivateKey privateKey) throws EaafBuilderException {
- String decryptedString;
-
- if (!target.startsWith(EaafConstants.URN_PREFIX_WITH_COLON)) {
- throw new EaafBuilderException("builder.32",
- null, ERROR_MSG_WRONG_TARGET_FORMAT);
-
- }
-
- try {
- 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[] parts = decryptedString.split("::");
- if (parts.length != 4) {
- log.trace("Encrypted bPK has value: {}", decryptedString);
- throw new EaafBuilderException("builder.31", new Object[] {parts.length},
- "encBpk has a suspect format");
-
- }
-
- final String sector = parts[1];
- final String bPK = parts[2];
-
- if (target.equals(normalizeBpkTargetIdentifierToCommonFormat(sector))) {
- return Pair.newInstance(bPK, target);
-
- } else {
- throw new EaafBuilderException("builder.30", new Object[] {sector, target},
- "Decrypted bPK-target does not match");
-
- }
- }
-
- /**
- * Normalize wbPK target identifier for FN, ZVR, and ERSB to XFN, XZVR, and XERSB.
- *
- * <p>If the target is not of this types the target will be returned as it is</p>
- * @param targetIdentifier bPK input target
- * @return XFN, XZVR, XERSB, or targetIdentfier if no normalization is required
- */
- @Nullable
- public static String normalizeBpkTargetIdentifierToCommonFormat(@Nullable String targetIdentifier) {
- if (targetIdentifier != null
- && !targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X)) {
- for (Entry<String, String> mapper : EaafConstants.URN_WBPK_TARGET_X_TO_NONE_MAPPER.entrySet()) {
- if (targetIdentifier.startsWith(mapper.getValue())) {
- String wbpkTarget = mapper.getKey() + targetIdentifier.substring(mapper.getValue().length());
- log.trace("Normalize wbPK target: {} to {}", targetIdentifier, wbpkTarget);
- return wbpkTarget;
-
- }
- }
- }
-
- return targetIdentifier;
- }
-
- /**
- * Normalize wbPK target identifier for XFN, XZVR, and XERSB to bPK calculation format like, FN, ZVR, and ERSB.
- *
- * <p>If the target is not of this types the target will be returned as it is</p>
- *
- * @param targetIdentifier bPK input target
- * @return FN, ZVR, ERSB, or targetIdentfier if no normalization is required
- */
- @Nullable
- public static String normalizeBpkTargetIdentifierToCalculationFormat(@Nullable String targetIdentifier) {
- if (targetIdentifier != null && targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
- for (Entry<String, String> mapper : EaafConstants.URN_WBPK_TARGET_X_TO_NONE_MAPPER.entrySet()) {
- if (targetIdentifier.startsWith(mapper.getKey())) {
- String wbpkTarget = mapper.getValue() + targetIdentifier.substring(mapper.getKey().length());
- log.trace("Find new wbPK target: {}. Replace it by: {}", targetIdentifier, wbpkTarget);
- return wbpkTarget;
-
- }
- }
- }
-
- return targetIdentifier;
- }
-
- /**
- * 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);
- }
-
- 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 8eef4a8e..368652be 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
@@ -22,9 +22,11 @@ package at.gv.egiz.eaaf.core.impl.idp.auth.data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.TimeZone;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -264,16 +266,20 @@ public class AuthProcessDataWrapper
* 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;
+ public Map<String, Object> getGenericSessionDataStorage() {
+ return authProcessData.entrySet().stream()
+ .filter(el -> el.getKey().startsWith(GENERIC_PREFIX))
+ .collect(
+ Collectors.toMap(
+ el -> el.getKey().substring(GENERIC_PREFIX.length()),
+ value -> value.getValue()));
+
+ }
+
+ @Override
+ public Stream<Entry<String, Object>> getGenericSessionDataStream() {
+ return getGenericSessionDataStorage().entrySet().stream();
+
}
/*
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/EidAuthProcessDataWrapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/EidAuthProcessDataWrapper.java
new file mode 100644
index 00000000..48a2206b
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/EidAuthProcessDataWrapper.java
@@ -0,0 +1,34 @@
+package at.gv.egiz.eaaf.core.impl.idp.auth.data;
+
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IEidAuthProcessData;
+
+/**
+ * Authentication session-data that adds ID Austria specific information.
+ *
+ * @author tlenz
+ *
+ */
+public class EidAuthProcessDataWrapper extends AuthProcessDataWrapper implements IEidAuthProcessData {
+
+ private static final String VALUE_INTERNAL_TEST_IDENTITY_PROCESS = "direct_is_testidentity";
+
+ public EidAuthProcessDataWrapper(Map<String, Object> authProcessData) {
+ super(authProcessData);
+
+ }
+
+ @Override
+ public boolean isTestIdentity() {
+ return wrapStoredObject(VALUE_INTERNAL_TEST_IDENTITY_PROCESS, false, Boolean.class);
+
+ }
+
+ @Override
+ public void setTestIdentity(boolean flag) {
+ authProcessData.put(VALUE_INTERNAL_TEST_IDENTITY_PROCESS, flag);
+
+ }
+
+}
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 ee1037a1..8327b544 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
@@ -23,15 +23,20 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.PublicKey;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
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.XPathUtils;
+import org.w3c.dom.Element;
+
+import lombok.extern.slf4j.Slf4j;
+
/**
* Data contained in an identity link issued by BMI, relevant to the MOA ID
* component. <br>
@@ -41,10 +46,13 @@ import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
* @author Paul Ivancsics
* @version $Id$
*/
+@Slf4j
public class IdentityLink implements Serializable, IIdentityLink {
private static final long serialVersionUID = 1L;
+ public static final String PATTERN_ISSUE_INSTANT = "yyyy-MM-dd'T'HH:mm:ssXXX";
+
/**
* <code>"identificationValue"</code> is the translation of
* <code>"Stammzahl"</code>.
@@ -372,6 +380,23 @@ public class IdentityLink implements Serializable, IIdentityLink {
return issueInstant;
}
+ @Override
+ public Date getIssueInstantDate() {
+ final SimpleDateFormat f = new SimpleDateFormat(PATTERN_ISSUE_INSTANT);
+ try {
+ if (issueInstant != null) {
+ return f.parse(issueInstant);
+
+ }
+
+ } catch (final ParseException e) {
+ log.error("Can NOT parse Date from String: {}", issueInstant, null, e);
+
+ }
+
+ return null;
+ }
+
/*
* (non-Javadoc)
*
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 3d093a9f..5b5d0aa8 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
@@ -45,6 +45,7 @@ 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;
+import at.gv.egiz.eaaf.core.api.data.EaafEventCodes;
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;
@@ -155,6 +156,36 @@ public abstract class AbstractAuthServletTask extends AbstractTask {
}
/**
+ * Stopping the current authentication process by User decision.
+ *
+ * @param executionContext Current execution context
+ * @param request Http request
+ * @param response Http response
+ * @throws TaskExecutionException In case of an error during process-stopping
+ */
+ protected void stopProcessFromUserDecision(final ExecutionContext executionContext,
+ final HttpServletRequest request, final HttpServletResponse response)
+ throws TaskExecutionException {
+ try {
+ revisionsLogger.logEvent(pendingReq, EaafEventCodes.PROCESS_STOPPED_BY_USER);
+ pendingReq.setAbortedByUser(true);
+ pendingReq.setAuthenticated(false);
+ performRedirectToProtocolFinialization(executionContext, pendingReq, request, response);
+
+ log.trace("Set process-cancelation flag");
+ executionContext.setCanceleProcessFlag();
+
+ } catch (final EaafException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (final Exception e) {
+ log.warn("Stopping auth.process FAILED", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+ /**
* Parses the request input stream for parameters, assuming parameters are
* encoded UTF-8 (no standard exists how browsers should encode them).
*
@@ -268,4 +299,21 @@ public abstract class AbstractAuthServletTask extends AbstractTask {
return url + "&" + param;
}
}
+
+ /**
+ * Get a {@link Boolean} parameter from http request.
+ *
+ * @param httpReq http Request object
+ * @param paramName http Parameter name
+ * @return <code>true</code> if the parameter exists and the <code>Boolean.parseBoolean(value)</code>
+ * evaluates to <code>true</code>, otherwise <code>false</code>
+ */
+ protected boolean evaluteBooleanReqParam(final HttpServletRequest httpReq, final String paramName) {
+ final String value = httpReq.getParameter(paramName);
+ if (value != null) {
+ return Boolean.parseBoolean(value);
+ } else {
+ return false;
+ }
+ }
}
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 c4f1b505..c1593cb1 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
@@ -100,7 +100,7 @@ public class ModuleRegistration {
*/
private void initSpringModules() {
log.debug("Discovering Spring modules.");
- final Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);
+ final Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);
for (final AuthModule module : modules.values()) {
registerModuleProcessDefinitions(module);
priorizedModules.add(module);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java
new file mode 100644
index 00000000..e41905a6
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java
@@ -0,0 +1,111 @@
+package at.gv.egiz.eaaf.core.impl.idp.auth.services;
+
+import java.text.MessageFormat;
+import java.util.HashSet;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class DefaultErrorService implements IErrorService {
+ private static final String TECH_LOG_MSG = "errorCode={0} Message={1}";
+ private static final String CONFIG_PROP_LOGGER_ON_INFO_LEVEL = "core.logging.level.info.errorcodes";
+
+ @Autowired IConfiguration basicConfig;
+ @Autowired IStatusMessenger statusMessager;
+
+ private final HashSet<String> logOnInfoLevel = new HashSet<>();
+
+ @Override
+ public String getExternalCodeFromInternal(String internalCode) {
+ return statusMessager.mapInternalErrorToExternalError(internalCode);
+
+ }
+
+ @Override
+ public IHandleData createHandleData(Throwable throwable, boolean supportRedirctToSp) throws EaafException {
+ String internalErrorId = extractInternalErrorCode(throwable);
+
+ return HandleData.builder()
+ .throwable(throwable)
+ .internalErrorCode(internalErrorId)
+ .actionType(ActionType.NO_TICKET)
+ .logLevel(logOnInfoLevel.contains(internalErrorId) ? LogLevel.INFO : LogLevel.WARN)
+ .build();
+
+ }
+
+ @Override
+ public void displayErrorData(ModifyableGuiBuilderConfiguration c, IHandleData errorData,
+ HttpServletRequest httpReq) throws EaafException {
+ log.trace("Do nothing because Tickets are not supported by: {}", DefaultErrorService.class.getName());
+
+ }
+
+ private String extractInternalErrorCode(Throwable throwable) {
+ Throwable originalException;
+ if (throwable instanceof TaskExecutionException
+ && ((TaskExecutionException) throwable).getOriginalException() != null) {
+ originalException = ((TaskExecutionException) throwable).getOriginalException();
+
+ } else {
+ originalException = throwable;
+
+ }
+
+ if (!(originalException instanceof EaafException)) {
+ return IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC;
+
+ } else {
+ return ((EaafException) originalException).getErrorId();
+
+ }
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafException {
+ log.info("initErrorTicketService");
+
+ logOnInfoLevel.addAll(KeyValueUtils.getListOfCsvValues(
+ basicConfig.getBasicConfiguration(CONFIG_PROP_LOGGER_ON_INFO_LEVEL)));
+ log.info("Set errorCodes={} to LogLevel:INFO", String.join(",", logOnInfoLevel));
+
+ }
+
+ @Builder
+ static class HandleData implements IHandleData {
+
+ @Getter
+ private String errorIdTokenForRedirect;
+
+ @Getter
+ private final Throwable throwable;
+
+ @Getter
+ private String internalErrorCode;
+
+ @Getter
+ private ActionType actionType;
+
+ @Getter
+ private LogLevel logLevel;
+
+ public String getPreFormatedErrorMessage() {
+ return MessageFormat.format(TECH_LOG_MSG, internalErrorCode, throwable.getMessage());
+
+ }
+
+ }
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java
new file mode 100644
index 00000000..b6bc1056
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java
@@ -0,0 +1,164 @@
+package at.gv.egiz.eaaf.core.impl.idp.auth.services;
+
+import javax.annotation.Nonnull;
+import javax.servlet.http.HttpServletRequest;
+
+import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+
+public interface IErrorService {
+
+ /**
+ * Describes the kind of action that should be taken.
+ */
+ enum ActionType {
+ TICKET("ticket"), NO_TICKET("no_ticket"), ERRORPAGE("errorpage");
+
+ private final String name;
+
+ ActionType(final String text) {
+ this.name = text;
+ }
+
+
+ /**
+ * Get flow type for error-handling from String representation.
+ *
+ * @param s Config parameter
+ * @return Error-handling flow
+ */
+ public static ActionType fromString(final String s) {
+ try {
+ return ActionType.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return null;
+
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * Defines the LogLevel for this types of errors.
+ */
+ enum LogLevel {
+ ERROR("error"), WARN("warn"), INFO("info"), DEBUG("debug");
+
+ private final String level;
+
+ LogLevel(final String logLevel) {
+ this.level = logLevel;
+
+ }
+
+
+ /**
+ * Get the log-level from String representation.
+ *
+ * @param s Config parameter
+ * @return Log-Level from configuration or ERROR as backup
+ */
+ public static LogLevel fromString(final String s) {
+ try {
+ return LogLevel.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return LogLevel.ERROR;
+
+ }
+ }
+
+ @Override
+ public String toString() {
+ return level;
+ }
+
+ }
+
+ String PARAM_GUI_TICKET = "supportTicket";
+ String PARAM_GUI_REDIRECT = "redirectLink";
+
+ /**
+ * Maps internal error codes to external ones.
+ * @param internalCode internal error code
+ * @return external error code
+ */
+ @Nonnull
+ String getExternalCodeFromInternal(@Nonnull String internalCode);
+
+ /**
+ * Creates error handling data.
+ *
+ * @param throwable Error that should be handled
+ * @param supportRedirctToSp <code>true</code> if the current process-state supports redirect
+ * to Service-Provider, otherwise <code>false</code>
+ * @return Information how the error should be handled
+ * @throws EaafException In case of an internal error
+ */
+ @Nonnull
+ IHandleData createHandleData(@Nonnull Throwable throwable, boolean supportRedirctToSp) throws EaafException;
+
+ /**
+ * Displays the error using suitable errordata.
+ *
+ * @param c guibuilder
+ * @param errorData Data to handle
+ * @param httpReq Current HTTP request
+ * @throws EaafException In case of an internal error
+ */
+ void displayErrorData(@Nonnull ModifyableGuiBuilderConfiguration c, @Nonnull IErrorService.IHandleData errorData,
+ @Nonnull HttpServletRequest httpReq) throws EaafException;
+
+ /**
+ * Contains all the Model data for Error Handling.
+ */
+ interface IHandleData {
+
+ /**
+ * Get a new pendingReqId that can be used to store the error for SP forwarding.
+ *
+ * @return errorToken as pendingRequest
+ */
+ String getErrorIdTokenForRedirect();
+
+ /**
+ * Describes the kind of action that should be taken.
+ *
+ * @return The appropriate action
+ */
+ ActionType getActionType();
+
+ /**
+ * Get internal errorCode describing the problem.
+ *
+ * @return internal error Code.
+ */
+ String getInternalErrorCode();
+
+ /**
+ * Get the original throwable of the error.
+ *
+ * @return causing throwable
+ */
+ Throwable getThrowable();
+
+ /**
+ * Get the log-level for this internal errorId.
+ *
+ * @return Level to Log the error
+ */
+ LogLevel getLogLevel();
+
+ /**
+ * Get pre-formated text for log message.
+ *
+ * @return log message
+ */
+ String getPreFormatedErrorMessage();
+ }
+}
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 5f84d118..ca2c92b1 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
@@ -15,16 +15,13 @@
* This product combines work with different licenses. See the "NOTICE" text file for details on the
* various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
* works that you distribute must include a readable copy of the "NOTICE" text file.
-*/
+ */
package at.gv.egiz.eaaf.core.impl.idp.auth.services;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
+import javax.annotation.PostConstruct;
import javax.naming.ConfigurationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -32,6 +29,7 @@ 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.owasp.encoder.Encode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,12 +37,14 @@ import org.springframework.context.ApplicationContext;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
+import org.springframework.util.SerializationUtils;
import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfiguration;
import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfigurationFactory;
import at.gv.egiz.eaaf.core.api.gui.IGuiFormBuilder;
@@ -60,6 +60,7 @@ import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService
import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
@@ -72,6 +73,9 @@ import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
import at.gv.egiz.eaaf.core.impl.data.Pair;
import at.gv.egiz.eaaf.core.impl.gui.AbstractGuiFormBuilderConfiguration;
import at.gv.egiz.eaaf.core.impl.http.HttpUtils;
+import at.gv.egiz.eaaf.core.impl.idp.auth.services.IErrorService.ActionType;
+import at.gv.egiz.eaaf.core.impl.idp.auth.services.IErrorService.IHandleData;
+import at.gv.egiz.eaaf.core.impl.idp.auth.services.IErrorService.LogLevel;
import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController;
import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
@@ -80,9 +84,6 @@ import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
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)
@@ -98,13 +99,21 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
@Autowired(required = true)
IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy;
+ @Autowired(required = true)
+ private IErrorService errorTicketService;
+
@Autowired(required = false)
private ISsoManager ssoManager;
+
@Autowired
private IStatisticLogger statisticLogger;
+
@Autowired
private IRevisionLogger revisionsLogger;
+ @Autowired(required = true)
+ protected ITransactionStorage transactionStorage;
+
private IGuiFormBuilder guiBuilder;
/*
@@ -130,8 +139,7 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
final ISpConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
if (oaParam == null) {
- throw new EaafAuthenticationException(
- IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
+ throw new EaafAuthenticationException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOSPCONFIG,
new Object[] { pendingReq.getSpEntityId() });
}
@@ -142,8 +150,8 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
finalizeAuthentication(req, resp, pendingReq);
// transaction is finished, log transaction finished event
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED,
- pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq
+ .getUniqueTransactionIdentifier());
}
@@ -170,7 +178,7 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
@Override
public void finalizeAuthentication(final HttpServletRequest req, final HttpServletResponse resp,
final IRequest pendingReq) throws EaafException, IOException {
- log.debug("Finalize PendingRequest with ID " + pendingReq.getPendingRequestId());
+ log.debug("Finalize PendingRequest with ID={} ", pendingReq.getPendingRequestId());
try {
// check if pending-request has 'abortedByUser' flag set
@@ -178,15 +186,8 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
// 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());
-
- }
+ new Object[] {}), req,
+ resp, pendingReq);
// check if pending-request are authenticated
} else if (pendingReq.isAuthenticated() && !pendingReq.isNeedUserConsent()) {
@@ -194,11 +195,12 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
} 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());
+ 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!");
+ log.error("PendingRequest NEEDS user-consent. "
+ + "Can NOT fininalize authentication --> Abort authentication process!");
} else {
log.error("PendingRequest is NOT authenticated --> Abort authentication process!");
@@ -210,66 +212,106 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
}
} catch (final Exception e) {
- log.error("Finalize authentication protocol FAILED.", e);
+ log.info("Finalize authentication protocol FAILED. Reason: {}", e.getMessage());
buildProtocolSpecificErrorResponse(e, req, resp, pendingReq);
+ } finally {
+ // remove pending-request
+ requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq
+ .getUniqueTransactionIdentifier());
}
- // 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 {
+ public void buildProtocolSpecificErrorResponse(final Throwable throwable, final HttpServletRequest req,
+ final HttpServletResponse resp, final IRequest protocolRequest) throws EaafException, IOException {
try {
+
+ final IErrorService.IHandleData errorData = errorTicketService.createHandleData(throwable, true);
- 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.");
+ // log Error to technical log
+ logExceptionToTechnicalLog(errorData);
- }
-
- final IModulInfo handlingModule = (IModulInfo) applicationContext.getBean(clazz);
+ // log Error Message
+ statisticLogger.logErrorOperation(throwable, protocolRequest);
+
+ // write revision log entries
+ revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR,
+ protocolRequest.getUniqueTransactionIdentifier());
+
+ if (ActionType.TICKET.equals(errorData.getActionType())
+ || ActionType.ERRORPAGE.equals(errorData.getActionType())) {
+
+ if (errorData.getErrorIdTokenForRedirect() != null) {
+ // Put pending request
+ final ExceptionContainer exceptionContainer = new ExceptionContainer(protocolRequest, throwable);
+ final byte[] serialized = SerializationUtils.serialize(exceptionContainer);
+ log.debug("Put error into cache to support SP forwarding ... ");
+ String internalErrorToken = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(
+ errorData.getErrorIdTokenForRedirect());
+ log.trace("errorIdToken: {}", internalErrorToken);
+ transactionStorage.put(internalErrorToken, serialized, -1);
+
+ } else {
+ log.debug("No errorTokenId. Forwarding to SP will not be available");
+
+ }
- if (handlingModule.generateErrorMessage(throwable, req, resp, protocolRequest)) {
+ // render GUI
+ displayException(req, resp, errorData);
- // log Error to technical log
- logExceptionToTechnicalLog(throwable);
+ } else {
+ final IModulInfo handlingModule = extractShibbolethHandling(protocolRequest, applicationContext);
+ if (handlingModule.generateErrorMessage(throwable, req, resp, protocolRequest)) {
+ log.debug("Error-response to SP successfully written");
- // log Error Message
- statisticLogger.logErrorOperation(throwable, protocolRequest);
+ } else {
+ log.info("Error-response to SP FAILED. Writing error message into GUI ... ");
+ displayException(req, resp, errorData);
- // write revision log entries
- revisionsLogger.logEvent(protocolRequest, EventConstants.TRANSACTION_ERROR,
- protocolRequest.getUniqueTransactionIdentifier());
+ }
+ }
- return;
+ } catch (final Throwable e) {
+ // if building error response results in error, we try with with
+ // handleErrorNoRedirect
+ log.error("ErrorHandling has an internel error. Show process-error in GUI ... ", e);
+ handleErrorNoRedirect(throwable, req, resp, false);
- } else {
- handleErrorNoRedirect(throwable, req, resp, true);
+ }
+ }
- }
+ /**
+ * Retrieves shibboleth module info.
+ *
+ * @param protocolRequest current request
+ * @param applicationContext spring context
+ * @return IModulInfo
+ * @throws ClassNotFoundException If no shibboleth handling implementation found
+ */
+ public static IModulInfo extractShibbolethHandling(IRequest protocolRequest,
+ ApplicationContext applicationContext)
+ throws ClassNotFoundException {
+ final Class<?> clazz = Class.forName(protocolRequest.requestedModule());
- } catch (final Throwable e) {
- handleErrorNoRedirect(throwable, req, resp, true);
+ if (clazz == null || !IModulInfo.class.isAssignableFrom(clazz)) {
+ log.error("Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
+ throw new ClassCastException(
+ "Requested protocol module Class is NULL or does not implement the IModulInfo interface.");
}
+ return (IModulInfo) applicationContext.getBean(clazz);
}
@Override
public void handleErrorNoRedirect(final Throwable throwable, final HttpServletRequest req,
- final HttpServletResponse resp, final boolean writeExceptionToStatisticLog)
- throws IOException, EaafException {
+ final HttpServletResponse resp, final boolean writeExceptionToStatisticLog) throws EaafException,
+ IOException {
+
+ final IErrorService.IHandleData errorData = errorTicketService.createHandleData(throwable, false);
// log Exception into statistic database
if (writeExceptionToStatisticLog) {
@@ -277,61 +319,61 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
}
// write errror to console
- logExceptionToTechnicalLog(throwable);
+ logExceptionToTechnicalLog(errorData);
+
+ // render GUI
+ displayException(req, resp, errorData);
+
+ }
+
+ private void logExceptionToTechnicalLog(IHandleData errorData) {
+ // In case of a TaskExecutionException, which is only a container for
+ // process-errors,
+ // extract internal exception
+
+ // Log exception
+ if (!(errorData.getThrowable() instanceof EaafException)
+ || LogLevel.ERROR.equals(errorData.getLogLevel())) {
+ log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable());
+
+ } else if (LogLevel.WARN.equals(errorData.getLogLevel())) {
+ log.warn(errorData.getPreFormatedErrorMessage(), errorData.getThrowable());
+
+ } else if (LogLevel.INFO.equals(errorData.getLogLevel())) {
+ log.info(errorData.getPreFormatedErrorMessage(), errorData.getThrowable());
+
+ } else if (LogLevel.DEBUG.equals(errorData.getLogLevel())) {
+ log.debug(errorData.getPreFormatedErrorMessage(), errorData.getThrowable());
- // 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);
+ log.warn("Get unsupported LogLevelType: {}. Use {} as default",
+ errorData.getLogLevel(), LogLevel.ERROR);
+ log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable());
}
-
}
@Override
public void forwardToErrorHandler(Pair<IRequest, Throwable> errorToHandle, String errorKey,
final HttpServletRequest req, final HttpServletResponse resp) throws GuiBuildException {
- IGuiBuilderConfiguration parentHopGuiConfig =
- evaluateRequiredErrorHandlingMethod(errorToHandle.getFirst(), errorKey);
+ final IGuiBuilderConfiguration parentHopGuiConfig = evaluateRequiredErrorHandlingMethod(errorToHandle
+ .getFirst(),
+ errorKey);
if (parentHopGuiConfig != null) {
log.trace("iFrame to parent hop requested. Building GUI step for error handling ... ");
guiBuilder.build(req, resp, parentHopGuiConfig, "iFrame-to-parent");
-
- } else {
+
+ } else {
// build up redirect URL
final String redirectUrl = generateErrorRedirectUrl(req, errorKey);
resp.setContentType("text/html");
resp.setStatus(302);
resp.addHeader("Location", redirectUrl);
- log.debug("REDIRECT TO: " + redirectUrl);
-
+ log.debug("REDIRECT TO: {}", redirectUrl);
+
}
}
-
- private IGuiBuilderConfiguration evaluateRequiredErrorHandlingMethod(IRequest first, String errorId) {
- if (first != null && first.isProcessInIframe()) {
- return guiConfigFactory.getDefaultIFrameParentHopGui(first,
- "/" + ProtocolFinalizationController.ENDPOINT_ERRORHANDLING,
- errorId);
-
- }
- return null;
- }
-
- private String generateErrorRedirectUrl(final HttpServletRequest req, String errorKey) {
- String redirectUrl = null;
- redirectUrl = ServletUtils.getBaseUrl(req);
- redirectUrl += "/" + ProtocolFinalizationController.ENDPOINT_ERRORHANDLING + "?"
- + EaafConstants.PARAM_HTTP_ERROR_CODE + "=" + errorKey;
- return redirectUrl;
-
- }
-
public void setGuiBuilder(final IGuiFormBuilder guiBuilder) {
this.guiBuilder = guiBuilder;
}
@@ -339,15 +381,14 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
/**
* 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
+ * @param req HttpServletRequest
+ * @param resp HttpServletResponse
+ * @param pendingReq Authentication request which is actually in process
* @throws Exception In case of an error
*/
protected void internalFinalizeAuthenticationProcess(final HttpServletRequest req,
- final HttpServletResponse resp, final IRequest pendingReq) throws Exception {
+ final HttpServletResponse resp,
+ final IRequest pendingReq) throws Exception {
String newSsoSessionId = null;
@@ -369,8 +410,8 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
final IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq);
// execute the protocol-specific action
- final SloInformationInterface sloInformation =
- executeProtocolSpecificAction(req, resp, pendingReq, authData);
+ final SloInformationInterface sloInformation = executeProtocolSpecificAction(req, resp, pendingReq,
+ authData);
// Store OA specific SSO session information if an SSO cookie is set
if (StringUtils.isNotEmpty(newSsoSessionId)) {
@@ -390,21 +431,24 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
}
// Advanced statistic logging
- statisticLogger.logSuccessOperation(pendingReq, authData,
- StringUtils.isNotEmpty(newSsoSessionId));
+ statisticLogger.logSuccessOperation(pendingReq, authData, StringUtils.isNotEmpty(newSsoSessionId));
+
+ }
+
+ @PostConstruct
+ private void initializer() {
+ log.trace("Initializing {} ...", ProtocolAuthenticationService.class.getName());
}
/**
* 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
- *
+ * @param httpReq HttpServletRequest
+ * @param httpResp HttpServletResponse
+ * @param pendingReq 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,
@@ -416,7 +460,7 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
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(
+ throw new ClassCastException(
"Requested protocol-action processing Class is NULL or does not implement the IAction interface.");
}
@@ -427,153 +471,130 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer
} 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.");
+ throw new ClassNotFoundException(
+ "Requested Auth. protocol processing Class is NULL or does not implement the IAction interface.",
+ e);
}
}
- /**
- * 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, String externalErrorCode) throws
+ // EaafException {
+ // this.writeHtmlErrorResponse(httpReq, httpResp, msg, errorCode, params,
+ // externalErrorCode, null, null);
+ // }
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 {
+ @NonNull final HttpServletResponse httpResp, @NonNull final String msg, @NonNull final String errorCode,
+ @Nullable final Object[] params, String externalErrorCode, IErrorService.IHandleData errorData)
+ throws EaafException {
try {
- final IGuiBuilderConfiguration config =
- guiConfigFactory.getDefaultErrorGui(HttpUtils.extractAuthUrlFromRequest(httpReq));
+ 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();
+ /* replace all single-quotes by two single-quotes for escaping purposes to mitigate
+ * Thymeleaf error in:
+ * th:text="${#messages.msgWithParams('__${msg.errorCode}__', '__${msg.errorParams}__')}"
+ */
+ errorCodeParams[i] = params[i].toString().replaceAll("'", "''");
+
} 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));
-
- }
+ final ModifyableGuiBuilderConfiguration c = (ModifyableGuiBuilderConfiguration) config;
+ c.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERROMSG, msg);
+ c.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_ERRORCODE,
+ errorCode);
+ // TODO: should we keep the internal errorcode secret?
+ c.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG,
+ PARAM_GUI_EXTERNAL_ERRORCODE,
+ externalErrorCode);
+ c.putCustomParameterWithOutEscaption(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG,
+ PARAM_GUI_ERRORCODEPARAMS, ArrayUtils.toString(errorCodeParams));
+ errorTicketService.displayErrorData(c, errorData, httpReq);
} else {
- log.info(
- "Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
+ 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);
+ throw new EaafException("internal.99", new Object[] {e.getMessage()}, e);
}
}
- private String getStacktraceFromException(final Exception ex) {
- final StringWriter errors = new StringWriter();
- ex.printStackTrace(new PrintWriter(errors));
- return errors.toString();
+ private void displayException(final HttpServletRequest req, final HttpServletResponse resp,
+ final IErrorService.IHandleData errorData) throws IOException, EaafException {
+ final Throwable e = errorData.getThrowable();
+ final String internalErrorCode = errorData.getInternalErrorCode();
- }
-
- private void internalMoaidExceptionHandler(final HttpServletRequest req,
- final HttpServletResponse resp, final Exception e, final boolean writeExceptionToStatisicLog)
- throws IOException, EaafException {
+ // send error response
if (e instanceof ProtocolNotActiveException) {
- resp.getWriter().write(e.getMessage());
+ resp.getWriter().write(Encode.forHtml(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());
- }
-
+ } else if (e instanceof AuthnRequestValidatorException || e instanceof InvalidProtocolRequestException
+ || e instanceof ProcessExecutionException || e instanceof ConfigurationException) {
// 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);
+ writeHtmlErrorResponse(req, resp, e.getMessage(), internalErrorCode, null,
+ statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData);
} else if (e instanceof EaafException) {
// send HTML formated error message
- writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
- ((EaafException) e).getParams(), e);
+ writeHtmlErrorResponse(req, resp, e.getMessage(), internalErrorCode, ((EaafException) e).getParams(),
+ statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData);
- } else if (e instanceof ProcessExecutionException) {
- // send HTML formated error message
- writeHtmlErrorResponse(req, resp, e.getMessage(), statusMessager.getResponseErrorCode(e),
- null, e);
+ } else {
+ // write generic message for general exceptions
+ final String msg = statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null);
+ writeHtmlErrorResponse(req, resp, msg, internalErrorCode, null,
+ statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData);
}
+ }
+
+ private IGuiBuilderConfiguration evaluateRequiredErrorHandlingMethod(IRequest first, String errorId) {
+ if (first != null && first.isProcessInIframe()) {
+ return guiConfigFactory
+ .getDefaultIFrameParentHopGui(first, ProtocolFinalizationController.ENDPOINT_ERRORHANDLING,
+ errorId);
+
+ }
+ return null;
+ }
+
+ private String generateErrorRedirectUrl(final HttpServletRequest req, String errorKey) {
+ String redirectUrl = null;
+ redirectUrl = ServletUtils.getBaseUrl(req);
+ redirectUrl += ProtocolFinalizationController.ENDPOINT_ERRORHANDLING + "?"
+ + EaafConstants.PARAM_HTTP_ERROR_CODE + "=" + errorKey;
+ return redirectUrl;
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/AttributeBuilderRegistration.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/AttributeBuilderRegistration.java
new file mode 100644
index 00000000..b554ad05
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/AttributeBuilderRegistration.java
@@ -0,0 +1,88 @@
+package at.gv.egiz.eaaf.core.impl.idp.builder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class AttributeBuilderRegistration {
+
+ private static HashMap<String, IAttributeBuilder> builders;
+
+ private static ServiceLoader<IAttributeBuilder> attributBuilderLoader =
+ ServiceLoader.load(IAttributeBuilder.class);
+
+ private static void addBuilder(final IAttributeBuilder builder) {
+ builders.put(builder.getName(), builder);
+ }
+
+ static {
+ builders = new HashMap<>();
+
+ log.info("Loading protocol attribut-builder modules:");
+ if (attributBuilderLoader != null) {
+ final Iterator<IAttributeBuilder> moduleLoaderInterator = attributBuilderLoader.iterator();
+ while (moduleLoaderInterator.hasNext()) {
+ try {
+ final IAttributeBuilder modul = moduleLoaderInterator.next();
+ log.info("Loading attribut-builder Modul Information: " + modul.getName());
+ addBuilder(modul);
+
+ } catch (final Throwable e) {
+ log.error("Check configuration! " + "Some attribute-builder modul"
+ + " is not a valid IAttributeBuilder", e);
+ }
+ }
+ }
+
+ log.info("Loading attribute-builder modules done");
+
+ }
+
+ /**
+ * Get a specific attribute builder.
+ *
+ * @param name Attribute-builder friendly name
+ *
+ * @return Attribute-builder with this name or null if builder does not exists
+ */
+ public static IAttributeBuilder getAttributeBuilder(final String name) {
+ return builders.get(name);
+
+ }
+
+ /**
+ * Check if a specific attribute-builder is available.
+ *
+ * @param name Attribute-builder friendly name
+ * @return <code>true</code> if the builder is registered, otherwise <code>false</code>
+ */
+ public static boolean containsBuilder(final String name) {
+ return builders.containsKey(name);
+
+ }
+
+ /**
+ * Get all registered attribute-builder.
+ *
+ * @return {@link Iterator} of all available builders
+ */
+ public static Iterator<IAttributeBuilder> getAllRegistratedBuilder() {
+ return builders.values().iterator();
+
+ }
+
+ /**
+ * Get the number of currently register attribute builders.
+ *
+ * @return number of attribute builders
+ */
+ public static int getNumberOfRegisteredBuilders() {
+ return builders.size();
+
+ }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
index 19500cb3..a82a1a55 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BirthdateAttributeBuilder.java
@@ -19,8 +19,7 @@
package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
+import org.apache.commons.lang3.StringUtils;
import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
@@ -41,11 +40,8 @@ public class BirthdateAttributeBuilder implements IPvpAttributeBuilder {
public <ATT> ATT build(final ISpConfiguration oaParam, final IAuthData authData,
final IAttributeGenerator<ATT> g) throws AttributeBuilderException {
- if (authData.getDateOfBirth() != null) {
- final DateFormat pvpDateFormat = new SimpleDateFormat(BIRTHDATE_FORMAT_PATTERN);
- final String dateString = pvpDateFormat.format(authData.getDateOfBirth());
-
- return g.buildStringAttribute(BIRTHDATE_FRIENDLY_NAME, BIRTHDATE_NAME, dateString);
+ if (StringUtils.isNotEmpty(authData.getDateOfBirth())) {
+ return g.buildStringAttribute(BIRTHDATE_FRIENDLY_NAME, BIRTHDATE_NAME, authData.getDateOfBirth());
} else {
throw new UnavailableAttributeException(BIRTHDATE_NAME);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BpkAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BpkAttributeBuilder.java
index e18cc1a8..5cbfec01 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BpkAttributeBuilder.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BpkAttributeBuilder.java
@@ -19,27 +19,23 @@
package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
-import javax.annotation.Nonnull;
-
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.Assert;
-import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.IPvpAttributeBuilder;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+import at.gv.egiz.eaaf.core.impl.builder.BpkBuilder;
@PvpMetadata
public class BpkAttributeBuilder implements IPvpAttributeBuilder {
private static final Logger log = LoggerFactory.getLogger(BpkAttributeBuilder.class);
- public static final String DELIMITER_BPKTYPE_BPK = ":";
-
+
@Override
public String getName() {
return BPK_NAME;
@@ -60,12 +56,13 @@ public class BpkAttributeBuilder implements IPvpAttributeBuilder {
}
protected String getBpkForSP(final IAuthData authData) throws UnavailableAttributeException {
- final String bpk = attrMaxSize(authData.getBpk());
- final String type = removeBpkTypePrefix(authData.getBpkType());
-
- if (StringUtils.isEmpty(bpk)) {
+ if (StringUtils.isEmpty(authData.getBpk()) || StringUtils.isEmpty(authData.getBpkType())) {
throw new UnavailableAttributeException(BPK_NAME);
+
}
+
+ final String bpk = attrMaxSize(authData.getBpk());
+ final String type = BpkBuilder.removeBpkTypePrefix(authData.getBpkType());
return type + DELIMITER_BPKTYPE_BPK + bpk;
@@ -78,23 +75,5 @@ public class BpkAttributeBuilder implements IPvpAttributeBuilder {
return attr;
}
-
- @Nonnull
- protected String removeBpkTypePrefix(@Nonnull final String type) {
- Assert.isTrue(type != null, "bPKType is 'NULL'");
- if (type.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
- return type.substring(EaafConstants.URN_PREFIX_WBPK.length());
-
- } else if (type.startsWith(EaafConstants.URN_PREFIX_CDID)) {
- return type.substring(EaafConstants.URN_PREFIX_CDID.length());
-
- } else if (type.startsWith(EaafConstants.URN_PREFIX_EIDAS)) {
- return type.substring(EaafConstants.URN_PREFIX_EIDAS.length());
-
- } else {
- return type;
-
- }
-
- }
+
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidCcsUrl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidCcsUrl.java
index 27b78059..03c16aef 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidCcsUrl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidCcsUrl.java
@@ -31,7 +31,8 @@ public class EidCcsUrl implements IPvpAttributeBuilder {
}
} else {
- log.info(EID_CCS_URL_FRIENDLY_NAME + " is only available in MOA-ID context");
+ log.info(EID_CCS_URL_FRIENDLY_NAME + " is only available in E-ID context");
+
}
throw new UnavailableAttributeException(EID_CCS_URL_NAME);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIdentityStatusLevelAttributeBuiler.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIdentityStatusLevelAttributeBuiler.java
index ee51564e..8345dcf8 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIdentityStatusLevelAttributeBuiler.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIdentityStatusLevelAttributeBuiler.java
@@ -1,8 +1,5 @@
package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
@@ -10,11 +7,11 @@ import at.gv.egiz.eaaf.core.api.idp.IPvpAttributeBuilder;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
@PvpMetadata
public class EidIdentityStatusLevelAttributeBuiler implements IPvpAttributeBuilder {
- private static final Logger log =
- LoggerFactory.getLogger(EidIdentityStatusLevelAttributeBuiler.class);
@Override
public String getName() {
@@ -28,12 +25,15 @@ public class EidIdentityStatusLevelAttributeBuiler implements IPvpAttributeBuild
if (authData instanceof IEidAuthData) {
if (((IEidAuthData) authData).getEidStatus() == null) {
throw new UnavailableAttributeException(getName());
+
}
return g.buildStringAttribute(getFriendlyName(), getName(),
((IEidAuthData) authData).getEidStatus().getUri());
+
} else {
log.info(getFriendlyName() + " is only available in EAAF context");
+
}
throw new UnavailableAttributeException(getName());
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIssuingNationAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIssuingNationAttributeBuilder.java
index fd85871c..90e8c285 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIssuingNationAttributeBuilder.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidIssuingNationAttributeBuilder.java
@@ -41,7 +41,7 @@ public class EidIssuingNationAttributeBuilder implements IPvpAttributeBuilder {
final String countryCode = authData.getCiticenCountryCode();
if (StringUtils.isNotEmpty(countryCode)) {
return g.buildStringAttribute(EID_ISSUING_NATION_FRIENDLY_NAME, EID_ISSUING_NATION_NAME,
- countryCode);
+ countryCode.toUpperCase());
} else {
return null;
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSectorForIdAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSectorForIdAttributeBuilder.java
index 48d7a3a3..ba993b0c 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSectorForIdAttributeBuilder.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSectorForIdAttributeBuilder.java
@@ -27,7 +27,7 @@ import at.gv.egiz.eaaf.core.api.idp.IPvpAttributeBuilder;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
-import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BpkBuilder;
+import at.gv.egiz.eaaf.core.impl.builder.BpkBuilder;
@PvpMetadata
public class EidSectorForIdAttributeBuilder implements IPvpAttributeBuilder {
@@ -48,7 +48,7 @@ public class EidSectorForIdAttributeBuilder implements IPvpAttributeBuilder {
return g.buildStringAttribute(EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME,
EID_SECTOR_FOR_IDENTIFIER_NAME,
- BpkBuilder.normalizeBpkTargetIdentifierToCalculationFormat(bpktype));
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(bpktype));
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSignerCertificate.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSignerCertificate.java
index 6f857779..daed8455 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSignerCertificate.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/EidSignerCertificate.java
@@ -53,16 +53,17 @@ public class EidSignerCertificate implements IPvpAttributeBuilder {
EID_SIGNER_CERTIFICATE_NAME, Base64Utils.encodeToString(signerCertificate));
} else {
- log.info(EID_SIGNER_CERTIFICATE_FRIENDLY_NAME + " is only available in MOA-ID context");
+ log.debug("{} is not available", EID_SIGNER_CERTIFICATE_FRIENDLY_NAME);
+
}
} catch (final Exception e) {
- log.info("Signer certificate BASE64 encoding error");
+ log.info("{} BASE64 encoding error", EID_SIGNER_CERTIFICATE_FRIENDLY_NAME);
}
} else {
- log.info(EID_SIGNER_CERTIFICATE_FRIENDLY_NAME + " is only available in AuthHandler context");
+ log.info("{} is only available in AuthHandler context", EID_SIGNER_CERTIFICATE_FRIENDLY_NAME);
}
throw new UnavailableAttributeException(EID_SIGNER_CERTIFICATE_NAME);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PiiTransactionIdAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PiiTransactionIdAttributeBuilder.java
new file mode 100644
index 00000000..08911ac7
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/PiiTransactionIdAttributeBuilder.java
@@ -0,0 +1,37 @@
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class PiiTransactionIdAttributeBuilder implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+
+ @Override
+ public String getName() {
+ return EID_PII_TRANSACTION_ID_NAME;
+
+ }
+
+ @Override
+ public <ATT> ATT build(ISpConfiguration oaParam, IAuthData authData, IAttributeGenerator<ATT> g)
+ throws AttributeBuilderException {
+ String piiTransactionId = authData.getGenericData(EID_PII_TRANSACTION_ID_NAME, String.class);
+ log.trace("{} piiTransactionId: {} as attribute",
+ piiTransactionId != null ? "Set" : "Notset", log.isTraceEnabled() ? piiTransactionId : "********");
+ return g.buildStringAttribute(EID_PII_TRANSACTION_ID_FRIENDLY_NAME, EID_PII_TRANSACTION_ID_NAME,
+ piiTransactionId);
+
+ }
+
+ @Override
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(EID_PII_TRANSACTION_ID_FRIENDLY_NAME, EID_PII_TRANSACTION_ID_NAME);
+
+ }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpUsesMandates.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateModeAttributeBuilder.java
index 44ff4e50..3240cfca 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpUsesMandates.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateModeAttributeBuilder.java
@@ -26,11 +26,11 @@ import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
-public class SpUsesMandates implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+public class SpMandateModeAttributeBuilder implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
@Override
public String getName() {
- return SP_USESMANDATES_NAME;
+ return SP_USED_MANDATE_TYPE_NAME;
}
@Override
@@ -44,7 +44,7 @@ public class SpUsesMandates implements IAttributeBuilder, ExtendedPvpAttributeDe
@Override
public <ATT> ATT buildEmpty(final IAttributeGenerator<ATT> g) {
- return g.buildEmptyAttribute(SP_USESMANDATES_FRIENDLY_NAME, SP_USESMANDATES_NAME);
+ return g.buildEmptyAttribute(SP_USED_MANDATE_TYPE_FRIENDLY_NAME, SP_USED_MANDATE_TYPE_NAME);
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateProfilesAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateProfilesAttributeBuilder.java
new file mode 100644
index 00000000..e0d00f7d
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/SpMandateProfilesAttributeBuilder.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class SpMandateProfilesAttributeBuilder implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+
+ @Override
+ public String getName() {
+ return SP_USED_MANDATE_PROFILES_NAME;
+ }
+
+ @Override
+ public <ATT> ATT build(final ISpConfiguration oaParam, final IAuthData authData,
+ final IAttributeGenerator<ATT> g)
+ throws AttributeBuilderException {
+ // this attribute can not generated yet
+ return null;
+
+ }
+
+ @Override
+ public <ATT> ATT buildEmpty(final IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(SP_USED_MANDATE_PROFILES_FRIENDLY_NAME, SP_USED_MANDATE_PROFILES_NAME);
+
+ }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/TransactionIdAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/TransactionIdAttributeBuilder.java
new file mode 100644
index 00000000..17b830dc
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/TransactionIdAttributeBuilder.java
@@ -0,0 +1,33 @@
+package at.gv.egiz.eaaf.core.impl.idp.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
+
+public class TransactionIdAttributeBuilder implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+
+ @Override
+ public String getName() {
+ return EID_TRANSACTION_ID_NAME;
+
+ }
+
+ @Override
+ public <ATT> ATT build(ISpConfiguration oaParam, IAuthData authData, IAttributeGenerator<ATT> g)
+ throws AttributeBuilderException {
+ return g.buildStringAttribute(EID_TRANSACTION_ID_FRIENDLY_NAME, EID_TRANSACTION_ID_NAME,
+ TransactionIdUtils.getTransactionId());
+
+ }
+
+ @Override
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(EID_TRANSACTION_ID_FRIENDLY_NAME, EID_TRANSACTION_ID_NAME);
+
+ }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
index fc62af45..b05d8df0 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
@@ -26,11 +26,11 @@ import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
+import org.springframework.util.SerializationUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import at.gv.egiz.components.eventlog.api.EventConstants;
@@ -42,12 +42,12 @@ import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
import at.gv.egiz.eaaf.core.api.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.PendingReqIdValidationException;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.data.Pair;
-import at.gv.egiz.eaaf.core.impl.utils.Random;
/**
* Basic application controller that implements core error-handling.
@@ -69,10 +69,13 @@ public abstract class AbstractController {
protected ITransactionStorage transactionStorage;
@Autowired(required = true)
protected IStatusMessenger statusMessager;
-
+
@Autowired
protected IRevisionLogger revisionsLogger;
+ @Autowired
+ protected IPendingRequestIdGenerationStrategy reqIdGenerationStrategy;
+
/**
* EAAF framework exception handler.
*
@@ -92,11 +95,11 @@ public abstract class AbstractController {
protAuthService.handleErrorNoRedirect(e, req, resp, true);
} catch (final EaafException e1) {
+ log.warn("ErrorHandling failed with error: ", e.getMessage(), e);
log.warn("Can NOT handle an 'EAAFException'. Forwarding to generic error ... ", e);
ioExceptionHandler(resp, e);
}
-
}
/**
@@ -106,20 +109,23 @@ public abstract class AbstractController {
* This handler wrote an internal server error into http response
* </p>
*
- * @param resp http response
- * @param exception exception
+ * @param req http request
+ * @param resp http response
+ * @param e Catched exception
* @throws IOException In case of an internal error.
*/
@ExceptionHandler({ Exception.class })
- public void genericExceptionHandler(final HttpServletResponse resp, final Exception exception)
- throws IOException {
- log.error("Internel Server Error.", exception);
- resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error!"
- + "(Errorcode=9199" + " | Description="
- + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage()))
- + ")");
+ public void genericExceptionHandler(final HttpServletRequest req, final HttpServletResponse resp,
+ final Exception e) throws IOException {
+ try {
+ protAuthService.handleErrorNoRedirect(e, req, resp, true);
+
+ } catch (final EaafException e1) {
+ log.warn("ErrorHandling failed with error: ", e.getMessage(), e);
+ log.error("Can NOT handle a generic 'Exception'. Forwarding to generic error ... ", e);
+ ioExceptionHandler(resp, e);
+ }
}
/**
@@ -150,8 +156,6 @@ public abstract class AbstractController {
try {
final String errorKey = storeErrorAndGetErrorToken(errorToHandle);
protAuthService.forwardToErrorHandler(errorToHandle, errorKey, req, resp);
-
- return;
} catch (final Exception e) {
log.warn("Default error-handling FAILED. Exception can not be stored ....", e);
@@ -169,18 +173,30 @@ public abstract class AbstractController {
}
// put exception into transaction store for redirect
- final String errorKey = Random.nextLongRandom();
+ final String errorToken = reqIdGenerationStrategy.generateExternalPendingRequestId();
+ final String errorKey = reqIdGenerationStrategy.getPendingRequestIdWithOutChecks(errorToken);
+
if (errorToHandle.getFirst() != null) {
revisionsLogger.logEvent(errorToHandle.getFirst(), EventConstants.TRANSACTION_ERROR);
- transactionStorage.put(errorKey, new ExceptionContainer(errorToHandle.getFirst(), errorToHandle
- .getSecond()), -1);
+
+ log.trace("Serializing {} ... ", ExceptionContainer.class.getName());
+ final byte[] serializedError = SerializationUtils.serialize(
+ new ExceptionContainer(errorToHandle.getFirst(), errorToHandle.getSecond()));
+
+ log.debug("Put 'ExceptionContainer' into cache with id: {}... ", errorKey);
+ transactionStorage.put(errorKey, serializedError, -1);
} else {
- transactionStorage.put(errorKey, new ExceptionContainer(null, errorToHandle.getSecond()), -1);
+ log.trace("Serializing {} ... ", ExceptionContainer.class.getName());
+ final byte[] serializedError = SerializationUtils.serialize(
+ new ExceptionContainer(null, errorToHandle.getSecond()));
+
+ log.trace("Put 'ExceptionContainer' into cache with id: {}... ",errorKey);
+ transactionStorage.put(errorKey, serializedError, -1);
}
- return errorKey;
+ return errorToken;
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
index 098bca4c..ea481bdb 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractProcessEngineSignalController.java
@@ -36,6 +36,7 @@ import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.EaafIllegalStateException;
+import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
/**
@@ -78,13 +79,16 @@ public abstract class AbstractProcessEngineSignalController extends AbstractCont
// process instance is mandatory
if (pendingReq.getProcessInstanceId() == null) {
throw new EaafIllegalStateException(
- new Object[] { "MOA session does not provide process instance id." });
+ new Object[] { "PendingRequest does not provide process-instance id." });
}
// wake up next task
processEngine.signal(pendingReq);
+ } catch (PendingReqIdValidationException e) {
+ handleError(null, e, req, resp, e.getInvalidPendingReq());
+
} catch (final Exception ex) {
handleError(null, ex, req, resp, pendingReq);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
index 17da63f5..a22cbe9d 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/ProtocolFinalizationController.java
@@ -15,7 +15,7 @@
* This product combines work with different licenses. See the "NOTICE" text file for details on the
* various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
* works that you distribute must include a readable copy of the "NOTICE" text file.
-*/
+ */
package at.gv.egiz.eaaf.core.impl.idp.controller;
@@ -29,6 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
+import org.springframework.util.SerializationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -38,22 +39,107 @@ import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
+import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
+import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.services.ProtocolAuthenticationService;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
/**
* Protocol finialization end-point.
*
* @author tlenz
- *
*/
@Controller
public class ProtocolFinalizationController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(ProtocolFinalizationController.class);
- public static final String ENDPOINT_FINALIZEPROTOCOL = "finalizeAuthProtocol";
- public static final String ENDPOINT_ERRORHANDLING = "errorHandling";
+ public static final String ENDPOINT_FINALIZEPROTOCOL =
+ EaafConstants.ENDPOINT_PREFIX_SECURED + "/finalizeAuthProtocol";
+ public static final String ENDPOINT_ERRORHANDLING =
+ EaafConstants.ENDPOINT_PREFIX_SECURED + "/errorHandling";
+ public static final String ENDPOINT_ERROR_REDIRECT =
+ EaafConstants.ENDPOINT_PREFIX_SECURED + "/errorRedirect";
@Autowired(required = true)
IRequestStorage requestStorage;
+ @Autowired
+ IPendingRequestIdGenerationStrategy requestIdValidationStragegy;
+
+
+ /**
+ * Handles incoming requests for redirects to IDP.
+ * @param req http request
+ * @param resp http response
+ * @throws EaafException In case of an internal error
+ * @throws IOException In case of a servlet error
+ */
+ @RequestMapping(value = ENDPOINT_ERROR_REDIRECT, method = {RequestMethod.GET, RequestMethod.POST})
+ public void errorRedirect(final HttpServletRequest req, final HttpServletResponse resp)
+ throws EaafException, IOException {
+
+ final String errorToken = StringEscapeUtils.escapeHtml4(req.getParameter(EaafConstants.PARAM_HTTP_ERROR_CODE));
+ if (errorToken != null) {
+ IRequest pendingReq = null;
+ try {
+ String errorId = requestIdValidationStragegy.validateAndGetPendingRequestId(errorToken);
+ log.debug("Searching exception with internal error-token: {}", errorId);
+
+ // load stored exception from database
+ final byte[] containerSerialized = transactionStorage.get(errorId, byte[].class);
+ if (containerSerialized != null) {
+ // remove exception if it was found
+ transactionStorage.remove(errorId);
+ log.trace("Find exception with internal error-token: {}", errorId);
+
+ //final Object containerObj = EaafSerializationUtils.deserialize(containerSerialized,
+ // Arrays.asList(
+ // ExceptionContainer.class.getName()
+ // ));
+ final Object containerObj = SerializationUtils.deserialize(containerSerialized);
+
+ if (containerObj instanceof ExceptionContainer) {
+ final ExceptionContainer container = (ExceptionContainer) containerObj;
+ final Throwable throwable = container.getExceptionThrown();
+ pendingReq = container.getPendingRequest();
+
+ if (pendingReq != null) {
+ IModulInfo handlingModule = ProtocolAuthenticationService
+ .extractShibbolethHandling(pendingReq, applicationContext);
+ if (!handlingModule.generateErrorMessage(throwable, req, resp, pendingReq)) {
+ protAuthService.handleErrorNoRedirect(new EaafException("process.90", null), req, resp, false);
+
+ }
+ }
+ }
+ } else {
+ log.info("Find no exception with internal error-token: {}", errorId);
+ protAuthService
+ .handleErrorNoRedirect(new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_TIMEOUT, null),
+ req, resp, false);
+
+ }
+
+ } catch (Throwable e) {
+ log.error(e.getMessage(), e);
+ protAuthService.handleErrorNoRedirect(e, req, resp, false);
+
+ } finally {
+ // remove pending-request
+ if (pendingReq != null) {
+ requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
+
+ }
+ }
+
+ } else {
+ log.debug("Request contains NO ErrorId");
+ protAuthService
+ .handleErrorNoRedirect(new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, null), req,
+ resp, false);
+
+ }
+ }
/**
* End-Point to handle errors.
@@ -63,42 +149,62 @@ public class ProtocolFinalizationController extends AbstractController {
* @throws EaafException In case of an internal error
* @throws IOException In case of a servlet error
*/
- @RequestMapping(value = ENDPOINT_ERRORHANDLING, method = { RequestMethod.GET, RequestMethod.POST })
+ @RequestMapping(value = ENDPOINT_ERRORHANDLING, method = {RequestMethod.GET, RequestMethod.POST})
public void errorHandling(final HttpServletRequest req, final HttpServletResponse resp)
throws EaafException, IOException {
// receive an authentication error
- final String errorid =
- StringEscapeUtils.escapeHtml4(req.getParameter(EaafConstants.PARAM_HTTP_ERROR_CODE));
- if (errorid != null) {
+ final String errorToken = StringEscapeUtils.escapeHtml4(req.getParameter(EaafConstants.PARAM_HTTP_ERROR_CODE));
+ if (errorToken != null) {
IRequest pendingReq = null;
try {
+ String errorId = requestIdValidationStragegy.validateAndGetPendingRequestId(errorToken);
+ log.debug("Searching exception with internal error-token: {}", errorId);
+
// load stored exception from database
- final ExceptionContainer container =
- transactionStorage.get(errorid, ExceptionContainer.class);
- if (container != null) {
+ final byte[] containerSerialized = transactionStorage.get(errorId, byte[].class);
+ if (containerSerialized != null) {
// remove exception if it was found
- transactionStorage.remove(errorid);
+ transactionStorage.remove(errorId);
+ log.trace("Find exception with internal error-token: {}", errorId);
+
+ //final Object containerObj = EaafSerializationUtils.deserialize(containerSerialized,
+ // Arrays.asList(
+ // ExceptionContainer.class.getName()
+ // ));
+ final Object containerObj = SerializationUtils.deserialize(containerSerialized);
+
+ if (containerObj instanceof ExceptionContainer) {
+ final ExceptionContainer container = (ExceptionContainer) containerObj;
+ final Throwable throwable = container.getExceptionThrown();
+ pendingReq = container.getPendingRequest();
- final Throwable throwable = container.getExceptionThrown();
- pendingReq = container.getPendingRequest();
+ if (pendingReq != null) {
+ //set MDC variables
+ TransactionIdUtils.setAllLoggingVariables(pendingReq);
- if (pendingReq != null) {
- // build protocol-specific error message if possible
- protAuthService.buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq);
+ // build protocol-specific error message if possible
+ protAuthService.buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq);
- // remove active user-session
- transactionStorage.remove(pendingReq.getPendingRequestId());
+ // remove active user-session
+ transactionStorage.remove(pendingReq.getPendingRequestId());
- return;
+ } else {
+ protAuthService.handleErrorNoRedirect(throwable, req, resp, true);
+
+ }
} else {
- protAuthService.handleErrorNoRedirect(throwable, req, resp, true);
+ protAuthService
+ .handleErrorNoRedirect(new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null), req,
+ resp, false);
}
+
} else {
- protAuthService.handleErrorNoRedirect(
- new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, null),
- req, resp, false);
+ log.info("Find no exception with internal error-token: {}", errorId);
+ protAuthService
+ .handleErrorNoRedirect(new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, null),
+ req, resp, false);
}
@@ -110,18 +216,20 @@ public class ProtocolFinalizationController extends AbstractController {
// remove pending-request
if (pendingReq != null) {
requestStorage.removePendingRequest(pendingReq.getPendingRequestId());
- revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED,
- pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_DESTROYED, pendingReq.getUniqueTransactionIdentifier());
}
+ //remove all Logger variables
+ TransactionIdUtils.removeAllLoggingVariables();
+
}
} else {
log.debug("Request contains NO ErrorId");
- protAuthService.handleErrorNoRedirect(
- new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, null), req,
- resp, false);
+ protAuthService
+ .handleErrorNoRedirect(new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_NOPENDIGREQID, null), req,
+ resp, false);
}
@@ -135,7 +243,7 @@ public class ProtocolFinalizationController extends AbstractController {
* @throws EaafException In case of an internal error
* @throws IOException In case of a servlet error
*/
- @RequestMapping(value = ENDPOINT_FINALIZEPROTOCOL, method = { RequestMethod.GET })
+ @RequestMapping(value = ENDPOINT_FINALIZEPROTOCOL, method = {RequestMethod.GET})
public void finalizeAuthProtocol(final HttpServletRequest req, final HttpServletResponse resp)
throws EaafException, IOException {
@@ -145,14 +253,19 @@ public class ProtocolFinalizationController extends AbstractController {
final IRequest pendingReq = requestStorage.getPendingRequest(pendingRequestID);
if (pendingReq == null) {
- log.error("No PendingRequest with ID " + pendingRequestID + " found.!");
+ log.info("PendingReqId was valid but no PendingRequest with ID: {}. Looks already used",
+ pendingRequestID);
protAuthService.handleErrorNoRedirect(
- new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_TIMEOUT,
- new Object[] { pendingRequestID, }),
- req, resp, false);
+ new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_AUTH_TIMEOUT, new Object[]{pendingRequestID,}), req,
+ resp, false);
} else {
+ //set MDC variables
+ TransactionIdUtils.setAllLoggingVariables(pendingReq);
+
+ //perform protocol finalization steps
protAuthService.finalizeAuthentication(req, resp, pendingReq);
+
}
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/AbstractLocaleAuthServletTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/AbstractLocaleAuthServletTask.java
index dcd5a1d1..007c3e1d 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/AbstractLocaleAuthServletTask.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/AbstractLocaleAuthServletTask.java
@@ -11,9 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
-import at.gv.egiz.eaaf.core.api.data.EaafEventCodes;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
@@ -53,29 +51,6 @@ public abstract class AbstractLocaleAuthServletTask extends AbstractAuthServletT
}
- protected void stopProcessFromUserDecision(final ExecutionContext executionContext,
- final HttpServletRequest request, final HttpServletResponse response)
- throws TaskExecutionException {
- try {
- revisionsLogger.logEvent(pendingReq, EaafEventCodes.PROCESS_STOPPED_BY_USER);
- pendingReq.setAbortedByUser(true);
- pendingReq.setAuthenticated(false);
- performRedirectToProtocolFinialization(executionContext, pendingReq, request, response);
-
- log.trace("Set process-cancelation flag");
- executionContext.setCanceleProcessFlag();
-
- } catch (final EaafException e) {
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
-
- } catch (final Exception e) {
- log.warn("Stopping auth.process FAILED", e);
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
-
- }
-
- }
-
protected boolean parseFlagFromHttpRequest(final HttpServletRequest httpReq,
final String httpParamName, final boolean defaultValue) {
final String flag = httpReq.getParameter(httpParamName);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
index 328a25c5..7a664915 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java
@@ -19,8 +19,6 @@
package at.gv.egiz.eaaf.core.impl.idp.controller.tasks;
-import java.util.Set;
-
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -32,6 +30,7 @@ import org.springframework.stereotype.Component;
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.exceptions.EaafException;
+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.AbstractAuthServletTask;
import at.gv.egiz.eaaf.core.impl.idp.auth.modules.ModuleRegistration;
@@ -73,12 +72,9 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask {
} else {
// create a new execution context and copy all elements to new context
final ExecutionContext newec = new ExecutionContextImpl();
- final Set<String> entries = executionContext.keySet();
- for (final String key : entries) {
- newec.put(key, executionContext.get(key));
-
- }
-
+ executionContext.keySet().stream().forEach(
+ key -> newec.put(key, executionContext.get(key)));
+
log.debug("Select new auth.-process and restart restart process-engine ... ");
// select and create new process instance
@@ -87,7 +83,7 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask {
if (processDefinitionId == null) {
log.warn("No suitable authentication process found for SessionID "
+ pendingReq.getPendingRequestId());
- throw new EaafException("process.02", new Object[] { pendingReq.getPendingRequestId() });
+ throw new EaafException("process.02", null);
}
final String processInstanceId =
@@ -112,10 +108,18 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask {
processEngine.start(pendingReq);
}
-
- } catch (final EaafException e) {
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
-
+
+ } catch (final ProcessExecutionException e) {
+ //check if Task in already selected process failed or if process selection failed
+ if (e.getCause() != null && e.getCause() instanceof TaskExecutionException) {
+ log.info("New process was started, but one Task in process failed. Reason: {}", e.getMessage());
+ throw (TaskExecutionException)e.getCause();
+
+ } else {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+
} catch (final Exception e) {
log.warn("RestartAuthProzessManagement has an internal error", e);
throw new TaskExecutionException(pendingReq, e.getMessage(), e);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
index 14537d44..edca0fba 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
@@ -101,6 +101,7 @@ public class ProcessDefinitionParser {
// Standard implementation of XMLInputFactory seems not to be thread-safe
final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
reader = inputFactory.createXMLEventReader(processDefinitionInputStream);
final List<StartElement> transitionElements = new ArrayList<>();
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
index 9274ea81..6e83a201 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
@@ -21,15 +21,13 @@ package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.InputStream;
import java.io.Serializable;
+import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -51,14 +49,17 @@ import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessNode;
import at.gv.egiz.eaaf.core.impl.idp.process.model.StartEvent;
import at.gv.egiz.eaaf.core.impl.idp.process.model.TaskInfo;
import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+import lombok.extern.slf4j.Slf4j;
/**
* Process engine implementation allowing starting and continuing processes as
* well as providing means for cleanup actions.
*/
+@Slf4j
public class ProcessEngineImpl implements ProcessEngine {
- private final Logger log = LoggerFactory.getLogger(getClass());
+ private static final String ERROR_PROCESS_OBJECT_NOT_EXIST =
+ "Process instance: {0} does not exist for pendingReq: {0}";
@Autowired
ProcessInstanceStoreDao piStoreDao;
@@ -156,15 +157,16 @@ public class ProcessEngineImpl implements ProcessEngine {
if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
log.error("Pending-request with id:" + pendingReq.getPendingRequestId()
+ " includes NO 'ProcessInstanceId'");
- throw new ProcessExecutionException("Pending-request with id:"
- + pendingReq.getPendingRequestId() + " includes NO 'ProcessInstanceId'");
+ throw new ProcessExecutionException(MessageFormat.format(ERROR_PROCESS_OBJECT_NOT_EXIST,
+ pendingReq.getProcessInstanceId(), pendingReq.getPendingRequestId()));
+
}
final ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
if (pi == null) {
- throw new ProcessExecutionException(
- "Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
+ throw new ProcessExecutionException(MessageFormat.format(ERROR_PROCESS_OBJECT_NOT_EXIST,
+ pendingReq.getProcessInstanceId(), pendingReq.getPendingRequestId()));
}
@@ -449,11 +451,9 @@ public class ProcessEngineImpl implements ProcessEngine {
final ExecutionContext executionContext =
new ExecutionContextImpl(piStore.getProcessInstanceId());
-
- final Map<String, Serializable> executionContextData = piStore.getExecutionContextData();
- for (final Entry<String, Serializable> el : executionContextData.entrySet()) {
- executionContext.put(el.getKey(), el.getValue());
- }
+
+ piStore.getExecutionContextData().entrySet().stream().forEach(
+ el -> executionContext.put(el.getKey(), el.getValue()));
final ProcessInstance pi = new ProcessInstance(
processDefinitions.get(piStore.getProcessDefinitionId()), executionContext);
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java
index cca8872f..611572c0 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java
@@ -72,7 +72,7 @@ public class ProcessInstanceStoreDaoImpl implements ProcessInstanceStoreDao {
log.debug("Found process instance store for instance '{}'.", processInstanceId);
} else {
- log.debug("Unable to find process instance store for instance '{}'.", processInstanceId);
+ log.info("Unable to find process instance store for instance '{}'.", processInstanceId);
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DomUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DomUtils.java
index 01b063aa..4b8a7a04 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DomUtils.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DomUtils.java
@@ -33,6 +33,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
+import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -111,10 +112,10 @@ public class DomUtils {
private static final String EXTERNAL_NO_NAMESPACE_SCHEMA_LOCATION_PROPERTY =
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";
- private static final String EXTERNAL_GENERAL_ENTITIES_FEATURE =
+ public static final String EXTERNAL_GENERAL_ENTITIES_FEATURE =
"http://xml.org/sax/features/external-general-entities";
- private static final String EXTERNAL_PARAMETER_ENTITIES_FEATURE =
+ public static final String EXTERNAL_PARAMETER_ENTITIES_FEATURE =
"http://xml.org/sax/features/external-parameter-entities";
public static final String DISALLOW_DOCTYPE_FEATURE =
@@ -785,6 +786,7 @@ public class DomUtils {
throws TransformerException, IOException {
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
final Transformer transformer = transformerFactory.newTransformer();
final ByteArrayOutputStream bos = new ByteArrayOutputStream(16384);
@@ -1211,6 +1213,7 @@ public class DomUtils {
// StringWriter stringWriter = new StringWriter();
final Result result = new StreamResult(out);
final TransformerFactory factory = TransformerFactory.newInstance();
+ factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
final Transformer transformer = factory.newTransformer();
transformer.transform(source, result);
return out.toByteArray();