Monitoring with OAuth2 and Grant Type Client Credentials

Hello,

postman made our live to check APIs a lot easier, thanks for this!
Now I would like to monitor the APIs but I need to useOauth2 with client credentials as grant type.
If I run the monitoring with this environment I get just a not authenticated and all fails.
Is this possbile to setup a monitoring like I need?
And if, so do we have any example for this?

best regards and thank you

1 Like

Hello!

I have the same issue and am interested in the solution

@joint-operations-ar5

There are a few considerations to be had here.

The first consideration is that Monitors run from the cloud, so my first question would be whether your OAuth 2.0 auth endpoints are available over the Internet.

If they aren’t, you may need a static IP which is available in the higher Postman tiers to allow that connectivity.

The next consideration is where would you store the confidential information that is needed when you send the request to the OAuth 2.0 authorise endpoint.

The client id, client secret, etc.

When you run this in Postman, you would normally store these details in the current values in Environment variables, which aren’t synced to the Postman Cloud, therefore although you can select an environment to use with the monitor, the current values would not be available.

I’m not sure of anyway around the second consideration. You should not store confidential information in the initial values, therefore I cannot see any secure way of this working.

The third consideration would be around using the authentication helpers vs a pre-request script. With the authorization helpers, I still think you would have to request a new token from time to time. I think there is an option to automatically refresh the token, but I don’t know how that would work with a monitor. I generally use a pre-request script for this, which looks for the existence of a token and also check an expiry date if if it exists. It give me a bit more control over the authorization and this works really well for the client credentials grant type.

The following is an example of authenticating to Microsoft.

let moment = require('moment');
let currentDateTime = moment(new Date()).format("YYYYMMDDHHmmss");
let tokenExpiry = moment(pm.environment.get("bearerTokenExpiresOn")).format("YYYYMMDDHHmmss");

// console.log("currentDateTime: " + currentDateTime);
// console.log("tokenExpiry: " + tokenExpiry);
// console.log(pm.environment.get("bearerToken"));


if (!pm.environment.get("bearerToken") || currentDateTime > tokenExpiry) {
    pm.test("Pre-request check for Environment Variables", function () {
        let vars = ['client_id', 'scope', 'tenant_id', 'client_secret', 'scope'];
        vars.forEach(function (item) {
            // console.log(item);
            pm.expect(pm.environment.get(item), item + " variable not set").to.not.be.undefined;
            pm.expect(pm.environment.get(item), item + " variable not set").to.not.be.empty;
        });
        pm.sendRequest({
            url: 'https://login.microsoftonline.com/' + pm.environment.get("tenant_id") + '/oauth2/v2.0/token',
            method: 'POST',
            header: 'Content-Type: application/x-www-form-urlencoded',
            body: {
                mode: 'urlencoded',
                urlencoded: [
                    { key: "client_id", value: pm.environment.get("client_id"), disabled: false },
                    { key: "scope", value: pm.environment.get("scope"), disabled: false },
                    { key: "client_secret", value: pm.environment.get("client_secret"), disabled: false },
                    { key: "grant_type", value: "client_credentials", disabled: false },
                ]
            }
        }, function (err, res) {
            if (err) {
                console.log(err);
            } else {
                pm.test("Pre-request Microsoft login Status code is 200", () => {
                    pm.expect(res).to.have.status(200);
                    let resJson = res.json();
                    // console.log(resJson);
                    let token = resJson.access_token;
                    // console.log(token);

                    function parseJwt(token) {
                        var base64Url = token.split('.')[1];
                        var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
                        var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
                            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
                        }).join(''));

                        return JSON.parse(jsonPayload);
                    }

                    let decoded = parseJwt(token);
                    // console.log(decoded);
                    let expiryDate = new Date(decoded.exp * 1000);
                    // console.log(expiryDate);

                    pm.environment.set("bearerToken", token);
                    pm.environment.set("bearerTokenExpiresOn", expiryDate);
                    // console.log("bearerTokenExpiresOn: " + pm.environment.get("bearerTokenExpiresOn"));
                });
            }
        });
    });
};

As you can see, it relies heavily on environment variables, which would cause it to fail if run by directly in a monitor.

It will be interesting to find if anyone else has details on how to use monitors where you need authorization.