/******************************************************************************* *******************************************************************************/ 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; } }