IP range to whitelist for serverless requests

Hi team!

I was made aware by marketplace support that If I use a third party lib for API call, the range IP to whitelist will not be static as specified on the doc:

But I can’t make use of the SDK Request Method because the third party API makes use of cookies for login and requests and I need to post files - and this is not supported by SDK Request Method.

Do you see someway to overcome this? I mean, I need to pass to the customer a IP range for them whitelist in their servers.

1 Like

Hi @samuelpares,

Right now we don’t have support upload file using SDK request method.

But here i have one doubt, even if SDK support the feature, how do you fetch the third party cookie and send it to SDK request method? browser won’t allow you to fetch third party site cookies using javascript due to security concern. Can u please explain your usecase?

4 Likes

Hi @Gopinath_Radhakrishn!

I’m integrating with IBM Rational Team Concert. Up until now, it was running in company intranet. So they will expose it to the internet now, and for security reasons, they want to allow requests from internet only when made by the APP in developing.

The IBM RTC provides OSLC APIs:
https://www.ibm.com/docs/en/rational-change/5.3.0?topic=change-using-oslc-cm-rest-api

To make calls to any endpoint, I need to make a post for login first:

You can see that it returns a cookie.
I need to pass it along on the next calls:

If I was going to use Request Method from SDK, I don’t know if I would be able to just capture it from the login header and pass it along in the next call. Since I need to send files, I didn’t even tried.
So for requests I’m using the lib: “postman-request”: “2.88.1-postman.28”.
On serverless, I have a class with methods to authenticate and to call others endpoints.
It works just fine.
Example:

var cookies;
var baseRequest;

class RTC {
  constructor(serverURI, userName, userPassword, _cookies) {
    try {
      this.serverURI = "https://" + serverURI + "/ccm";
      this.userName = userName;
      this.userPassword = userPassword;

      if (_cookies) {
        if (this.serverURI.includes("localhost")) {
          cookies = new tough.CookieJar(undefined, [{ rejectPublicSuffixes: false }]);
        } else {
          cookies = new tough.CookieJar();
        }
        for (const cookie of _cookies.cookies) {
          cookies.setCookieSync(tough.fromJSON(cookie), this.serverURI);
        }
      } else {
        cookies = new tough.CookieJar();
      }

      baseRequest = request.defaults({
        headers: {
          "OSLC-Core-Version": "2.0",
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        strictSSL: false,
        jar: cookies,
        followAllRedirects: true,
      });
    } catch (error) {
      console.error("Erro em RTC > constructor().", error);
    }
  }

  authenticate() {
    return new Promise((resolve, reject) => {
      try {
        var options = {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          url: this.serverURI + "/j_security_check",
          method: "POST",
          form: { j_username: this.userName, j_password: this.userPassword },
          resolveWithFullResponse: true,
        };

        baseRequest(options, function (error, response) {
          try {
            if (error) {
              reject({ status: response.statusCode, message: JSON.stringify(error) });
              return;
            }
            if (response.headers["x-com-ibm-team-repository-web-auth-msg"]) {
              reject({
                status: response.statusCode,
                message: response.headers["x-com-ibm-team-repository-web-auth-msg"],
              });
              return;
            }

            resolve(cookies);
          } catch (error) {
            reject({ message: error.message });
          }
        });
      } catch (error) {
        reject({ message: error.message });
      }
    });
  }

  getResourceName(resourceURL) {
    return new Promise((resolve, reject) => {
      try {
        var options = {
          method: "GET",
          url: resourceURL,
        };
        baseRequest(options, function (error, response) {
          try {
            if (error) {
              reject(error);
              return;
            }

            var body = JSON.parse(response.body);
            if (body["dcterms:title"]) {
              resolve(body["dcterms:title"]);
            } else {
              reject("Não foi encontrado o nome do recurso.");
            }
          } catch (error) {
            reject(error);
          }
        });
      } catch (error) {
        reject(error);
      }
    });
  }
}

So the question is… how can the customer on their end, allow requests just from my APP?

1 Like

Hey guys!

All I need is a confirmation that if I’m using third party lib for API requests, I won’t be able to pass to the customer an static IP for them whitelist in their servers.
I already asked about it on the marketplace support, they told me that it is not possible to have static IP in this case, but they told me to ask again here in the forum so the dev team can confirm it/suggest possible workarounds.

3 Likes

Hey @samuelpares. That is indeed correct - if you require outgoing requests to originate from well-known static IPs, you will need to use our Request Method. If requests are made any other way (using a 3rd party lib for example), the IP ranges from which the requests originate cannot be considered static, and it would be too long a list for someone to whitelist.

In addition, since you appear to be working with files, the Request Method won’t work anyway since we don’t support file transfers with Request Method yet.

Unfortunately, this appears to be one of those cases where a middleware server might be required to work on behalf of the app.

6 Likes