From bee5dd259a4438d45ecd1bcc26dfba12875236d6 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 26 Jun 2018 11:03:48 +0200 Subject: initial commit --- .../idp/auth/modules/AbstractAuthServletTask.java | 220 +++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java') 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 new file mode 100644 index 00000000..a421ff67 --- /dev/null +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/modules/AbstractAuthServletTask.java @@ -0,0 +1,220 @@ +/******************************************************************************* + *******************************************************************************/ +package at.gv.egiz.eaaf.core.impl.idp.auth.modules; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang3.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.IRequestStorage; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +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.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractAuthProtocolModulController; +import at.gv.egiz.eaaf.core.impl.idp.process.springweb.AbstractTask; +import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder; + +/** + * Task based counterpart to {@link AuthServlet}, providing the same utility methods (error handling, parameter parsing + * etc.).

The code has been taken from {@link AuthServlet}. + */ +public abstract class AbstractAuthServletTask extends AbstractTask { + private static final Logger log = LoggerFactory.getLogger(AbstractAuthServletTask.class); + + @Autowired(required=true) protected IRequestStorage requestStoreage; + @Autowired(required=true) protected IConfiguration authConfig; + + @Autowired protected IRevisionLogger revisionsLogger; + + protected static final String ERROR_CODE_PARAM = "errorid"; + + protected IRequest pendingReq = null; + + public abstract void execute(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) throws TaskExecutionException; + + + protected final IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) throws TaskExecutionException { + //set pending-request object + this.pendingReq = pendingReq; + + //execute task specific action + execute(executionContext, request, response); + + //return pending-request object + return this.pendingReq; + } + + /** + * Redirect the authentication process to protocol specific finalization endpoint. + * + * @param pendingReq Actually processed protocol specific authentication request + * @param httpResp + */ + protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) { + performRedirectToItself(pendingReq, httpResp, AbstractAuthProtocolModulController.ENDPOINT_FINALIZEPROTOCOL); + + } + + /** + * Redirect the authentication process to IDP itself + * + * @param pendingReq Actually processed protocol specific authentication request + * @param httpResp + * @param idpEndPoint Servlet EndPoint that should receive the redirect + */ + protected void performRedirectToItself(IRequest pendingReq, HttpServletResponse httpResp, String idpEndPoint) { + String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), + idpEndPoint, pendingReq.getPendingRequestId()); + + httpResp.setContentType("text/html"); + httpResp.setStatus(302); + httpResp.addHeader("Location", redirectURL); + log.debug("REDIRECT TO: " + redirectURL); + + } + + + /** + * Parses the request input stream for parameters, assuming parameters are + * encoded UTF-8 (no standard exists how browsers should encode them). + * + * @param req + * servlet request + * + * @return mapping parameter name -> value + * + * @throws IOException + * if parsing request parameters fails. + * + * @throws FileUploadException + * if parsing request parameters fails. + */ + protected Map getParameters(HttpServletRequest req) throws IOException, + FileUploadException { + + Map parameters = new HashMap(); + + if (ServletFileUpload.isMultipartContent(req)) { + // request is encoded as mulitpart/form-data + 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); + 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"); + + // TODO use RegExp + String startS = ""; + String endS = "urn:publicid:gv.at:baseid"; + String logWithMaskedBaseid = logString; + int start = logString.indexOf(startS); + if (start > -1) { + int end = logString.indexOf(endS); + if (end > -1) { + logWithMaskedBaseid = logString.substring(0, start); + logWithMaskedBaseid += startS; + logWithMaskedBaseid += "xxxxxxxxxxxxxxxxxxxxxxxx"; + logWithMaskedBaseid += logString.substring(end, + logString.length()); + } + } + + log.debug("Processed multipart/form-data request parameter: \nName: " + + item.getFieldName() + + "\nValue: " + + logWithMaskedBaseid); + } + + } + } + } + + else { + Iterator> requestParamIt = req.getParameterMap().entrySet().iterator(); + while (requestParamIt.hasNext()) { + Entry entry = requestParamIt.next(); + String key = entry.getKey(); + String[] values = entry.getValue(); + // take the last value from the value array since the legacy code above also does it this way + parameters.put(key, ArrayUtils.isEmpty(values) ? null : values[values.length-1]); + } + + } + + return parameters; + } + + /** + * Reads bytes up to a delimiter, consuming the delimiter. + * + * @param in + * input stream + * @param delimiter + * delimiter character + * @return String constructed from the read bytes + * @throws IOException + */ + protected String readBytesUpTo(InputStream in, char delimiter) + throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + boolean done = false; + int b; + while (!done && (b = in.read()) >= 0) { + if (b == delimiter) + done = true; + else + bout.write(b); + } + return bout.toString(); + } + + /** + * Adds a parameter to a URL. + * + * @param url + * the URL + * @param paramname + * parameter name + * @param paramvalue + * parameter value + * @return the URL with parameter added + */ + protected static String addURLParameter(String url, String paramname, + String paramvalue) { + String param = paramname + "=" + paramvalue; + if (url.indexOf("?") < 0) + return url + "?" + param; + else + return url + "&" + param; + } +} -- cgit v1.2.3