aboutsummaryrefslogtreecommitdiff
path: root/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java
diff options
context:
space:
mode:
Diffstat (limited to 'id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java')
-rw-r--r--id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java821
1 files changed, 0 insertions, 821 deletions
diff --git a/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java b/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java
deleted file mode 100644
index ff0f3a171..000000000
--- a/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java
+++ /dev/null
@@ -1,821 +0,0 @@
-package at.gv.egovernment.moa.id.proxy.servlet;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.net.ssl.SSLSocketFactory;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import at.gv.egovernment.moa.id.AuthenticationException;
-import at.gv.egovernment.moa.id.BuildException;
-import at.gv.egovernment.moa.id.MOAIDException;
-import at.gv.egovernment.moa.id.ParseException;
-import at.gv.egovernment.moa.id.ServiceException;
-import at.gv.egovernment.moa.id.config.ConfigurationException;
-import at.gv.egovernment.moa.id.config.ConnectionParameter;
-import at.gv.egovernment.moa.id.config.proxy.ProxyConfigurationProvider;
-import at.gv.egovernment.moa.id.config.proxy.OAConfiguration;
-import at.gv.egovernment.moa.id.config.proxy.OAProxyParameter;
-import at.gv.egovernment.moa.id.data.AuthenticationData;
-import at.gv.egovernment.moa.id.data.CookieManager;
-import at.gv.egovernment.moa.id.proxy.ConnectionBuilder;
-import at.gv.egovernment.moa.id.proxy.ConnectionBuilderFactory;
-import at.gv.egovernment.moa.id.proxy.LoginParameterResolver;
-import at.gv.egovernment.moa.id.proxy.LoginParameterResolverException;
-import at.gv.egovernment.moa.id.proxy.LoginParameterResolverFactory;
-import at.gv.egovernment.moa.id.proxy.MOAIDProxyInitializer;
-import at.gv.egovernment.moa.id.proxy.NotAllowedException;
-import at.gv.egovernment.moa.id.proxy.invoke.GetAuthenticationDataInvoker;
-import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
-import at.gv.egovernment.moa.id.util.SSLUtils;
-import at.gv.egovernment.moa.logging.Logger;
-import at.gv.egovernment.moa.util.Base64Utils;
-
-/**
- * Servlet requested for logging in at an online application,
- * and then for proxying requests to the online application.
- * @author Paul Ivancsics
- * @version $Id$
- */
-public class ProxyServlet extends HttpServlet {
- /** Name of the Parameter for the Target */
- private static final String PARAM_TARGET = "Target";
- /** Name of the Parameter for the SAMLArtifact */
- private static final String PARAM_SAMLARTIFACT = "SAMLArtifact";
-
- /** Name of the Attribute for the PublicURLPrefix */
- private static final String ATT_PUBLIC_URLPREFIX = "PublicURLPrefix";
- /** Name of the Attribute for the RealURLPrefix */
- private static final String ATT_REAL_URLPREFIX = "RealURLPrefix";
- /** Name of the Attribute for the SSLSocketFactory */
- private static final String ATT_SSL_SOCKET_FACTORY = "SSLSocketFactory";
- /** Name of the Attribute for the LoginHeaders */
- private static final String ATT_LOGIN_HEADERS = "LoginHeaders";
- /** Name of the Attribute for the LoginParameters */
- private static final String ATT_LOGIN_PARAMETERS = "LoginParameters";
- /** Name of the Attribute for the SAMLARTIFACT */
- private static final String ATT_SAML_ARTIFACT = "SamlArtifact";
- /** Name of the Attribute for the state of the browser request for login dialog*/
- private static final String ATT_BROWSERREQU = "BrowserLoginRequest";
- /** Name of the Attribute for the state of the browser request for login dialog*/
- private static final String ATT_OA_CONF = "oaConf";
- /** Name of the Attribute for the Logintype of the OnlineApplication*/
- private static final String ATT_OA_LOGINTYPE = "LoginType";
- /** Name of the Attribute for the number of the try to login into the OnlineApplication*/
- private static final String ATT_OA_LOGINTRY = "LoginTry";
- /** Maximum permitted login tries */
- private static final int MAX_OA_LOGINTRY = 3;
- /** Name of the Attribute for authorization value for further connections*/
- private static final String ATT_OA_AUTHORIZATION_HEADER = "authorizationkey";
- /** Name of the Attribute for user binding */
- private static final String ATT_OA_USER_BINDING = "UserBinding";
- /** For extended internal debug messages */
- private static final boolean INTERNAL_DEBUG = false;
- /** Message to be given if browser login failed */
- private static final String RET_401_MSG = "<html><head><title>Ein Fehler ist aufgetreten</title></head><body><h1>Fehler bei der Anmeldung</h1><p>Bei der Anmeldung ist ein Fehler aufgetreten.</p><p>Fehler bei der Anmeldung. <br>Pr&uuml;fen Sie bitte ihre Berechtigung.<br><b>Abbruch durch den Benutzer.</b><br></p></body></html>";
-
- /**
- * @see javax.servlet.http.HttpServlet#service(HttpServletRequest, HttpServletResponse)
- */
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- Logger.debug("getRequestURL:" + req.getRequestURL().toString());
- try {
- if (req.getParameter(PARAM_SAMLARTIFACT) != null) {
- // check if SAML Artifact was already used in this session (in case of page reload)
- HttpSession session = req.getSession();
- if (null != session && req.getParameter(PARAM_SAMLARTIFACT).equals(session.getAttribute(ATT_SAML_ARTIFACT))) {
- if (session.getAttribute(ATT_BROWSERREQU)==null) {
- tunnelRequest(req, resp);
- }else{
- login(req, resp); //login after browser login dialog
- }
- } else
- // it is the first time that the SAML Artifact was used
- login(req, resp);
- }
- else
- tunnelRequest(req, resp);
- }
- catch (MOAIDException ex) {
- handleError(ex.getMessage(), ex, req, resp);
- }
- catch (Throwable ex) {
- handleError(ex.getMessage(), ex, req, resp);
- }
- }
-
- /**
- * Login to online application at first call of servlet for a user session.<br/>
- * <ul>
- * <li>Acquires authentication data from the MOA-ID Auth component.</li>
- * <li>Reads configuration data for the online application.</li>
- * <li>Resolves login parameters.</li>
- * <li>Sets up an SSLSocketFactory in case of a secure connection to the online application.</li>
- * <li>For a stateless online application, stores data in the HttpSession.</li>
- * <li>Tunnels the request to the online application.</li>
- * </ul>
- * @param req
- * @param resp
- * @throws ConfigurationException when wrong configuration is encountered
- * @throws ProxyException when wrong configuration is encountered
- * @throws BuildException while building the request for MOA-ID Auth
- * @throws ServiceException while invoking MOA-ID Auth
- * @throws ParseException while parsing the response from MOA-ID Auth
- */
- private void login(HttpServletRequest req, HttpServletResponse resp) throws ConfigurationException, ProxyException, BuildException, ServiceException, ParseException, AuthenticationException {
-
- HttpSession session = req.getSession();
- String samlArtifact = "";
- Map loginHeaders = null;
- Map loginParameters = null;
- String publicURLPrefix = "";
- String realURLPrefix = "";
- SSLSocketFactory ssf = null;
- String urlRequested = req.getRequestURL().toString();
- OAConfiguration oaConf = null;
- String loginType = "";
- String binding = "";
-
- if (session.getAttribute(ATT_BROWSERREQU)==null) {
-
- samlArtifact = req.getParameter(PARAM_SAMLARTIFACT);
- Logger.debug("moa-id-proxy login " + PARAM_SAMLARTIFACT + ": " + samlArtifact);
- // String target = req.getParameter(PARAM_TARGET); parameter given but not processed
- // boolean targetprovided = req.getParameter(PARAM_TARGET) != null;
-
- // get authentication data from the MOA-ID Auth component
- AuthenticationData authData;
- try {
- authData = new GetAuthenticationDataInvoker().getAuthenticationData(samlArtifact);
- } catch (ServiceException ex) {
- throw new ProxyException("proxy.14", new Object[] {ex.getMessage()}, ex);
- } catch (ProxyException ex) {
- throw new ProxyException("proxy.14", new Object[] {ex.getMessage()}, ex);
- }
-
- // read configuration data
- ProxyConfigurationProvider proxyConf = ProxyConfigurationProvider.getInstance();
- OAProxyParameter oaParam = proxyConf.getOnlineApplicationParameter(urlRequested);
- if (oaParam == null) {
- throw new ProxyException("proxy.02", new Object[] { urlRequested });
- }
- publicURLPrefix = oaParam.getPublicURLPrefix();
- Logger.debug("OA: " + publicURLPrefix);
- oaConf = oaParam.getOaConfiguration();
- ConnectionParameter oaConnParam = oaParam.getConnectionParameter();
- realURLPrefix = oaConnParam.getUrl();
-
- // resolve login parameters to be forwarded to online application
- LoginParameterResolver lpr = LoginParameterResolverFactory.getLoginParameterResolver(publicURLPrefix);
- String clientIPAddress = req.getRemoteAddr();
- boolean businessService = oaParam.getBusinessService();
- try {
- if (oaConf.getAuthType().equals(OAConfiguration.PARAM_AUTH)) {
- loginParameters = lpr.getAuthenticationParameters(oaConf, authData, clientIPAddress, businessService, publicURLPrefix);
- } else {
- loginHeaders = lpr.getAuthenticationHeaders(oaConf, authData, clientIPAddress, businessService, publicURLPrefix);
- for (Iterator iter = loginHeaders.keySet().iterator(); iter.hasNext();) {
- //extract user-defined bindingValue
- String headerKey = (String) iter.next();
- String headerKeyValue = (String) loginHeaders.get(headerKey);
- if (headerKey.equalsIgnoreCase("binding")) {
- binding = (String) loginHeaders.get(headerKey);
- }
- for (int i = 1; i <= 3; i++) {
- if (headerKey.equalsIgnoreCase("param" + i)) {
- int sep = headerKeyValue.indexOf("=");
- if (sep>-1) {
- if (sep>0) {
- String value = "";
- if (headerKeyValue.length()>sep+1) value = headerKeyValue.substring(sep+1);
- if (loginParameters == null) loginParameters = new HashMap();
- loginParameters.put(headerKeyValue.substring(0,sep) , value);
- }
- } else {
- loginParameters.put(headerKey, "");
- }
- }
- }
- }
- loginHeaders.remove("binding");
- loginHeaders.remove("param1");
- loginHeaders.remove("param2");
- loginHeaders.remove("param3");
- }
- } catch (LoginParameterResolverException ex) {
- throw new ProxyException("proxy.13", new Object[] { publicURLPrefix });
- } catch (NotAllowedException e) {
- throw new ProxyException("proxy.15", new Object[] { });
- }
-
- // setup SSLSocketFactory for communication with the online application
- if (oaConnParam.isHTTPSURL()) {
- try {
- ssf = SSLUtils.getSSLSocketFactory(proxyConf, oaConnParam);
- } catch (Throwable ex) {
- throw new ProxyException(
- "proxy.05",
- new Object[] { oaConnParam.getUrl(), ex.toString()},
- ex);
- }
- }
-
- // for stateless online application, store data in HttpSession
- loginType = oaConf.getLoginType();
- if ("".equalsIgnoreCase(binding)) {
- binding = oaConf.getBinding();
- if ("".equalsIgnoreCase(binding)) binding = "full";
- }
- Logger.debug("Login type: " + loginType);
- if (loginType.equals(OAConfiguration.LOGINTYPE_STATELESS)) {
- int sessionTimeOut = oaParam.getSessionTimeOut();
- if (sessionTimeOut == 0)
- sessionTimeOut = 60 * 60; // default 1 h
-
- session.setMaxInactiveInterval(sessionTimeOut);
- session.setAttribute(ATT_PUBLIC_URLPREFIX, publicURLPrefix);
- session.setAttribute(ATT_REAL_URLPREFIX, realURLPrefix);
- session.setAttribute(ATT_SSL_SOCKET_FACTORY, ssf);
- session.setAttribute(ATT_LOGIN_HEADERS, loginHeaders);
- session.setAttribute(ATT_LOGIN_PARAMETERS, loginParameters);
- session.setAttribute(ATT_SAML_ARTIFACT, samlArtifact);
- session.setAttribute(ATT_OA_CONF, oaConf);
- session.setAttribute(ATT_OA_LOGINTYPE, loginType);
- session.setAttribute(ATT_OA_USER_BINDING, binding);
- session.removeAttribute(ATT_BROWSERREQU);
- session.removeAttribute(ATT_OA_AUTHORIZATION_HEADER);
- session.removeAttribute(ATT_OA_LOGINTRY);
- Logger.debug("moa-id-proxy: HTTPSession " + session.getId() + " angelegt");
- }
-
- } else {
- loginHeaders = (Map) session.getAttribute(ATT_LOGIN_HEADERS);
- publicURLPrefix = (String) session.getAttribute(ATT_PUBLIC_URLPREFIX);
- realURLPrefix = (String) session.getAttribute(ATT_REAL_URLPREFIX);
- ssf = (SSLSocketFactory) session.getAttribute(ATT_SSL_SOCKET_FACTORY);
- loginHeaders = (Map) session.getAttribute(ATT_LOGIN_HEADERS);
- loginParameters = (Map) session.getAttribute(ATT_LOGIN_PARAMETERS);
- samlArtifact = (String) session.getAttribute(ATT_SAML_ARTIFACT);
- oaConf = (OAConfiguration) session.getAttribute(ATT_OA_CONF);
- loginType = (String) session.getAttribute(ATT_OA_LOGINTYPE);
- binding = (String) session.getAttribute(ATT_OA_USER_BINDING);
- session.removeAttribute(ATT_BROWSERREQU);
- Logger.debug("moa-id-proxy: HTTPSession " + session.getId() + " aufgenommen");
- }
-
- try {
- int respcode = 0;
-
- // tunnel request to the online application
- respcode = tunnelRequest(req, resp, loginHeaders, loginParameters, publicURLPrefix, realURLPrefix, ssf, binding);
- if (respcode == 401) {
- if (OAConfiguration.BINDUNG_FULL.equals(binding) && oaConf.getLoginType().equals(OAConfiguration.LOGINTYPE_STATELESS)) {
- throw new ProxyException("proxy.12", new Object[] { realURLPrefix });
- }
- }
- } catch (ProxyException ex) {
- throw new ProxyException("proxy.12", new Object[] { realURLPrefix });
- } catch (Throwable ex) {
- throw new ProxyException("proxy.04", new Object[] { urlRequested, ex.toString()}, ex);
- }
- }
-
- /**
- * Tunnels a request to the stateless online application using data stored in the HTTP session.
- * @param req HTTP request
- * @param resp HTTP response
- * @throws IOException if an I/O error occurs
- */
- private void tunnelRequest(HttpServletRequest req, HttpServletResponse resp) throws ProxyException, IOException {
-
- //Logger.debug("Tunnel request (stateless)");
- HttpSession session = req.getSession(false);
-
- if (session == null)
- throw new ProxyException("proxy.07", null);
- String publicURLPrefix = (String) session.getAttribute(ATT_PUBLIC_URLPREFIX);
- //A session is automatically created when forwarded 1st time to errorpage-proxy.jsp (with the handleError method)
- //additional check if publicURLPrefix is OK, if not throw an Exception
- if (publicURLPrefix == null)
- throw new ProxyException("proxy.07", null);
-
- String realURLPrefix = (String) session.getAttribute(ATT_REAL_URLPREFIX);
- SSLSocketFactory ssf = (SSLSocketFactory) session.getAttribute(ATT_SSL_SOCKET_FACTORY);
- Map loginHeaders = (Map) session.getAttribute(ATT_LOGIN_HEADERS);
- Map loginParameters = (Map) session.getAttribute(ATT_LOGIN_PARAMETERS);
- String binding = (String) session.getAttribute(ATT_OA_USER_BINDING);
- if (publicURLPrefix == null || realURLPrefix == null)
- throw new ProxyException("proxy.08", new Object[] { req.getRequestURL().toString()});
-
- int respcode = tunnelRequest(req, resp, loginHeaders, loginParameters, publicURLPrefix, realURLPrefix, ssf, binding);
- if (respcode == -401) // #tries to login exceeded
- throw new ProxyException("proxy.16", new Object[] {realURLPrefix, Integer.toString(MAX_OA_LOGINTRY)});
- }
-
-/**
- * Tunnels a request to the online application using given URL mapping and SSLSocketFactory.
- * This method returns the ResponseCode of the request to the online application.
- * @param req HTTP request
- * @param resp HTTP response
- * @param loginHeaders header field/values to be inserted for purposes of authentication;
- * may be <code>null</code>
- * @param loginParameters parameter name/values to be inserted for purposes of authentication;
- * may be <code>null</code>
- * @param publicURLPrefix prefix of request URL to be substituted for the <code>realURLPrefix</code>
- * @param realURLPrefix prefix of online application URL to substitute the <code>publicURLPrefix</code>
- * @param ssf SSLSocketFactory to use
- * @throws IOException if an I/O error occurs
- */
-private int tunnelRequest(HttpServletRequest req, HttpServletResponse resp, Map loginHeaders, Map loginParameters, String publicURLPrefix, String realURLPrefix, SSLSocketFactory ssf, String binding)
- throws IOException {
-
- String browserUserID = "";
- String browserPassword = "";
- //URL url = new URL(realURLPrefix);
- //String realURLHost = url.getHost();
- if (INTERNAL_DEBUG && !binding.equals("")) Logger.debug("Binding: " + binding);
-
- // collect headers from request
- Map headers = new HashMap();
- for (Enumeration enu = req.getHeaderNames(); enu.hasMoreElements();) {
- String headerKey = (String) enu.nextElement();
- String headerKeyValue = req.getHeader(headerKey);
- if (INTERNAL_DEBUG) Logger.debug("Incoming:" + headerKey + "=" + headerKeyValue);
- //Analyze Basic-Auth-Headers from the client
- if (headerKey.equalsIgnoreCase("Authorization")) {
- if (headerKeyValue.substring(0,6).equalsIgnoreCase("Basic ")) {
- String credentials = headerKeyValue.substring(6);
- byte [] bplaintextcredentials = Base64Utils. decode(credentials, true);
- String plaintextcredentials = new String(bplaintextcredentials);
- browserUserID = plaintextcredentials.substring(0,plaintextcredentials.indexOf(":"));
- browserPassword = plaintextcredentials.substring(plaintextcredentials.indexOf(":")+1);
- //Logger.debug("Analyzing authorization-header from browser: " + headerKeyValue + "gives UN:PW=" + browserUserID + ":" + browserPassword );
- }
- if (headerKeyValue.substring(0,9).equalsIgnoreCase("Negotiate")) {
- //Logger.debug("Analyzing authorization-header from browser: Found NTLM Aut.: " + headerKeyValue + "gives UN:PW=" + browserUserID + ":" + browserPassword );
- }
- }
- else
- {
- /* Headers MUST NOT be repaced according to our Spec.
- if (headerKey.equalsIgnoreCase("Host")) {
- headerKeyValue = realURLHost;
- //headerKeyValue= realURLPrefix.substring(hoststartpos);
- if (INTERNAL_DEBUG) Logger.debug("replaced:" + headerKey + "=" + headerKeyValue);
- }
- */
- headers.put(headerKey, headerKeyValue);
- }
- }
-
- // collect login headers, possibly overwriting headers from request
- String authorizationvalue="";
- if (req.getSession().getAttribute(ATT_OA_AUTHORIZATION_HEADER)==null) {
-
- //we have a connection with not having logged on
- if (loginHeaders != null && (browserPassword.length()!=0 || browserUserID.length()!=0 || OAConfiguration.BINDUNG_FULL.equals(binding))) {
- for (Iterator iter = loginHeaders.keySet().iterator(); iter.hasNext();) {
- String headerKey = (String) iter.next();
- String headerKeyValue = (String) loginHeaders.get(headerKey);
- //customize loginheaders if necessary
- if (isBasicAuthenticationHeader(headerKey, headerKeyValue))
- {
- if ( OAConfiguration.BINDUNG_FULL.equals(binding)) {
- authorizationvalue = headerKeyValue;
- Logger.debug("Binding: full binding to user established");
- } else {
- String credentials = headerKeyValue.substring(6);
- byte [] bplaintextcredentials = Base64Utils.decode(credentials, true);
- String plaintextcredentials = new String(bplaintextcredentials);
- String userID = plaintextcredentials.substring(0,plaintextcredentials.indexOf(":"));
- String password = plaintextcredentials.substring(plaintextcredentials.indexOf(":")+1);
- String userIDPassword = ":";
- if (OAConfiguration.BINDUNG_USERNAME.equals(binding)) {
- Logger.debug("Binding: Access with necessary binding to user");
- userIDPassword = userID + ":" + browserPassword;
- } else if (OAConfiguration.BINDUNG_NONE.equals(binding)) {
- Logger.debug("Binding: Access without binding to user");
- //If first time
- if (browserUserID.length()==0) browserUserID = userID;
- if (browserPassword.length()==0) browserPassword = password;
- userIDPassword = browserUserID + ":" + browserPassword;
- } else {
- userIDPassword = userID + ":" + password;
- }
- credentials = Base64Utils.encode(userIDPassword.getBytes());
- authorizationvalue = "Basic " + credentials;
- headerKeyValue = authorizationvalue;
- }
- }
- headers.put(headerKey, headerKeyValue);
- }
- }
- }else{
- //if OA needs Authorization header in each further request
- authorizationvalue = (String) req.getSession().getAttribute(ATT_OA_AUTHORIZATION_HEADER);
- if (loginHeaders != null) headers.put("Authorization", authorizationvalue);
- }
-
-
- Vector parameters = new Vector();
-
- for (Enumeration enu = req.getParameterNames(); enu.hasMoreElements();) {
- String paramName = (String) enu.nextElement();
- if (!(paramName.equals(PARAM_SAMLARTIFACT) || paramName.equals(PARAM_TARGET))) {
- if (INTERNAL_DEBUG) Logger.debug("Req Parameter-put: " + paramName + ":" + req.getParameter(paramName));
- String parameter[] = new String[2];
- parameter[0]= paramName;
- parameter[1]= req.getParameter(paramName);
- parameters.add(parameter);
- }
- }
- // collect login parameters, possibly overwriting parameters from request
- if (loginParameters != null) {
- for (Iterator iter = loginParameters.keySet().iterator(); iter.hasNext();) {
- String paramName = (String) iter.next();
- if (!(paramName.equals(PARAM_SAMLARTIFACT) || paramName.equals(PARAM_TARGET))) {
- if (INTERNAL_DEBUG) Logger.debug("Req Login-Parameter-put: " + paramName + ":" + loginParameters.get(paramName));
- String parameter[] = new String[2];
- parameter[0]= paramName;
- parameter[1]= (String) loginParameters.get(paramName);
- parameters.add(parameter);
- }
- }
- }
-
- ConnectionBuilder cb = ConnectionBuilderFactory.getConnectionBuilder(publicURLPrefix);
- HttpURLConnection conn = cb.buildConnection(req, publicURLPrefix, realURLPrefix, ssf, parameters);
-
- // set headers as request properties of URLConnection
- for (Iterator iter = headers.keySet().iterator(); iter.hasNext();) {
- String headerKey = (String) iter.next();
- String headerValue = (String) headers.get(headerKey);
- String LogStr = "Req header " + headerKey + ": " + headers.get(headerKey);
- if (isBasicAuthenticationHeader(headerKey, headerValue)) {
- String credentials = headerValue.substring(6);
- byte [] bplaintextcredentials = Base64Utils. decode(credentials, true);
- String plaintextcredentials = new String(bplaintextcredentials);
- String uid = plaintextcredentials.substring(0,plaintextcredentials.indexOf(":"));
- String pwd = plaintextcredentials.substring(plaintextcredentials.indexOf(":")+1);
- //Sollte AuthorizationInfo vom HTTPClient benutzt werden: cb.addBasicAuthorization(publicURLPrefix, uid, pwd);
- //if (Logger.isDebugEnabled()) LogStr = LogStr + " >UserID:Password< >" + uid + ":" + pwd + "<";
- }
- conn.setRequestProperty(headerKey, headerValue);
- if (INTERNAL_DEBUG) Logger.debug(LogStr);
- }
-
- StringWriter sb = new StringWriter();
-
- // Write out parameters into output stream of URLConnection.
- // On GET request, do not send parameters in any case,
- // otherwise HttpURLConnection would send a POST.
- if (!"get".equalsIgnoreCase(req.getMethod()) && !parameters.isEmpty()) {
- boolean firstParam = true;
- String parameter[] = new String[2];
- for (Iterator iter = parameters.iterator(); iter.hasNext();) {
- parameter = (String[]) iter.next();
- String paramName = parameter[0];
- String paramValue = parameter[1];
- if (firstParam)
- firstParam = false;
- else
- sb.write("&");
- sb.write(paramName);
- sb.write("=");
- sb.write(paramValue);
- if (INTERNAL_DEBUG) Logger.debug("Req param " + paramName + ": " + paramValue);
- }
- }
-
- // For WebDAV and POST: copy content
- if (!"get".equalsIgnoreCase(req.getMethod())) {
- if (INTERNAL_DEBUG && !"post".equalsIgnoreCase(req.getMethod())) Logger.debug("---- WEBDAV ---- copying content");
- try {
- OutputStream out = conn.getOutputStream();
- InputStream in = req.getInputStream();
- if (!parameters.isEmpty()) out.write(sb.toString().getBytes()); //Parameter nicht mehr mittels Printwriter schreiben
- copyStream(in, out, null, req.getMethod());
- out.flush();
- out.close();
- } catch (IOException e) {
- if (!"post".equalsIgnoreCase(req.getMethod()))
- Logger.debug("---- WEBDAV ---- streamcopy problem");
- else
- Logger.debug("---- POST ---- streamcopy problem");
- }
- }
-
- // connect
- conn.connect();
-
- // check login tries
- if (conn.getResponseCode()==HttpURLConnection.HTTP_UNAUTHORIZED) {
- String oa_loginTry = (String) req.getSession().getAttribute(ATT_OA_LOGINTRY);
- int loginTry = 1;
- if (oa_loginTry!=null) loginTry = Integer.parseInt(oa_loginTry)+1;
- req.getSession().setAttribute(ATT_OA_LOGINTRY, Integer.toString(loginTry));
- if (loginTry > MAX_OA_LOGINTRY) {
- Logger.debug("Found 401 UNAUTHORIZED, maximum tries exceeded; leaving...");
- cb.disconnect(conn);
- return -401;
- }
- }
-
-
-
- if (conn.getResponseCode()==HttpURLConnection.HTTP_UNAUTHORIZED && OAConfiguration.BINDUNG_FULL.equals(binding)) {
- Logger.debug("Found 401 UNAUTHORIZED, leaving...");
- cb.disconnect(conn);
- return conn.getResponseCode();
- }
-
-
- resp.setStatus(conn.getResponseCode());
- resp.setContentType(conn.getContentType());
-
- if (loginHeaders != null && (conn.getResponseCode()==HttpURLConnection.HTTP_OK || conn.getResponseCode()==HttpURLConnection.HTTP_MOVED_TEMP) && req.getSession().getAttribute(ATT_OA_AUTHORIZATION_HEADER)==null) {
- req.getSession().setAttribute(ATT_OA_AUTHORIZATION_HEADER, authorizationvalue);
- Logger.debug("Login OK. Saving authorization header to remember in further requests");
- }
-
- // Read response headers
- // Omit response header "content-length" if response header "Transfer-encoding: chunked" is set.
- // Otherwise, the connection will not be kept alive, resulting in subsequent missing requests.
- // See JavaDoc of javax.servlet.http.HttpServlet:
- // When using HTTP 1.1 chunked encoding (which means that the response has a Transfer-Encoding header), do not set the Content-Length header.
- Vector respHeaders = new Vector();
-
- boolean chunked = false;
- String contentLengthKey = null;
- String transferEncodingKey = null;
- int i = 1;
- String headerKey;
- String loginType = (String) req.getSession().getAttribute(ATT_OA_LOGINTYPE);
- while ((headerKey = conn.getHeaderFieldKey(i)) != null) {
- String headerValue = conn.getHeaderField(i);
- // Überschrift im Browser-Passworteingabedialog setzen (sonst ist der reale host eingetragen)
- if (headerKey.equalsIgnoreCase("WWW-Authenticate") && headerValue.startsWith("Basic realm=\"")) {
- headerValue = "Basic realm=\"" + publicURLPrefix + "\"";
- if (OAConfiguration.BINDUNG_USERNAME.equals(binding)) headerValue = "Basic realm=\"Bitte Passwort eingeben\"";
- if (OAConfiguration.BINDUNG_NONE.equals(binding)) headerValue = "Basic realm=\"Bitte Benutzername und Passwort eingeben\"";
- }
- String respHeader[] = new String[2];
- if ((conn.getResponseCode()==HttpURLConnection.HTTP_UNAUTHORIZED) && headerKey.equalsIgnoreCase("content-length")) {
- //alter the unauthorized message with template for login
- //TODO: supply a special login form on unauthorized messages with bindings!=full
- headerValue = Integer.toString(RET_401_MSG.length());
- }
- respHeader[0]= headerKey;
- respHeader[1]= headerValue;
-
- if (!(OAConfiguration.BINDUNG_FULL.equals(binding) && OAConfiguration.LOGINTYPE_STATELESS.equals(loginType) && headerKey.equalsIgnoreCase("WWW-Authenticate") && headerValue.startsWith("Basic realm=\""))) {
- respHeaders.add(respHeader);
- if (INTERNAL_DEBUG) Logger.debug("Resp header " + headerKey + ": " + headerValue);
- } else {
- Logger.debug("Resp header ---REMOVED--- " + headerKey + ": " + headerValue);
- }
- if (isTransferEncodingChunkedHeader(headerKey, headerValue)) {
- chunked = true;
- transferEncodingKey = headerKey;
- }
- if ("content-length".equalsIgnoreCase(headerKey))
- contentLengthKey = headerKey;
- i++;
- }
- if (chunked && contentLengthKey != null) {
- respHeaders.remove(transferEncodingKey);
- Logger.debug("Resp header " + transferEncodingKey + " REMOVED");
- }
-
- String headerValue;
- String respHeader[] = new String[2];
-
- //write out all Responseheaders
- for (Iterator iter = respHeaders.iterator(); iter.hasNext();) {
- respHeader = (String[]) iter.next();
- headerKey = respHeader[0];
- headerValue = respHeader[1];
- resp.addHeader(headerKey, headerValue);
- }
-
- //Logger.debug(">>>> Copy Content");
- //Logger.debug(" from ()" + conn.getURL());
- //Logger.debug(" to (" + req.getRemoteAddr() + ":"+ ") " +req.getRequestURL());
-
- // read response stream
- Logger.debug("Resp from " + conn.getURL().toString() + ": status " + conn.getResponseCode());
- // Load content unless the server lets us know that the content is NOT MODIFIED...
- if (conn.getResponseCode()!=HttpURLConnection.HTTP_NOT_MODIFIED ) {
- BufferedInputStream respIn = new BufferedInputStream(conn.getInputStream());
- //Logger.debug("Got Inputstream");
- BufferedOutputStream respOut = new BufferedOutputStream(resp.getOutputStream());
- //Logger.debug("Got Outputstream");
-
- byte [] buffer = new byte[4096];
- if (respOut != null) {
- int bytesRead;
- while ((bytesRead = respIn.read(buffer)) >= 0) {
- if (conn.getResponseCode()!=HttpURLConnection.HTTP_UNAUTHORIZED) respOut.write(buffer, 0, bytesRead);
- }
- } else {
- while (respIn.read(buffer) >= 0);
- }
-
-
- /*
- int ch;
- StringBuffer strBuf = new StringBuffer("");
- while ((ch = respIn.read()) >= 0) {
- if (conn.getResponseCode()!=HttpURLConnection.HTTP_UNAUTHORIZED) respOut.write(ch);
- strBuf.append((char)ch);
- }
- Logger.debug("Resp Content:");
- if (strBuf.toString().length()>500)
- Logger.debug(strBuf.toString().substring(0,500));
- else
- Logger.debug(strBuf.toString());
- */
-
-
- if (conn.getResponseCode()==HttpURLConnection.HTTP_UNAUTHORIZED) {
- respOut.write(RET_401_MSG.getBytes());
- }
- respOut.flush();
- respOut.close();
- respIn.close();
- if (conn.getResponseCode()==HttpURLConnection.HTTP_UNAUTHORIZED) {
- Logger.debug("Found 401 UNAUTHORIZED...");
- cb.disconnect(conn);
- return conn.getResponseCode();
- }
- } else {
- //if (conn.getResponseCode()==HttpURLConnection.HTTP_NOT_MODIFIED)
- Logger.debug("Found 304 NOT MODIFIED...");
- }
-
- cb.disconnect(conn);
- Logger.debug("Request done");
-
- return conn.getResponseCode();
-}
-/**
- * Determines whether a HTTP header is a basic authentication header of the kind "Authorization: Basic ..."
- *
- * @param headerKey header name
- * @param headerValue header value
- * @return true for a basic authentication header
- */
-private boolean isBasicAuthenticationHeader(String headerKey, String headerValue) {
- if (!"authorization".equalsIgnoreCase(headerKey))
- return false;
- if (headerValue.length() < "basic".length())
- return false;
- String authenticationSchema = headerValue.substring(0, "basic".length());
- return "basic".equalsIgnoreCase(authenticationSchema);
-}
-/**
- * Determines whether a basic authentication header of the kind "Authorization: Basic ..."
- * is included in a HTTP request
- * @param req HTTP request
- * @return true for a basic authentication header provided
- */
-private boolean isBasicAuthenticationHeaderProvided(HttpServletRequest req) {
- for (Enumeration enu = req.getHeaderNames(); enu.hasMoreElements();) {
- String headerKey = (String) enu.nextElement();
- String headerValue = req.getHeader(headerKey);
- if (isBasicAuthenticationHeader(headerKey, headerValue))
- return true;
- }
- return false;
-}
-/**
- * Determines whether a HTTP header is "Transfer-encoding" header with value containing "chunked"
- *
- * @param headerKey header name
- * @param headerValue header value
- * @return true for a "Transfer-encoding: chunked" header
- */
-private boolean isTransferEncodingChunkedHeader(String headerKey, String headerValue) {
- if (!"transfer-encoding".equalsIgnoreCase(headerKey))
- return false;
- return headerValue.indexOf("chunked") >= 0 || headerValue.indexOf("Chunked") >= 0 || headerValue.indexOf("CHUNKED") >= 0;
-}
-
-/**
- * Calls the web application initializer.
- *
- * @see javax.servlet.Servlet#init(ServletConfig)
- */
-public void init(ServletConfig servletConfig) throws ServletException {
- super.init(servletConfig);
- try {
- MOAIDProxyInitializer.initialize();
- Logger.info(MOAIDMessageProvider.getInstance().getMessage("proxy.00", null));
- }
- catch (Exception ex) {
- Logger.fatal(MOAIDMessageProvider.getInstance().getMessage("proxy.06", null), ex);
- throw new ServletException(ex);
- }
-}
-
-/**
- * Handles an error. <br>
- * <ul>
- * <li>Logs the error</li>
- * <li>Places error message and exception thrown into the request
- * as request attributes (to be used by <code>"/errorpage-proxy.jsp"</code>)</li>
- * <li>Sets HTTP status 500 (internal server error)</li>
- * </ul>
- *
- * @param errorMessage error message
- * @param exceptionThrown exception thrown
- * @param req servlet request
- * @param resp servlet response
- */
-protected void handleError(
- String errorMessage, Throwable exceptionThrown, HttpServletRequest req, HttpServletResponse resp) {
-
-
- if(null != errorMessage) {
- Logger.error(errorMessage);
- req.setAttribute("ErrorMessage", errorMessage );
- }
-
- if (null != exceptionThrown) {
- if(null == errorMessage) errorMessage = exceptionThrown.getMessage();
- Logger.error(errorMessage, exceptionThrown);
- //req.setAttribute("ExceptionThrown", exceptionThrown);
- }
-
- //forward this to errorpage-proxy.jsp where the HTML error page is generated
- ServletContext context = getServletContext();
- RequestDispatcher dispatcher = context.getRequestDispatcher("/errorpage-proxy.jsp");
- try {
- dispatcher.forward(req, resp);
- } catch (ServletException e) {
- Logger.error(e);
- } catch (IOException e) {
- Logger.error(e);
- }
-
-}
-
-
-// * taken from iaik.utils.util.copyStream:
-/**
- * Reads all data (until EOF is reached) from the given source to the
- * destination stream. If the destination stream is null, all data is dropped.
- * It uses the given buffer to read data and forward it. If the buffer is
- * null, this method allocates a buffer.
- *
- * @param source The stream providing the data.
- * @param destination The stream that takes the data. If this is null, all
- * data from source will be read and discarded.
- * @param buffer The buffer to use for forwarding. If it is null, the method
- * allocates a buffer.
- * @exception IOException If reading from the source or writing to the
- * destination fails.
- */
-private static void copyStream(InputStream source, OutputStream destination, byte[] buffer, String method) throws IOException {
- if (source == null) {
- throw new NullPointerException("Argument \"source\" must not be null.");
- }
- if (buffer == null) {
- buffer = new byte[4096];
- }
-
- if (destination != null) {
- int bytesRead;
- while ((bytesRead = source.read(buffer)) >= 0) {
- destination.write(buffer, 0, bytesRead);
- //if (method.equalsIgnoreCase("POST")) Logger.debug(buffer.toString());
- }
- } else {
- while (source.read(buffer) >= 0);
- }
-}
-
-
-}