MTLS authentication & OAuth 2.0

Hi,

I need to connect to an API which is secured with MTLS and OAuth2. Testing the API in Postman, it is very easy to configure the certificates and to make the request. It works.

I want now to do it in make. I have the following data:
-a public key in a PEM file
-a private key in a KEY file
-a CRT public Key
-a client ID
-a client secret

I have tried the basic authentication and the oAuth2 in the http module, but with no success.

Thanks for your help.

Marc

2 Likes

Following - working on a custom app and Make doesn’t support adding client certificates for mTLS.

Hi,

My workaround is the following: I’m using Pipedream to do the transactions with MTLS (i only have a few), and I call their webhook from Make.

I’m using basic Python code. If you’re using the free version of Pipedream, you can’t use directly the certificates because you don’t have access to files, so here is my code to use certificates as string (check if it is compatible with your level of security).

Marc

import requests
from requests.auth import HTTPBasicAuth
import tempfile
import os

# Configurable Constants
#Note it is important to have you certificate in one line with  \n
PUBLIC_KEY_CERT ="-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"
CA_PUBLIC_KEY ="-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"
PRIVATE_KEY  ="-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"
  
BASE_URL = "Your URL"
ENDPOINT = "/api/v2/transactions"
TOKEN_URL = "/oauth/token"
CLIENT_ID = ""
CLIENT_SECRET = ""

def create_temp_files():
    """
    Crée des fichiers temporaires pour stocker les certificats et les clés.
    Retourne les chemins des fichiers temporaires.
    """
    with tempfile.NamedTemporaryFile(mode="w", delete=False) as public_key_file, \
         tempfile.NamedTemporaryFile(mode="w", delete=False) as private_key_file, \
         tempfile.NamedTemporaryFile(mode="w", delete=False) as ca_cert_file:

        public_key_file.write(PUBLIC_KEY_CERT)
        private_key_file.write(PRIVATE_KEY)
        ca_cert_file.write(CA_PUBLIC_KEY)

        public_key_file.close()
        private_key_file.close()
        ca_cert_file.close()

        return public_key_file.name, private_key_file.name, ca_cert_file.name

def delete_temp_files(file_paths):
    """
    Supprime les fichiers temporaires à partir de leurs chemins.
    """
    for file_path in file_paths:
        try:
            os.remove(file_path)
        except:
            pass

def get_access_token():
    try:
        # Créer des fichiers temporaires pour stocker les certificats
        public_key_file_path, private_key_file_path, ca_cert_file_path = create_temp_files()

        auth = HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
        response = requests.post(
            f"{BASE_URL}{TOKEN_URL}",
            auth=auth,
            cert=(public_key_file_path, private_key_file_path),
            verify=ca_cert_file_path
        )
        response.raise_for_status()  # Raises an HTTPError for bad responses
        token = response.json().get('access_token')
        print(token)
        return token
    except Exception as e:
        print(f"Error fetching access token: {e}")
        return None
    finally:
        # Supprimer les fichiers temporaires
        delete_temp_files([public_key_file_path, private_key_file_path, ca_cert_file_path])

def get_api_data(access_token):
    try:
         # Créer des fichiers temporaires pour stocker les certificats
        public_key_file_path, private_key_file_path, ca_cert_file_path = create_temp_files()

        headers = {'Authorization': f'Bearer {access_token}'}
        parameters={'operationDateRangeStart':'2024-03-01','operationDateRangeEnd':'2024-04-10'}
        response = requests.get(
            f"{BASE_URL}{ENDPOINT}",
            headers=headers,
             cert=(public_key_file_path, private_key_file_path),
            verify=ca_cert_file_path
        )

        response.raise_for_status()  # Raises an HTTPError for bad responses

        if response.status_code == 200:
            data = response.json()
            print("API Response:", data)
        else:
            print("Failed to fetch data. Status code:", response.status_code)
    except requests.exceptions.RequestException as e:
        print(f"Error fetching API data: {e}")


# Utilisation de la fonction get_access_token()
access_token = get_access_token()
get_api_data(access_token)