devtj3 / ttapp-

GNU General Public License v3.0
0 stars 0 forks source link

Sample #1

Open devtj3 opened 1 year ago

devtj3 commented 1 year ago

Basic sample

Certainly, here's a Python script that uses the OIDC (OpenID Connect) flow to authenticate against a BeyondTrust (BT) API, assuming that BT supports OIDC. The script uses the requests library to handle HTTP interactions.

First, install the requests library:

pip install requests

Here's the script:

import requests
import json

# BT API & OIDC Configurations
API_URL = "https://bt.example.com/api"  # Replace with your BeyondTrust API URL
OIDC_TOKEN_ENDPOINT = "https://your-oidc-provider.com/token"  # Replace with your OIDC token endpoint
CLIENT_ID = "your-client-id"  # Replace with your OIDC client id
CLIENT_SECRET = "your-client-secret"  # Replace with your OIDC client secret
SECRET_LIST = "ttom1/ttaws"

# Function to get OIDC token
def get_oidc_token():
    payload = {
        'grant_type': 'client_credentials',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET
    }
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    response = requests.post(OIDC_TOKEN_ENDPOINT, headers=headers, data=payload)
    if response.status_code == 200:
        return json.loads(response.text)['access_token']
    else:
        print("Error in getting OIDC token:", response.text)
        return None

# Main function
def main():
    # Get OIDC Token
    oidc_token = get_oidc_token()
    if not oidc_token:
        return

    # Get secrets from BeyondTrust using the OIDC token
    headers = {
        'Authorization': f"Bearer {oidc_token}"
    }
    response = requests.get(f"{API_URL}/secrets/{SECRET_LIST}", headers=headers)

    if response.status_code == 200:
        secrets = json.loads(response.text)
        print("Retrieved Secrets:", secrets)
    else:
        print("Error in getting secrets:", response.text)

if __name__ == "__main__":
    main()

Replace placeholder values like your-oidc-provider.com, your-client-id, and your-client-secret with your actual OIDC configuration. Run the script after these changes.

This script first obtains an OIDC token and then uses that token to authenticate against the BeyondTrust API to retrieve secrets.

AWS Sample

If the BeyondTrust (BT) API doesn't support OIDC yet, then you'd have to modify the API server to include OIDC authentication. Normally, you'd need access to the source code of the API to add such functionality.

However, if you don't have that access, you can create a "proxy" service that stands between the client and the BT API. The proxy would handle OIDC authentication and forward valid requests to the BT API.

Here is a simplified example using Python and Flask to build such a proxy:

First, install the required packages:

pip install Flask
pip install python_jwt

Here's the Python code:

from flask import Flask, request, jsonify
import requests
import json
import python_jwt as jwt

app = Flask(__name__)

BT_API_URL = "https://bt.example.com/api"
OIDC_PUBLIC_KEY = "Your OIDC Public Key Here"

@app.route('/proxy/<path:subpath>', methods=['GET', 'POST'])
def proxy(subpath):
    # Validate OIDC Token
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Bearer '):
        return jsonify({"error": "Missing or invalid Authorization header"}), 401

    token = auth_header.split(" ")[1]
    try:
        jwt.verify_jwt(token, OIDC_PUBLIC_KEY, ['RS256'])
    except Exception as e:
        return jsonify({"error": "Invalid token", "details": str(e)}), 401

    # Forward request to BT API
    headers = {'Authorization': 'Your BT API credentials'}
    if request.method == 'GET':
        resp = requests.get(f"{BT_API_URL}/{subpath}", headers=headers)
    elif request.method == 'POST':
        resp = requests.post(f"{BT_API_URL}/{subpath}", headers=headers, json=request.json)

    return (resp.content, resp.status_code, resp.headers.items())

if __name__ == '__main__':
    app.run(port=5000)

Replace "Your OIDC Public Key Here" and 'Your BT API credentials' with your actual OIDC public key and BT API credentials.

This Flask application acts as a proxy, validating incoming requests for a valid OIDC token and then forwarding them to the actual BT API. Run this Flask app, and your clients should make API calls to this service instead of directly to the BT API. This way, you're adding OIDC support "in front of" the existing API.

devtj3 commented 1 year ago

To get the OIDC public key for token validation, you generally fetch it from the identity provider's JWKS (JSON Web Key Set) URL. The JWKS URL is often found in the OIDC discovery document, which is usually located at an endpoint like https://<identity_provider_domain>/.well-known/openid-configuration.

Here's an example using Python to fetch the public key:

  1. Install the required package:

    pip install requests
  2. Fetch the public key:

import requests
import json

# Fetch OIDC configuration
oidc_config_url = 'https://<identity_provider_domain>/.well-known/openid-configuration'
response = requests.get(oidc_config_url)
config = response.json()

# Fetch JWKS
jwks_url = config['jwks_uri']
response = requests.get(jwks_url)
jwks = response.json()

# Extract RSA public keys
keys = {}
for key_data in jwks['keys']:
    if key_data['kty'] == 'RSA' and 'kid' in key_data:
        kid = key_data['kid']
        keys[kid] = key_data

# Now `keys` contains the public keys, indexed by 'kid' (Key ID)

Once you have the public keys, you can use them to validate incoming JWTs by matching the 'kid' in the JWT header to one of the public keys you've fetched.