newman icon indicating copy to clipboard operation
newman copied to clipboard

Feature request: support OAuth2 client credentials from the collection Authorization tab (JSON "auth" key)

Open bchociej opened this issue 3 years ago • 4 comments

Related: #191 #2615 #2724

This behavior has been discussed at length already including in the above issues. This post is more formally a request to implement the desired behavior.

Specifically, please consider supporting OAuth2 client credentials when they have been configured under the "Authorization" tab for the collection in the Postman UI (equivalent to the "auth" key in collection JSON).

Obviously, a lot of OAuth2 grant types are interactive and so are not really compatible with newman, but client_credentials is non-interactive and would provide a much easier way to configure tests than manually adding headers for every test.

Here is an example of the "auth" key excerpt from a Postman collection JSON file that I would expect to be supported:

{
        "info": {...},
        "item": [...],
        "auth": {
                "type": "oauth2",
                "oauth2": [
                        {
                                "key": "tokenName",
                                "value": "My OAuth Token",
                                "type": "string"
                        },
                        {
                                "key": "accessTokenUrl",
                                "value": "{{baseUrl}}/oauth/token",
                                "type": "string"
                        },
                        {
                                "key": "client_authentication",
                                "value": "body",
                                "type": "string"
                        },
                        {
                                "key": "clientSecret",
                                "value": "{{client_secret}}",
                                "type": "string"
                        },
                        {
                                "key": "clientId",
                                "value": "{{client_id}}",
                                "type": "string"
                        },
                        {
                                "key": "grant_type",
                                "value": "client_credentials",
                                "type": "string"
                        },
                        {
                                "key": "addTokenTo",
                                "value": "header",
                                "type": "string"
                        }
                ]
        }
}
  1. Newman Version (can be found via newman -v): 5.3.2
  2. OS details (type, version, and architecture): multiple (OSX Big Sur, Monterey; Alpine Linux 3.16 via Docker)
  3. Are you using Newman as a library, or via the CLI? library, but should apply to either
  4. Did you encounter this recently, or has this bug always been there: n/a
  5. Expected behaviour: OAuth client credentials grant type is supported
  6. Command / script used to run Newman: See below
  7. Sample collection, and auxiliary files (minus the sensitive details): See above
  8. Screenshots (if applicable): n/a

Newman library call:

    newman.run({
        collection: require('./postman_collection.json'),
        environment: {},
        reporters: ['cli', 'htmlextra'],
        reporter: {
            htmlextra: {
                export: outputFile,
            },
        },
    }, async (error, summary) => {
        // ...
    })

bchociej avatar Jul 26 '22 19:07 bchociej

Wow, I was testing a few api testing tools to compare experience (ease of use) and was really surprised to stumble on this issue. Leveraged chatgpt but it seems that it was not aware of that limitation (suggest global and environment file, none worked).

Also, while working on this, I noticed that the postman auth configs are not clean, saw values (username,password) from different auth configs scheme I had used before...

I used chatgp to hack a python script to load the configs from the collection and reinject the token in each request of a new generated collection file ("with token"). This solution is not general but is good enough for my intended usage, something like this:

json collections file in a collections folder Script "python prepare_collection_with_token_using_collection_config.py"

import json
import requests

def add_token_to_collection(source_file_name, dest_file_name, token):
    with open(source_file_name, 'r') as f:
        collection = json.load(f)

    # Walk through every item in the collection
    for item in collection['item']:
        # Add the Authorization header with the Bearer token to each request
        if 'request' in item:
            if 'header' not in item['request']:
                item['request']['header'] = []
            item['request']['header'].append({
                "key": "Authorization",
                "value": f"Bearer {token}"
            })

    # Write the modified collection to the destination file
    with open(dest_file_name, 'w') as f:
        json.dump(collection, f, indent=2)

# Load the collection JSON
with open('collections/something.postman_collection.json') as f:
    data = json.load(f)

# Extract the OAuth2 parameters
params = {item['key']: item['value'] for item in data['auth']['oauth2']}

# Make the request to the OAuth2 server
response = requests.post(
    params['accessTokenUrl'],
    data={
        'client_id': params['clientId'],
        'client_secret': params['clientSecret'],
        'grant_type': params['grant_type'],
        'scope': params['scope'],
    },
)

# Extract the access token
token = response.json()['access_token']

source_file_name = "collections/something.postman_collection.json"
dest_file_name = "collections/something.postman_collection_with_token_unsafe.json"
add_token_to_collection(source_file_name, dest_file_name, token)

run-test-in-docker.sh file (using gitbash on windows so a few more hoops, would be cleaner on linux)

`#!/bin/bash python prepare_collection_with_token_using_collection_config.py

winpty docker run -it
-v "//$(pwd)//collections":/etc/newman
postman/newman run "something.postman_collection_with_token_unsafe.json" rm collections/something.postman_collection_with_token_unsafe.json`

ghost avatar May 30 '23 21:05 ghost