Example #1
0
 protected void doAuthorization(
     HttpClient httpclient, HttpMethod method, Map<String, Object> params) {
   if (type == null) {
     return;
   }
   String u = (String) params.get("Username");
   String p = (String) params.get("Password");
   if (u == null || p == null) {
     u = this.username;
     p = this.password;
   }
   if (u == null) {
     throw new IllegalArgumentException("Could not find username");
   }
   if (p == null) {
     throw new IllegalArgumentException("Could not find password");
   }
   if (type == AuthenticationType.BASIC) {
     httpclient
         .getState()
         .setCredentials(
             new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
             new UsernamePasswordCredentials(u, p));
     method.setDoAuthentication(true);
   } else if (type == AuthenticationType.FORM_BASED) {
     String authUrlStr = (String) params.get("AuthUrl");
     if (authUrlStr == null) {
       authUrlStr = authUrl;
     }
     if (authUrlStr == null) {
       throw new IllegalArgumentException("Could not find authentication url");
     }
     try {
       httpclient.executeMethod(method);
     } catch (IOException e) {
       throw new RuntimeException("Could not execute request for form-based authentication", e);
     } finally {
       method.releaseConnection();
     }
     PostMethod authMethod = new PostMethod(authUrlStr);
     NameValuePair[] data = {
       new NameValuePair("j_username", u), new NameValuePair("j_password", p)
     };
     authMethod.setRequestBody(data);
     try {
       httpclient.executeMethod(authMethod);
     } catch (IOException e) {
       throw new RuntimeException("Could not initialize form-based authentication", e);
     } finally {
       authMethod.releaseConnection();
     }
   } else {
     throw new RuntimeException("Unknown AuthenticationType " + type);
   }
 }
  protected boolean doRequestedAuthentication(
      HttpClient client, HttpMethod method, RenderRequest request, RenderResponse response) {
    if (super.doRequestedAuthentication(client, method, request, response)) {
      // already handled
      return true;
    }

    // System.out.println("SSOWebContentPortlet.doRequestedAuthentication...");

    if (method.getHostAuthState().getAuthScheme().getSchemeName().equals(BASIC_AUTH_SCHEME_NAME)) {
      // Basic authentication being requested
      String userName = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME);
      if (userName == null) userName = "";
      String password = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD);
      if (password == null) password = "";

      // System.out.println("...providing basic authentication with userName: "******", and
      // password: "******"SSOWebContentPortlent.doAuthenticate() - unexpected authentication scheme: "
              + method.getHostAuthState().getAuthScheme().getSchemeName());
    }

    // only know how to handle Basic authentication, in this context
    return false;
  }
 protected void applyAuthentication(HttpClient client, HttpMethod method) {
   if (credentials != null) {
     client.getState().setCredentials(realm, host, credentials);
     method.setDoAuthentication(true);
   }
 }
  /**
   * Makes a rest request of any type at the specified urlSuffix. The urlSuffix should be of the
   * form /userService/users. If CS throws an exception it handled and transalated to a Openfire
   * exception if possible. This is done using the check fault method that tries to throw the best
   * maching exception.
   *
   * @param type Must be GET or DELETE
   * @param urlSuffix The url suffix of the rest request
   * @param xmlParams The xml with the request params, must be null if type is GET or DELETE only
   * @return The response as a xml doc.
   * @throws ConnectionException Thrown if there are issues perfoming the request.
   * @throws Exception Thrown if the response from Clearspace contains an exception.
   */
  public Element executeRequest(HttpType type, String urlSuffix, String xmlParams)
      throws ConnectionException, Exception {
    if (Log.isDebugEnabled()) {
      Log.debug("Outgoing REST call [" + type + "] to " + urlSuffix + ": " + xmlParams);
    }

    String wsUrl = getConnectionURI() + WEBSERVICES_PATH + urlSuffix;

    String secret = getSharedSecret();

    HttpClient client = new HttpClient();
    HttpMethod method;

    // Configures the authentication
    client.getParams().setAuthenticationPreemptive(true);
    Credentials credentials = new UsernamePasswordCredentials(OPENFIRE_USERNAME, secret);
    AuthScope scope = new AuthScope(host, port, AuthScope.ANY_REALM);
    client.getState().setCredentials(scope, credentials);

    // Creates the method
    switch (type) {
      case GET:
        method = new GetMethod(wsUrl);
        break;
      case POST:
        PostMethod pm = new PostMethod(wsUrl);
        StringRequestEntity requestEntity = new StringRequestEntity(xmlParams);
        pm.setRequestEntity(requestEntity);
        method = pm;
        break;
      case PUT:
        PutMethod pm1 = new PutMethod(wsUrl);
        StringRequestEntity requestEntity1 = new StringRequestEntity(xmlParams);
        pm1.setRequestEntity(requestEntity1);
        method = pm1;
        break;
      case DELETE:
        method = new DeleteMethod(wsUrl);
        break;
      default:
        throw new IllegalArgumentException();
    }

    method.setRequestHeader("Accept", "text/xml");
    method.setDoAuthentication(true);

    try {
      // Executes the request
      client.executeMethod(method);

      // Parses the result
      String body = method.getResponseBodyAsString();
      if (Log.isDebugEnabled()) {
        Log.debug("Outgoing REST call results: " + body);
      }

      // Checks the http status
      if (method.getStatusCode() != 200) {
        if (method.getStatusCode() == 401) {
          throw new ConnectionException(
              "Invalid password to connect to Clearspace.",
              ConnectionException.ErrorType.AUTHENTICATION);
        } else if (method.getStatusCode() == 404) {
          throw new ConnectionException(
              "Web service not found in Clearspace.", ConnectionException.ErrorType.PAGE_NOT_FOUND);
        } else if (method.getStatusCode() == 503) {
          throw new ConnectionException(
              "Web service not avaible in Clearspace.",
              ConnectionException.ErrorType.SERVICE_NOT_AVAIBLE);
        } else {
          throw new ConnectionException(
              "Error connecting to Clearspace, http status code: " + method.getStatusCode(),
              new HTTPConnectionException(method.getStatusCode()),
              ConnectionException.ErrorType.OTHER);
        }
      } else if (body.contains("Clearspace Upgrade Console")) {
        // TODO Change CS to send a more standard error message
        throw new ConnectionException(
            "Clearspace is in an update state.", ConnectionException.ErrorType.UPDATE_STATE);
      }

      Element response = localParser.get().parseDocument(body).getRootElement();

      // Check for exceptions
      checkFault(response);

      // Since there is no exception, returns the response
      return response;
    } catch (DocumentException e) {
      throw new ConnectionException(
          "Error parsing the response of Clearspace.", e, ConnectionException.ErrorType.OTHER);
    } catch (HttpException e) {
      throw new ConnectionException(
          "Error performing http request to Clearspace", e, ConnectionException.ErrorType.OTHER);
    } catch (UnknownHostException e) {
      throw new ConnectionException(
          "Unknown Host " + getConnectionURI() + " trying to connect to Clearspace",
          e,
          ConnectionException.ErrorType.UNKNOWN_HOST);
    } catch (IOException e) {
      throw new ConnectionException(
          "Error peforming http request to Clearspace.", e, ConnectionException.ErrorType.OTHER);
    } finally {
      method.releaseConnection();
    }
  }
  protected byte[] doPreemptiveAuthentication(
      HttpClient client, HttpMethod method, RenderRequest request, RenderResponse response) {
    byte[] result = super.doPreemptiveAuthentication(client, method, request, response);
    if (result != null) {
      // already handled
      return result;
    }

    // System.out.println("SSOWebContentPortlet.doPreemptiveAuthentication...");

    PortletPreferences prefs = request.getPreferences();
    String type = getSingleSignOnAuthType(prefs);

    if (type.equalsIgnoreCase(SSO_TYPE_BASIC_PREEMPTIVE)) {
      // Preemptive, basic authentication
      String userName = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME);
      if (userName == null) userName = "";
      String password = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD);
      if (password == null) password = "";

      // System.out.println("...performing preemptive basic authentication with userName:
      // "+userName+", and password: "******"");
        if (formAction == null || formAction.length() == 0) {
          log.warn(
              "sso.type specified as 'form', but no: "
                  + SSO_TYPE_FORM_ACTION_URL
                  + ", action was specified - unable to preemptively authenticate by form.");
          return null;
        }
        String userNameField = prefs.getValue(SSO_TYPE_FORM_USERNAME_FIELD, "");
        if (userNameField == null || userNameField.length() == 0) {
          log.warn(
              "sso.type specified as 'form', but no: "
                  + SSO_TYPE_FORM_USERNAME_FIELD
                  + ", username field was specified - unable to preemptively authenticate by form.");
          return null;
        }
        String passwordField = prefs.getValue(SSO_TYPE_FORM_PASSWORD_FIELD, "password");
        if (passwordField == null || passwordField.length() == 0) {
          log.warn(
              "sso.type specified as 'form', but no: "
                  + SSO_TYPE_FORM_PASSWORD_FIELD
                  + ", password field was specified - unable to preemptively authenticate by form.");
          return null;
        }

        String userName = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME);
        if (userName == null) userName = "";
        String password = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD);
        if (password == null) password = "";

        // get submit method
        int i = type.indexOf('.');
        boolean isPost =
            i > 0
                ? type.substring(i + 1).equalsIgnoreCase("post")
                : true; // default to post, since it is a form

        // get parameter map
        HashMap formParams = new HashMap();
        formParams.put(userNameField, new String[] {userName});
        formParams.put(passwordField, new String[] {password});
        String formArgs = prefs.getValue(SSO_TYPE_FORM_ACTION_ARGS, "");
        if (formArgs != null && formArgs.length() > 0) {
          StringTokenizer iter = new StringTokenizer(formArgs, ";");
          while (iter.hasMoreTokens()) {
            String pair = iter.nextToken();
            i = pair.indexOf('=');
            if (i > 0) formParams.put(pair.substring(0, i), new String[] {pair.substring(i + 1)});
          }
        }

        // resuse client - in case new cookies get set - but create a new method (for the
        // formAction)
        String formMethod = (isPost) ? FORM_POST_METHOD : FORM_GET_METHOD;
        method =
            getHttpMethod(
                client,
                getURLSource(formAction, formParams, request, response),
                formParams,
                formMethod,
                request);
        // System.out.println("...posting credentials");
        result = doHttpWebContent(client, method, 0, request, response);
        // System.out.println("Result of attempted authorization: "+success);
        PortletMessaging.publish(request, FORM_AUTH_STATE, Boolean.valueOf(result != null));
        return result;
      } catch (Exception ex) {
        // bad
        log.error("Form-based authentication failed", ex);
      }
    } else if (type.equalsIgnoreCase(SSO_TYPE_URL) || type.equalsIgnoreCase(SSO_TYPE_URL_BASE64)) {
      // set user name and password parameters in the HttpMethod
      String userNameParam = prefs.getValue(SSO_TYPE_URL_USERNAME_PARAM, "");
      if (userNameParam == null || userNameParam.length() == 0) {
        log.warn(
            "sso.type specified as 'url', but no: "
                + SSO_TYPE_URL_USERNAME_PARAM
                + ", username parameter was specified - unable to preemptively authenticate by URL.");
        return null;
      }
      String passwordParam = prefs.getValue(SSO_TYPE_URL_PASSWORD_PARAM, "");
      if (passwordParam == null || passwordParam.length() == 0) {
        log.warn(
            "sso.type specified as 'url', but no: "
                + SSO_TYPE_URL_PASSWORD_PARAM
                + ", password parameter was specified - unable to preemptively authenticate by URL.");
        return null;
      }
      String userName = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME);
      if (userName == null) userName = "";
      String password = (String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD);
      if (password == null) password = "";
      if (type.equalsIgnoreCase(SSO_TYPE_URL_BASE64)) {
        Base64 encoder = new Base64();
        userName = new String(encoder.encode(userName.getBytes()));
        password = new String(encoder.encode(password.getBytes()));
      }

      // GET and POST accept args differently
      if (method instanceof PostMethod) {
        // add POST data
        PostMethod postMethod = (PostMethod) method;
        postMethod.addParameter(userNameParam, userName);
        postMethod.addParameter(passwordParam, password);
      } else {
        // augment GET query string
        NameValuePair[] authPairs =
            new NameValuePair[] {
              new NameValuePair(userNameParam, userName), new NameValuePair(passwordParam, password)
            };
        String existingQuery = method.getQueryString();
        method.setQueryString(authPairs);
        if (existingQuery != null && existingQuery.length() > 0) {
          // augment existing query with new auth query
          existingQuery = existingQuery + '&' + method.getQueryString();
          method.setQueryString(existingQuery);
        }
      }

      return result;
    }
    // else System.out.println("...sso.type: "+type+", no pre-emptive authentication");

    // not handled
    return null;
  }
  @Override
  public void executeMethod(final HttpMethod method, final ClientRequest cr) {
    final Map<String, Object> props = cr.getProperties();

    method.setDoAuthentication(true);

    final HttpMethodParams methodParams = method.getParams();

    // Set the handle cookies property
    if (!cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES)) {
      methodParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
    }

    // Set the interactive and credential provider properties
    if (cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_INTERACTIVE)) {
      CredentialsProvider provider =
          (CredentialsProvider) props.get(ApacheHttpClientConfig.PROPERTY_CREDENTIALS_PROVIDER);
      if (provider == null) {
        provider = DEFAULT_CREDENTIALS_PROVIDER;
      }
      methodParams.setParameter(CredentialsProvider.PROVIDER, provider);
    } else {
      methodParams.setParameter(CredentialsProvider.PROVIDER, null);
    }

    // Set the read timeout
    final Integer readTimeout = (Integer) props.get(ApacheHttpClientConfig.PROPERTY_READ_TIMEOUT);
    if (readTimeout != null) {
      methodParams.setSoTimeout(readTimeout);
    }

    if (method instanceof EntityEnclosingMethod) {
      final EntityEnclosingMethod entMethod = (EntityEnclosingMethod) method;

      if (cr.getEntity() != null) {
        final RequestEntityWriter re = getRequestEntityWriter(cr);
        final Integer chunkedEncodingSize =
            (Integer) props.get(ApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE);
        if (chunkedEncodingSize != null) {
          // There doesn't seems to be a way to set the chunk size.
          entMethod.setContentChunked(true);

          // It is not possible for a MessageBodyWriter to modify
          // the set of headers before writing out any bytes to
          // the OutputStream
          // This makes it impossible to use the multipart
          // writer that modifies the content type to add a boundary
          // parameter
          writeOutBoundHeaders(cr.getHeaders(), method);

          // Do not buffer the request entity when chunked encoding is
          // set
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return false;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  re.writeRequestEntity(out);
                }

                @Override
                public long getContentLength() {
                  return re.getSize();
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });

        } else {
          entMethod.setContentChunked(false);

          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try {
            re.writeRequestEntity(
                new CommittingOutputStream(baos) {

                  @Override
                  protected void commit() throws IOException {
                    writeOutBoundHeaders(cr.getMetadata(), method);
                  }
                });
          } catch (IOException ex) {
            throw new ClientHandlerException(ex);
          }

          final byte[] content = baos.toByteArray();
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return true;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  out.write(content);
                }

                @Override
                public long getContentLength() {
                  return content.length;
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });
        }
      }
    } else {
      writeOutBoundHeaders(cr.getHeaders(), method);

      // Follow redirects
      method.setFollowRedirects(
          cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_FOLLOW_REDIRECTS));
    }
    try {
      httpClient.executeMethod(
          getHostConfiguration(httpClient, props), method, getHttpState(props));
    } catch (Exception e) {
      method.releaseConnection();
      throw new ClientHandlerException(e);
    }
  }
  protected byte[] URLtoByteArray(
      String location,
      Http.Method method,
      Map<String, String> headers,
      Cookie[] cookies,
      Http.Auth auth,
      Http.Body body,
      List<Http.FilePart> fileParts,
      Map<String, String> parts,
      Http.Response response,
      boolean followRedirects)
      throws IOException {

    byte[] bytes = null;

    HttpMethod httpMethod = null;
    HttpState httpState = null;

    try {
      _cookies.set(null);

      if (location == null) {
        return null;
      } else if (!location.startsWith(Http.HTTP_WITH_SLASH)
          && !location.startsWith(Http.HTTPS_WITH_SLASH)) {

        location = Http.HTTP_WITH_SLASH + location;
      }

      HostConfiguration hostConfiguration = getHostConfiguration(location);

      HttpClient httpClient = getClient(hostConfiguration);

      if (method.equals(Http.Method.POST) || method.equals(Http.Method.PUT)) {

        if (method.equals(Http.Method.POST)) {
          httpMethod = new PostMethod(location);
        } else {
          httpMethod = new PutMethod(location);
        }

        if (body != null) {
          RequestEntity requestEntity =
              new StringRequestEntity(body.getContent(), body.getContentType(), body.getCharset());

          EntityEnclosingMethod entityEnclosingMethod = (EntityEnclosingMethod) httpMethod;

          entityEnclosingMethod.setRequestEntity(requestEntity);
        } else if (method.equals(Http.Method.POST)) {
          PostMethod postMethod = (PostMethod) httpMethod;

          processPostMethod(postMethod, fileParts, parts);
        }
      } else if (method.equals(Http.Method.DELETE)) {
        httpMethod = new DeleteMethod(location);
      } else if (method.equals(Http.Method.HEAD)) {
        httpMethod = new HeadMethod(location);
      } else {
        httpMethod = new GetMethod(location);
      }

      if (headers != null) {
        for (Map.Entry<String, String> header : headers.entrySet()) {
          httpMethod.addRequestHeader(header.getKey(), header.getValue());
        }
      }

      if ((method.equals(Http.Method.POST) || method.equals(Http.Method.PUT))
          && ((body != null)
              || ((fileParts != null) && !fileParts.isEmpty())
                  | ((parts != null) && !parts.isEmpty()))) {
      } else if (!hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
        httpMethod.addRequestHeader(
            HttpHeaders.CONTENT_TYPE, ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED);
      }

      if (!hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
        httpMethod.addRequestHeader(HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
      }

      httpState = new HttpState();

      if ((cookies != null) && (cookies.length > 0)) {
        org.apache.commons.httpclient.Cookie[] commonsCookies = toCommonsCookies(cookies);

        httpState.addCookies(commonsCookies);

        HttpMethodParams httpMethodParams = httpMethod.getParams();

        httpMethodParams.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
      }

      if (auth != null) {
        httpMethod.setDoAuthentication(true);

        httpState.setCredentials(
            new AuthScope(auth.getHost(), auth.getPort(), auth.getRealm()),
            new UsernamePasswordCredentials(auth.getUsername(), auth.getPassword()));
      }

      proxifyState(httpState, hostConfiguration);

      httpClient.executeMethod(hostConfiguration, httpMethod, httpState);

      Header locationHeader = httpMethod.getResponseHeader("location");

      if ((locationHeader != null) && !locationHeader.equals(location)) {
        String redirect = locationHeader.getValue();

        if (followRedirects) {
          return URLtoByteArray(
              redirect,
              Http.Method.GET,
              headers,
              cookies,
              auth,
              body,
              fileParts,
              parts,
              response,
              followRedirects);
        } else {
          response.setRedirect(redirect);
        }
      }

      InputStream inputStream = httpMethod.getResponseBodyAsStream();

      if (inputStream != null) {
        Header contentLength = httpMethod.getResponseHeader(HttpHeaders.CONTENT_LENGTH);

        if (contentLength != null) {
          response.setContentLength(GetterUtil.getInteger(contentLength.getValue()));
        }

        Header contentType = httpMethod.getResponseHeader(HttpHeaders.CONTENT_TYPE);

        if (contentType != null) {
          response.setContentType(contentType.getValue());
        }

        bytes = FileUtil.getBytes(inputStream);
      }

      for (Header header : httpMethod.getResponseHeaders()) {
        response.addHeader(header.getName(), header.getValue());
      }

      return bytes;
    } finally {
      try {
        if (httpState != null) {
          _cookies.set(toServletCookies(httpState.getCookies()));
        }
      } catch (Exception e) {
        _log.error(e, e);
      }

      try {
        if (httpMethod != null) {
          httpMethod.releaseConnection();
        }
      } catch (Exception e) {
        _log.error(e, e);
      }
    }
  }