diff options
Diffstat (limited to 'eaaf_core/src/main')
9 files changed, 182 insertions, 108 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IPendingRequestIdGenerationStrategy.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IPendingRequestIdGenerationStrategy.java index 443404eb..b0507042 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IPendingRequestIdGenerationStrategy.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IPendingRequestIdGenerationStrategy.java @@ -27,5 +27,15 @@ public interface IPendingRequestIdGenerationStrategy { @NonNull public String validateAndGetPendingRequestId(@Nullable String pendingReqId) throws PendingReqIdValidationException; + /** + * Get the internal pendingReqId without any validation + * + * @param pendingReqId pending-request Id that should be validated + * @return internalPendingRequestId + * @throws PendingReqIdValidationException + */ + @NonNull + public String getPendingRequestIdWithOutChecks(@Nullable String externalPendingReqId) throws PendingReqIdValidationException; + } 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 2115d9b0..2b0cbab3 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 @@ -98,7 +98,7 @@ public class RequestStorage implements IRequestStorage{ if (pendingRequest instanceof IRequest) { try { //validate pending-requestId - final String internalPendingRequestId = pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(pendingRequest.getPendingRequestId()); + final String internalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId()); //store pending request transactionStorage.put(internalPendingRequestId, pendingRequest, -1); @@ -128,7 +128,7 @@ public class RequestStorage implements IRequestStorage{ if (pendingReqID != null) { String internalPendingReqId = null; try { - internalPendingReqId = pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(pendingReqID); + internalPendingReqId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingReqID); } catch (final PendingReqIdValidationException e) { internalPendingReqId = e.getInvalidInternalPendingReqId(); @@ -170,7 +170,7 @@ public class RequestStorage implements IRequestStorage{ String newInternalPendingRequestId = null; try { - newInternalPendingRequestId = pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(newRequestID); + newInternalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(newRequestID); } catch (final PendingReqIdValidationException e) { throw new EAAFException("internal.99", new Object[]{"Generate invalid pendingRequestId. Something looks WRONG"}, e); 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 eb87e893..5027a84b 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 @@ -52,8 +52,10 @@ import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.IRequestStorage; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController; import at.gv.egiz.eaaf.core.impl.idp.process.springweb.AbstractTask; @@ -66,6 +68,7 @@ import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder; public abstract class AbstractAuthServletTask extends AbstractTask { private static final Logger log = LoggerFactory.getLogger(AbstractAuthServletTask.class); + @Autowired(required=true) IProtocolAuthenticationService protAuchService; @Autowired(required=true) protected IRequestStorage requestStoreage; @Autowired(required=true) protected IConfiguration authConfig; @@ -75,10 +78,12 @@ public abstract class AbstractAuthServletTask extends AbstractTask { protected IRequest pendingReq = null; + @Override public abstract void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException; + @Override protected final IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { //set pending-request object @@ -96,12 +101,28 @@ public abstract class AbstractAuthServletTask extends AbstractTask { /** * Redirect the authentication process to protocol specific finalization endpoint. + * @param executionContext * * @param pendingReq Actually processed protocol specific authentication request * @param httpResp + * @throws IOException + * @throws EAAFException */ - protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) { - performRedirectToItself(pendingReq, httpResp, ProtocolFinalizationController.ENDPOINT_FINALIZEPROTOCOL); + protected void performRedirectToProtocolFinialization(ExecutionContext executionContext, IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp) throws EAAFException, IOException { + final Object frontChannelRedirectFlagObj = executionContext.get(EAAFConstants.PROCESS_ENGINE_REQUIRES_NO_POSTAUTH_REDIRECT); + if (frontChannelRedirectFlagObj != null && frontChannelRedirectFlagObj instanceof Boolean && + (Boolean)frontChannelRedirectFlagObj) { + log.info("AuthProcess finished. Forward to Protocol finalization."); + protAuchService.finalizeAuthentication(httpReq, httpResp, pendingReq); + + } else { + log.info("AuthProcess finished. Redirect to Protocol Dispatcher."); + requestStoreage.storePendingRequest(pendingReq); + performRedirectToItself(pendingReq, httpResp, ProtocolFinalizationController.ENDPOINT_FINALIZEPROTOCOL); + + } + + } @@ -113,7 +134,7 @@ public abstract class AbstractAuthServletTask extends AbstractTask { * @param idpEndPoint Servlet EndPoint that should receive the redirect */ protected void performRedirectToItself(IRequest pendingReq, HttpServletResponse httpResp, String idpEndPoint) { - String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), + final String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), idpEndPoint, pendingReq.getPendingRequestId()); httpResp.setContentType("text/html"); @@ -142,32 +163,32 @@ public abstract class AbstractAuthServletTask extends AbstractTask { protected Map<String, String> getParameters(HttpServletRequest req) throws IOException, FileUploadException { - Map<String, String> parameters = new HashMap<String, String>(); + final Map<String, String> parameters = new HashMap<String, String>(); if (ServletFileUpload.isMultipartContent(req)) { // request is encoded as mulitpart/form-data - FileItemFactory factory = new DiskFileItemFactory(); + final FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = null; upload = new ServletFileUpload(factory); List items = null; items = upload.parseRequest(req); for (int i = 0; i < items.size(); i++) { - FileItem item = (FileItem) items.get(i); + final FileItem item = (FileItem) items.get(i); if (item.isFormField()) { // Process only form fields - no file upload items parameters.put(item.getFieldName(), item.getString("UTF-8")); //log requests on trace if (log.isTraceEnabled()) { - String logString = item.getString("UTF-8"); + final String logString = item.getString("UTF-8"); // TODO use RegExp - String startS = "<pr:Identification><pr:Value>"; - String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>"; + final String startS = "<pr:Identification><pr:Value>"; + final String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>"; String logWithMaskedBaseid = logString; - int start = logString.indexOf(startS); + final int start = logString.indexOf(startS); if (start > -1) { - int end = logString.indexOf(endS); + final int end = logString.indexOf(endS); if (end > -1) { logWithMaskedBaseid = logString.substring(0, start); logWithMaskedBaseid += startS; @@ -188,11 +209,11 @@ public abstract class AbstractAuthServletTask extends AbstractTask { } else { - Iterator<Entry<String, String[]>> requestParamIt = req.getParameterMap().entrySet().iterator(); + final Iterator<Entry<String, String[]>> requestParamIt = req.getParameterMap().entrySet().iterator(); while (requestParamIt.hasNext()) { - Entry<String, String[]> entry = requestParamIt.next(); - String key = entry.getKey(); - String[] values = entry.getValue(); + final Entry<String, String[]> entry = requestParamIt.next(); + final String key = entry.getKey(); + final String[] values = entry.getValue(); // take the last value from the value array since the legacy code above also does it this way parameters.put(key, ArrayUtils.isEmpty(values) ? null : values[values.length-1]); } @@ -214,7 +235,7 @@ public abstract class AbstractAuthServletTask extends AbstractTask { */ protected String readBytesUpTo(InputStream in, char delimiter) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); boolean done = false; int b; while (!done && (b = in.read()) >= 0) { @@ -239,7 +260,7 @@ public abstract class AbstractAuthServletTask extends AbstractTask { */ protected static String addURLParameter(String url, String paramname, String paramvalue) { - String param = paramname + "=" + paramvalue; + final String param = paramname + "=" + paramvalue; if (url.indexOf("?") < 0) return url + "?" + param; else 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 4edde029..7d3ca2f8 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 @@ -381,7 +381,7 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer // HTTPUtils.extractAuthURLFromRequest(req), // DefaultGUIFormBuilderConfiguration.VIEW_ERRORMESSAGE, // null); - + //add errorcode and errormessage if (config instanceof ModifyableGuiBuilderConfiguration) { ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorMsg", msg); diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java index 5667fad7..f037f4ab 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java @@ -35,13 +35,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import javax.naming.ConfigurationException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; @@ -96,14 +96,37 @@ public abstract class RequestImpl implements IRequest, Serializable{ private final Map<String, Object> genericDataStorage = new HashMap<String, Object>(); + /** + * Initialize this pendingRequest object + * + * @param req {@link HttpServletRequest} + * @param authConfig {@link IConfiguration} + * @throws EAAFException + * + */ + public final void initialize(HttpServletRequest req, IConfiguration authConfig) throws EAAFException { + initialize(req, authConfig, null); + + } /** - * @throws ConfigurationException + * Initialize this pendingRequest object + * + * @param req {@link HttpServletRequest} + * @param authConfig {@link IConfiguration} + * @param transactionId transactionId that should be used in this pendingRequest for logging. If 'null' a new one will be generated + * + * @throws EAAFException * */ - public final void initialize(HttpServletRequest req, IConfiguration authConfig) throws EAAFException { + public final void initialize(@NonNull HttpServletRequest req, @NonNull IConfiguration authConfig, @Nullable String transactionId) throws EAAFException { + //use external transactionId or create new one if empty or null + if (StringUtils.isNotEmpty(transactionId)) + uniqueTransactionIdentifer = transactionId; + else + uniqueTransactionIdentifer = Random.nextLongRandom(); + //set unique transaction identifier for logging - uniqueTransactionIdentifer = Random.nextLongRandom(); TransactionIDUtils.setTransactionId(uniqueTransactionIdentifer); //initialize session object diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java index eff6b631..b12a69b2 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/FinalizeAuthenticationTask.java @@ -26,20 +26,15 @@ *******************************************************************************/ package at.gv.egiz.eaaf.core.impl.idp.controller.tasks; -import java.io.Serializable; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cglib.proxy.Dispatcher; import org.springframework.stereotype.Component; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager; -import at.gv.egiz.eaaf.core.api.idp.auth.services.IProtocolAuthenticationService; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; @@ -53,9 +48,7 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; public class FinalizeAuthenticationTask extends AbstractAuthServletTask { private static final Logger log = LoggerFactory.getLogger(FinalizeAuthenticationTask.class); - - @Autowired(required=true) IProtocolAuthenticationService protAuchService; - + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @@ -68,25 +61,13 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask { //set pending request to authenticated pendingReq.setAuthenticated(true); revisionsLogger.logEvent(pendingReq, IAuthenticationManager.EVENT_AUTHENTICATION_PROCESS_FINISHED); + performRedirectToProtocolFinialization(executionContext, pendingReq, request, response); - - Object frontChannelRedirectFlagObj = executionContext.get(EAAFConstants.PROCESS_ENGINE_REQUIRES_NO_POSTAUTH_REDIRECT); - if (frontChannelRedirectFlagObj != null && frontChannelRedirectFlagObj instanceof Boolean && - (Boolean)frontChannelRedirectFlagObj) { - log.info("AuthProcess finished. Forward to Protocol finalization."); - protAuchService.finalizeAuthentication(request, response, pendingReq); - - } else { - log.info("AuthProcess finished. Redirect to Protocol Dispatcher."); - requestStoreage.storePendingRequest(pendingReq); - performRedirectToProtocolFinialization(pendingReq, response); - - } - - } catch (EAAFException e) { + + } catch (final EAAFException e) { throw new TaskExecutionException(pendingReq, e.getMessage(), e); - } catch (Exception e) { + } catch (final Exception e) { log.warn("FinalizeAuthenticationTask 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/controller/tasks/RestartAuthProzessManagement.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/tasks/RestartAuthProzessManagement.java index 7ecc7425..1e5b63a2 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 @@ -65,13 +65,13 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask { if (this.pendingReq.isAbortedByUser()) { log.debug("AuthProcess was stopped. Forward to finalization ... "); - performRedirectToProtocolFinialization(pendingReq, response); + performRedirectToProtocolFinialization(executionContext, pendingReq, request, response); } else { //create a new execution context and copy all elements to new context - ExecutionContext newec = new ExecutionContextImpl(); - Set<String> entries = executionContext.keySet(); - for (String key : entries) { + final ExecutionContext newec = new ExecutionContextImpl(); + final Set<String> entries = executionContext.keySet(); + for (final String key : entries) { newec.put(key, executionContext.get(key)); } @@ -79,13 +79,13 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask { log.debug("Select new auth.-process and restart restart process-engine ... "); // select and create new process instance - String processDefinitionId = ModuleRegistration.getInstance().selectProcess(newec); + final String processDefinitionId = ModuleRegistration.getInstance().selectProcess(newec); if (processDefinitionId == null) { log.warn("No suitable authentication process found for SessionID " + pendingReq.getPendingRequestId()); throw new EAAFException("process.02", new Object[] { pendingReq.getPendingRequestId()}); } - String processInstanceId = processEngine.createProcessInstance(processDefinitionId, newec); + final String processInstanceId = processEngine.createProcessInstance(processDefinitionId, newec); // keep process instance id in moa session ((RequestImpl)pendingReq).setProcessInstanceId(processInstanceId); @@ -94,7 +94,7 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask { try { requestStoreage.storePendingRequest(pendingReq); - } catch (EAAFException e) { + } catch (final EAAFException e) { log.error("Database Error! MOASession is not stored!"); throw new EAAFException("internal.02", null); @@ -107,10 +107,10 @@ public class RestartAuthProzessManagement extends AbstractAuthServletTask { } - } catch (EAAFException e) { + } catch (final EAAFException e) { throw new TaskExecutionException(pendingReq, e.getMessage(), e); - } catch (Exception 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/utils/SecurePendingRequestIdGenerationStrategy.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java index 0daa0eb7..f0ef9b38 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java @@ -22,6 +22,8 @@ import org.joda.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; @@ -30,7 +32,12 @@ import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.core.exceptions.EAAFIllegalStateException; import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; - +/** + * PendingRequestId generation strategy based on signed tokens that facilitates extended token validation + * + * @author tlenz + * + */ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy { private static final Logger log = LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class); @@ -72,56 +79,43 @@ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequest } @Override - public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException { - log.trace("RAW external pendingReqId: {}", externalPendingReqId); + public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException { + final String[] tokenElements = extractTokens(externalPendingReqId); + return tokenElements[1]; + } + + @Override + public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException { try { - final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId); - - if (externalPendingReqIdBytes.length > maxPendingReqIdSize) { - log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize); - throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize); - - } - - final String stringToken = new String(externalPendingReqIdBytes); - if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) { - final String[] tokenElements = StringUtils.split(stringToken, - TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS); - - final String internalPendingReqId = tokenElements[1]; - final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]); + final String[] tokenElements = extractTokens(externalPendingReqId); + final String internalPendingReqId = tokenElements[1]; + final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]); - log.trace("Checking HMAC from externalPendingReqId ... "); - final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]); - final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp)); - if (!Arrays.equals(tokenDigest, refDigist)) { - log.warn("Digest of Token does NOT match"); - log.debug("Token: {} | Ref: {}", tokenDigest, refDigist); - throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match"); - - } - log.debug("PendingRequestId HMAC digest check successful"); - - log.trace("Checking valid period ... "); - final DateTime now = DateTime.now(); - if (timeStamp.withFieldAdded( - DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) { - log.warn("Token exceeds the valid period"); - log.debug("Token: {} | Now: {}", timeStamp, now ); - throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period"); - - } - log.debug("Token valid-period check successful"); + log.trace("Checking HMAC from externalPendingReqId ... "); + final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]); + final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp)); + if (!Arrays.equals(tokenDigest, refDigist)) { + log.warn("Digest of Token does NOT match"); + log.debug("Token: {} | Ref: {}", tokenDigest, refDigist); + throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match"); + + } + log.debug("PendingRequestId HMAC digest check successful"); + + log.trace("Checking valid period ... "); + final DateTime now = DateTime.now(); + if (timeStamp.withFieldAdded( + DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) { + log.warn("Token exceeds the valid period"); + log.debug("Token: {} | Now: {}", timeStamp, now ); + throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period"); - return internalPendingReqId; - - } else { - log.warn("PendingRequestId has an unvalid format"); - log.debug("PendingRequestId: {}", stringToken); - throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format"); - } + log.debug("Token valid-period check successful"); + + return internalPendingReqId; + } catch (final IllegalArgumentException | EAAFIllegalStateException e) { log.warn("Token is NOT a valid String. Msg: {}", e.getMessage()); @@ -131,6 +125,38 @@ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequest } } + @NonNull + private String[] extractTokens(@Nullable String externalPendingReqId) throws PendingReqIdValidationException { + if (StringUtils.isEmpty(externalPendingReqId)) { + log.info("PendingReqId is 'null' or empty"); + throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty"); + + } + + log.trace("RAW external pendingReqId: {}", externalPendingReqId); + final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId); + + if (externalPendingReqIdBytes.length > maxPendingReqIdSize) { + log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize); + throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize); + + } + + final String stringToken = new String(externalPendingReqIdBytes); + if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) { + final String[] tokenElements = StringUtils.split(stringToken, + TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS); + return tokenElements; + + } else { + log.warn("PendingRequestId has an unvalid format"); + log.debug("PendingRequestId: {}", stringToken); + throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format"); + + } + + } + @PostConstruct private void initialize() throws EAAFConfigurationException { diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java index 59da3d06..6b8fe9b7 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java @@ -5,6 +5,12 @@ import org.apache.commons.lang3.StringUtils; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; +/** + * Simple pendingRequestId generation strategy that facilitates no extended validation + * + * @author tlenz + * + */ public class SimplePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy { @Override @@ -15,11 +21,18 @@ public class SimplePendingRequestIdGenerationStrategy implements IPendingRequest @Override public String validateAndGetPendingRequestId(String pendingReqId) throws PendingReqIdValidationException { - if (StringUtils.isEmpty(pendingReqId)) - throw new PendingReqIdValidationException(pendingReqId, "PendingRequestId is empty or null"); - - return pendingReqId; + return getPendingRequestIdWithOutChecks(pendingReqId); } + @Override + public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException { + if (StringUtils.isEmpty(externalPendingReqId)) + throw new PendingReqIdValidationException(externalPendingReqId, "PendingRequestId is empty or null"); + + + + return externalPendingReqId; + } + } |