- Firmare un’asserzione client JWT con la propria chiave privata ES256.
- Sostituitela con un token di accesso a breve durata.
- Richiamare un punto di accesso ai metadati utilizzando il token di accesso.
private_key.pem) accanto allo script. Sostituire <OAuthClientId> e <KID> con i valori contenuti nel Suo pacchetto di onboarding. Consulti Richiedere un token di accesso per conoscere la funzione di ciascun passaggio.
- TypeScript
- Python
Richiede Node.js 18 o versioni successive per il globale
fetch.npm install jsonwebtoken
npm install --save-dev typescript tsx @types/jsonwebtoken @types/node
npx tsx sample_request.ts
sample_request.ts
import { randomUUID } from 'node:crypto';
import { readFileSync } from 'node:fs';
import jwt from 'jsonwebtoken';
// ---------------------------------------------------------------------------
// Configuration — fill these in for your environment.
// ---------------------------------------------------------------------------
const OAUTH_CLIENT_ID = '<OAuthClientId>'; // Your OAuth Client Id (from your onboarding pack)
const KID = '<KID>'; // The Kid whose PRIVATE key you're using to sign below
const PRIVATE_KEY_PATH = './private_key.pem'; // Path to the PRIVATE key matching that Kid's public key
const GATEWAY_BASE_URL = 'https://gateway.creditbenchmark.com';
const TOKEN_URL = 'https://gateway.creditbenchmark.com/api/security/token';
const AUDIENCE = 'cb-gateway-m2m-blue';
// Any of the metadata endpoints below — change as needed.
const METADATA_ENDPOINT = '/beta/metadata/columns';
/** Builds and signs the RFC 7523 JWT bearer client assertion. */
function buildClientAssertion(): string {
const privateKeyPem = readFileSync(PRIVATE_KEY_PATH, 'utf8');
const now = Math.floor(Date.now() / 1000);
return jwt.sign(
{
iss: OAUTH_CLIENT_ID,
sub: OAUTH_CLIENT_ID,
aud: AUDIENCE,
jti: randomUUID(),
iat: now,
exp: now + 120,
},
privateKeyPem,
{ algorithm: 'ES256', keyid: KID }
);
}
/** Exchanges the signed client assertion for a short-lived access token. */
async function getAccessToken(): Promise<string> {
const clientAssertion = buildClientAssertion();
const body = new URLSearchParams({
grant_type: 'client_credentials',
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
client_assertion: clientAssertion,
OAuthClientId: OAUTH_CLIENT_ID,
});
const response = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body,
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.status} ${await response.text()}`);
}
const data = (await response.json()) as { accessToken: string };
return data.accessToken;
}
/** Calls a metadata API using the access token. Swap 'endpoint' for any of
* the other metadata endpoints. */
async function callMetadataEndpoint(accessToken: string, endpoint: string = METADATA_ENDPOINT): Promise<unknown> {
const response = await fetch(`${GATEWAY_BASE_URL}${endpoint}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`Metadata request failed: ${response.status} ${await response.text()}`);
}
return response.json();
}
(async () => {
const token = await getAccessToken();
console.log('Access token acquired.');
const data = await callMetadataEndpoint(token);
console.log(`Response from ${METADATA_ENDPOINT}:`);
console.log(data);
})().catch((err) => {
console.error(err);
process.exitCode = 1;
});
Richiede Python 3.8 o versioni successive.
pip install "requests>=2.31.0" "PyJWT>=2.8.0" "cryptography>=41.0.0"
python sample_request.py
sample_request.py
import time
import uuid
import jwt # PyJWT
import requests
# ---------------------------------------------------------------------------
# Configuration — fill these in for your environment.
# ---------------------------------------------------------------------------
OAUTH_CLIENT_ID = "<OAuthClientId>" # Your OAuth Client Id (from your onboarding pack)
KID = "<KID>" # The Kid whose PRIVATE key you're using to sign below
PRIVATE_KEY_PATH = "private_key.pem" # Path to the PRIVATE key matching that Kid's public key
GATEWAY_BASE_URL = "https://gateway.creditbenchmark.com"
TOKEN_URL = "https://gateway.creditbenchmark.com/api/security/token"
AUDIENCE = "cb-gateway-m2m-blue"
# Any of the metadata endpoints below — change as needed.
METADATA_ENDPOINT = "/beta/metadata/columns"
def build_client_assertion() -> str:
"""Builds and signs the RFC 7523 JWT bearer client assertion."""
with open(PRIVATE_KEY_PATH, "r", encoding="utf-8") as f:
private_key_pem = f.read()
now = int(time.time())
payload = {
"iss": OAUTH_CLIENT_ID,
"sub": OAUTH_CLIENT_ID,
"aud": AUDIENCE,
"jti": str(uuid.uuid4()),
"iat": now,
"exp": now + 120,
}
headers = {"kid": KID}
return jwt.encode(payload, private_key_pem, algorithm="ES256", headers=headers)
def get_access_token() -> str:
"""Exchanges the signed client assertion for a short-lived access token."""
client_assertion = build_client_assertion()
response = requests.post(
TOKEN_URL,
data={
"grant_type": "client_credentials",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": client_assertion,
"OAuthClientId": OAUTH_CLIENT_ID,
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
timeout=30,
)
response.raise_for_status()
return response.json()["accessToken"]
def call_metadata_endpoint(access_token: str, endpoint: str = METADATA_ENDPOINT) -> dict:
"""Calls a metadata API using the access token. Swap 'endpoint' for any
of the other metadata endpoints."""
response = requests.get(
f"{GATEWAY_BASE_URL}{endpoint}",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
"Accept": "application/json",
},
timeout=30,
)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
token = get_access_token()
print("Access token acquired.")
data = call_metadata_endpoint(token)
print(f"Response from {METADATA_ENDPOINT}:")
print(data)
Endpoint dei metadati
ImpostareMETADATA_ENDPOINT una qualsiasi di queste opzioni. Sono tutte GET richieste.
| Endpoint | Restituisce |
|---|---|
/beta/metadata/columns | Colonne di input disponibili con tipo, possibilità di restrizione per ambito, possibilità di filtraggio per facette e autorizzazione |
/beta/metadata/available-dates | Data di entrata in vigore più recente e data di entrata in vigore definitiva più recente |
/beta/metadata/geography-schema | Gerarchia di gruppi di regioni, regioni e paesi |
/beta/metadata/rating-scales | Scale di valutazione supportate e relative mappature dei gradi |
Non condivida mai la Sua chiave privata con nessuno, compreso Credit Benchmark. Generi una nuova asserzione client per ogni richiesta di token e, qualora la chiave privata dovesse mai essere compromessa, segua la procedura descritta all’indirizzo rotazione delle chiavi.

