Authentication with Proof Key for Code Exchange (PKCE) for Access Token and CI/CD integration with Newman to Run the Postman collection

Authentication with Proof Key for Code Exchange (PKCE) for Access Token and CI/CD integration with Newman to Run the Postman collection

In today's digital landscape, modern applications are increasingly built on the foundation of APIs (Application Programming Interfaces). APIs serve as the bridge between different software components, allowing them to communicate and exchange data seamlessly. As the backbone of countless applications, APIs play a crucial role in enabling functionality and driving innovation.

As APIs become more common, it's crucial to prioritize their security. One powerful method for securing APIs is using PKCE (Proof Key for Code Exchange) workflows. PKCE adds an extra layer of security by protecting against certain types of attacks, such as authorization code interception.

Testing APIs is essential for ensuring their functionality, reliability, and security. By thoroughly testing APIs, developers can identify and address issues early in the development lifecycle, preventing costly errors and vulnerabilities down the line.

However, testing APIs manually can be time-consuming and prone to human error. That's where automated testing tools like Postman come in. Postman offers a comprehensive platform for designing, testing, and managing APIs, streamlining the testing process, and improving overall efficiency.

One challenge arises when implementing PKCE authentication flows in Postman for API testing. Typically, PKCE workflows require user input for authentication, such as entering credentials and interacting with a callback URL (https://oauth.pstmn.io/v1/callback or https://localhost:8080). This manual intervention is not conducive to automated testing, especially in continuous integration and continuous deployment (CI/CD) pipelines where seamless, without human interference execution is essential.

To address this challenge, I’m presenting a solution that allows for automated authentication with PKCE flows, enabling smooth integration into CI/CD pipelines.

Authorization code using GET request

When accessing the URL in any web browser, users are directed to the Microsoft login page to input their credentials. Upon successful authentication, users are redirected to the URL configured in Azure, where they receive the authorization code.

Authorization code URL

Below Selenium Python script can be used to grab the authorization code and out the value using GitHub environment file.

import sys

import time

import os

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from urllib.parse import urlparse, parse_qs

from selenium.webdriver.chrome.options import Options

 

#Set Chrome options for running in headless mode

chrome_options = Options()

chrome_options.add_argument("--headless")

# Initialize the WebDriver

driver = webdriver.Chrome(options=chrome_options)

driver.get("Authorization code URL")

# Explicitly wait until the element with ID "signinOptions" is visible

signin_options_element = WebDriverWait(driver, 10).until(

    EC.visibility_of_element_located((By.ID, "loginHeader"))

)

driver.find_element(By.NAME,"loginfmt").send_keys("your email")

driver.find_element(By.ID,"idSIButton9").click()

 password = sys.argv[1]

driver.find_element(By.NAME,"passwd").send_keys(password)

driver.find_element(By.ID,"idSIButton9").click()

# Explicitly wait until the element with ID "signinOptions" is visible

signin_options_element = WebDriverWait(driver, 10).until(

    EC.visibility_of_element_located((By.ID, "KmsiDescription"))

)

driver.find_element(By.ID,"idBtn_Back").click()

# Wait until the page title is "localhost" or until a timeout of 30 seconds

wait = WebDriverWait(driver, 30)

wait.until(EC.url_contains("localhost:8080"))

print("Curent page URL: " + driver.current_url)

# Parse the URL to extract the query parameters

parsed_url = urlparse(driver.current_url)

# Get the query parameters as a dictionary

query_parameters = parse_qs(parsed_url.query)

# Get the value of the 'code' parameter

code_value = query_parameters.get('code', [''])[0]  # Use [0] to get the first value if it exists, or an empty string if it doesn't

print("Code: " + code_value)

env_file = os.getenv('GITHUB_ENV') # Get the path of the runner file

# write to the file

with open(env_file, "a") as env_file:

    env_file.write(f"CODE=${code_value}")

# Close the driver

driver.quit()        

?

Substitute the placeholder "Authorization code URL" with your specific link and replace " your email" with your actual email address. Afterward, execute the script on the local machine by passing the password as an argument and do not forget the comment out the below code.

env_file = os.getenv('GITHUB_ENV') # Get the path of the runner file

# write to the file

with open(env_file, "a") as env_file:

? ? env_file.write(f"CODE=${code_value}")

?

In the console, you'll find the URL of the redirected page along with the authorization code. Use this authorization code and code verifier in Postman to obtain the access token. Once you receive the access token in the response, store its value in a variable. This token will be used to execute and verify the remaining APIs.

Note: While the above script is basic, it can certainly be enhanced to meet your specific needs.

Postman Test Script

Replace the authorization code, code_verifier and send it. In the response, you should have the access and refresh tokens.

Now uncomment the code from the Python file, replace the actual code and code_verifier values with the variables ({{code}}, {{code_verifier}}), and then commit these files to your GitHub repository along with the Postman collection and Environment variables files.

Github Repo


Postman collection, accepting code and code verifier as arguments.

Postman Collection

Proceed to the Actions tab and initiate the creation of a new workflow. Copy pastes the below script and make the changes as per your own requirements.

name: Automated API tests using Newman CLI

on:

 workflow_dispatch: 

jobs:

  automated-api-tests:

    runs-on: ubuntu-latest

    steps:

      - name: Checkout code

        uses: actions/[email protected] 

      - name: Set up Python

        uses: actions/[email protected]

        with:

          python-version: 3.12.2  # Choose the Python version
 

      - name: Install dependencies

        run: |

          python -m pip install --upgrade pip

          pip install selenium  
       

      - name: Run Selenium script

        run: |

          output=$(python Python/login.py ${{ secrets.PASS }})
     

      - name: Print Code Value

        run: |

          echo "The code is: $CODE"
 

   # Install Node on the runner

      - name: Install Node

        uses: actions/[email protected]

        with:

          node-version: '20.x'
 

    #Install newaman and reporter

      - name: Install newman

        run: |

          npm install -g newman

          npm install -g newman-reporter-htmlextra
   

    # Run Collection

      - name: Run Collection

        run: |

          newman run "PostmanCollections/App.postman_collection.json" -e "PostmanCollections/QA.postman_environment.json" --env-var "code=$CODE" --env-var "${{ secrets.VERIFIER }}" -r cli,htmlextra --reporter-htmlextra-export testResults/htmlReport.html || true
     

    # Upload the contents of Test Results directory to workspace

      - name: Output the run Details

        uses: actions/upload-artifact@v3

        with:

          name: PostmanRunReport

          path: testResults        

?

Navigate to your workflows and run the pipeline.

Run workflow manually

Pipeline should be executed successfully. Go and see the Job run.

Against the action run you should be able to see the artifact that you can download to analyze the API test run.

GitHub Action Run

Upon clicking the “PostmanRunReport” artifact, zip folder will be downloaded. Unzip that folder and open the HTML page.

HTML Report

To execute the CI/CD pipeline for testing the Postman collection via Newman, ensuring API security with PKCE and eliminating manual intervention, follow these steps:

  • Utilize Selenium in Python to automate login and retrieve the authorization code.
  • Save the obtained code in the GitHub environment file.
  • Incorporate the code and code verifier as arguments in the GitHub action script.
  • Execute the Postman collection using Newman within the GitHub action script.

Steve Denton

Quality Engineering Manager at Retail Insight

1 年

Good work, Mahboob!

Gary Hodgson

Technical Programme Manager at Retail Insight

1 年

Nice work Mahboob!

Shabab Arshad

Senior Software Developer, FreeLancer, Open Source Code Contributor, Xamarin/MAUI Developer Team Lead

1 年

very helpful

Sher Hassan

Experienced Professional | Software Quality Assurance & Quality Control | Business Analysis | Data Analysis | Software Support | Technical Writing | Project & Team Management

1 年

Great share

Shahid Ghaffar, PMP, PMI-ACP

ERP | CRM | Innovative Solution Architect | Technical Leadership | PMI-ACP | PMP | I help Organizations for Driving 30% Efficiency Growth

1 年

great.

要查看或添加评论,请登录

Mahboob Hassan的更多文章

  • RPA Support in Digital Transformation

    RPA Support in Digital Transformation

    We are living in the age of digitalization, where information is being transformed into digital format for better and…

    4 条评论
  • RPA Evolution: From Macros to Hyper Automation

    RPA Evolution: From Macros to Hyper Automation

    These days everyone is talking about Robotic Process Automation (RPA), the much demanding technology that automates the…

    1 条评论
  • Test Automation and Robotic Process Automation

    Test Automation and Robotic Process Automation

    Many of us might have a question or ambiguity, what the difference is between Test Automation and Robotic Process…

    12 条评论

社区洞察

其他会员也浏览了