Authentifizierung
Alle IDCloud-APIs (Web & SDK- und API-Verträge) verwenden OAuth2 mit JWT Bearer Grant Type (RFC 7523). Sie generieren eine kurzlebige JWT-Assertion in Ihrem Back-End, tauschen sie gegen ein Bearer-Token aus und verwenden dieses Token bei jedem nachfolgenden Aufruf.
Die JWT-Assertion muss ausschließlich in Ihrem Back-End generiert werden. Legen Sie Ihren privaten Schlüssel niemals in Front-End-Code, mobilen Apps, Repositories oder Logs offen.
Anmeldedaten abrufen
Bevor Sie Token generieren können, benötigen Sie ein von Unico bereitgestelltes Dienstkonto. Kontaktieren Sie den Unico-Support und geben Sie folgendes an:
- Name des Dienstkontos (max. 12 Zeichen)
- Name, E-Mail und Telefonnummer der verantwortlichen Person (nur Nummern aus Brasilien, USA oder Mexiko)
Sie erhalten:
- Eindeutiger Kontoname
- Mandanten-ID (Tenant ID)
- Basis-JWT-Payload
- Private-Key-Datei (Format
.pem)
Verwenden Sie separate Dienstkonten für UAT und Produktion.
JWT-Assertion erstellen
Die Assertion ist ein JWT im kompakten JWS-Format: {Base64url(Header)}.{Base64url(Payload)}.{Base64url(Signature)}.
{
"alg": "RS256",
"typ": "JWT"
}
| Claim | Wert | Hinweise |
|---|---|---|
iss | <account_name>@<tenant_id>.iam.acesso.io | Wird mit Ihren Anmeldedaten bereitgestellt |
aud | https://identityhomolog.acesso.io (UAT) oder https://identity.acesso.io (Produktion) | Muss mit dem Token-Endpoint-Host übereinstimmen |
scope | * | Gewährt alle Berechtigungen |
iat | Unix-Zeitstempel (Sekunden) | Zeitpunkt der JWT-Ausstellung |
exp | iat + max 3600 | Darf iat nicht um mehr als 1 Stunde überschreiten |
{
"aud": "https://identity.acesso.io",
"scope": "*",
"iat": 1738086000,
"exp": 1738089600
}
Signieren Sie Header + Payload mit RS256 (RSA + SHA-256) und dem von Unico bereitgestellten privaten Schlüssel im Format .pem.
Jedes Feld, das nicht oben aufgeführt ist (z. B. sub, jti, nbf), führt zu einem Fehler 1.2.22. Verwenden Sie ausschließlich die angezeigten Claims.
Token anfordern
Der Token-Endpoint ist für beide Verträge identisch:
| Umgebung | Endpoint |
|---|---|
| Produktion | POST https://identity.acesso.io/oauth2/token |
| UAT | POST https://identityhomolog.acesso.io/oauth2/token |
| Parameter | Wert |
|---|---|
Content-Type | application/x-www-form-urlencoded |
grant_type | urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion | Ihr signiertes JWT |
- cURL
- Node.js
- Python
curl -X POST https://identity.acesso.io/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
import jwt from 'jsonwebtoken';
import fs from 'fs';
import qs from 'querystring';
const privateKey = fs.readFileSync('./private-key.pem');
const now = Math.floor(Date.now() / 1000);
const assertion = jwt.sign(
{
aud: 'https://identity.acesso.io',
scope: '*',
iat: now,
exp: now + 3600,
},
privateKey,
{ algorithm: 'RS256' }
);
const res = await fetch('https://identity.acesso.io/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: qs.stringify({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion,
}),
});
const { access_token, expires_in } = await res.json();
import time
import jwt # PyJWT
import requests
with open("private-key.pem", "rb") as f:
private_key = f.read()
now = int(time.time())
assertion = jwt.encode(
{
"aud": "https://identity.acesso.io",
"scope": "*",
"iat": now,
"exp": now + 3600,
},
private_key,
algorithm="RS256",
)
response = requests.post(
"https://identity.acesso.io/oauth2/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": assertion,
},
)
token_data = response.json()
access_token = token_data["access_token"]
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
| Feld | Typ | Beschreibung |
|---|---|---|
access_token | string | JWT-Zugriffstoken. Verwenden Sie es als Authorization: Bearer <token> bei allen API-Aufrufen. |
expires_in | integer | Ablaufzeit in Sekunden. Beispiel: 3600. |
token_type | string | Immer Bearer. |
Token verwenden
Fügen Sie das Token dem Authorization-Header jeder API-Anfrage hinzu. Der Header ist für beide Verträge identisch — was sich unterscheidet, ist der Host und Pfad der aufgerufenen API:
| Vertrag | Produktions-Host | UAT-Host |
|---|---|---|
| Web & SDK | https://api.idcloud.unico.app | https://api.idcloud.uat.unico.app |
| API | https://api.id.unico.app | https://api.id.uat.unico.app |
Web & SDK — Authorization ist der einzige erforderliche Auth-Header:
curl -X POST https://api.idcloud.unico.app/client/v1/process \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }'
API — Authorization wird zusammen mit dem APIKEY-Header verwendet:
curl -X POST https://api.id.unico.app/processes/v1 \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "APIKEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'
Token erneuern
Token laufen nach 3600 Sekunden ab. Implementieren Sie eine proaktive Erneuerung in Ihrem Back-End:
- Verfolgen Sie
expires_inaus der Token-Antwort und speichern Sie den Ablaufzeitstempel. - Fordern Sie ein neues Token an, wenn noch 10 Minuten oder weniger bis zum Ablauf verbleiben.
- Warten Sie in der Produktionsumgebung nie auf ein
401, bevor Sie eine Erneuerung auslösen.
API-Referenz
Die vollständige OpenAPI-Spezifikation für den Token-Endpoint ist in authentication.yaml verfügbar.
| Methode | Pfad | Beschreibung |
|---|---|---|
POST | /oauth2/token | Tauscht eine signierte JWT-Assertion gegen ein Bearer-Zugriffstoken aus |
Fehlercodes
| Code | Beschreibung | Maßnahme |
|---|---|---|
1.0.1 | Die in der iss-Bildung angegebene ID ist falsch | Überprüfen Sie, ob das iss-Feld mit der Mandanten-ID übereinstimmt, die bei der Generierung des privaten Schlüssels angegeben wurde |
1.0.14 | Anwendung ist nicht aktiv | Prüfen Sie mit dem Projektmanager, ob die verwendete Anwendung aktiv ist |
1.1.1 | Der Parameter scope wurde nicht angegeben | Fügen Sie "scope": "*" zu Ihrem JWT-Payload hinzu |
1.2.4 | JWT-Assertion ungültig | Die JWT-Assertion ist nicht mehr gültig. Zwei mögliche Ursachen: (a) der aktuelle Zeitpunkt liegt nach exp (JWT tatsächlich abgelaufen — generieren Sie für jede Token-Anfrage eine neue Assertion); oder (b) exp überschreitet iat + 3600 (Gültigkeitsdauer zu lang — begrenzen Sie exp auf iat + 3600). |
1.2.5 | JWT-Validierung fehlgeschlagen | Das JWT kann nicht validiert werden. Überprüfen Sie die Parameter und stellen Sie sicher, dass es mit RS256 und dem richtigen privaten Schlüssel signiert wurde |
1.2.6 | Privater Schlüssel ist nicht mehr gültig | Der zum Signieren des JWT verwendete private Schlüssel ist nicht mehr akzeptiert. Fordern Sie neue Anmeldedaten für das Konto an |
1.2.7 | JWT bereits verwendet | Das JWT wird nicht mehr akzeptiert, da es bereits verwendet wurde. Generieren Sie für jede Token-Anfrage eine neue Assertion |
1.2.11 | Konto ist nicht aktiv | Das verwendete Konto ist nicht aktiv |
1.2.14 | Konto verfügt nicht über die erforderlichen Berechtigungen | Das verwendete Konto besitzt nicht die erforderlichen Berechtigungen |
1.2.18 | Konto vorübergehend gesperrt | Das Konto wurde vorübergehend gesperrt, da die Anzahl ungültiger Authentifizierungsversuche überschritten wurde |
1.2.19 | Nicht autorisierte Benutzerverkörperung | Das JWT enthält einen sub-Claim, der auf ein Konto verweist, das nicht zur Verkörperung autorisiert ist. Entfernen Sie den sub-Claim aus dem Payload. |
1.2.20 | JWT-Dekodierung fehlgeschlagen | Das JWT konnte nicht dekodiert werden. Überprüfen Sie das Token-Format und stellen Sie sicher, dass es mit RS256 signiert wurde. |
1.2.21 | Falscher privater Schlüssel / Authentifizierung fehlgeschlagen | Die JWT-Signatur konnte für kein bekanntes Schlüsselpaar dieses Kontos verifiziert werden. Stellen Sie sicher, dass Sie den richtigen .pem-Schlüssel für dieses Dienstkonto und diese Umgebung verwenden. |
1.2.22 | Nicht erlaubte Felder im Payload | Das JWT enthält zusätzliche Payload-Felder, die nicht erlaubt sind. Entfernen Sie alle Claims, die nicht in dieser Anleitung aufgeführt sind (z. B. sub, jti, nbf). Hinweis: Falls ein sub-Claim enthalten war und stattdessen Fehler 1.2.19 aufgetreten ist, hat dieser Fehler Vorrang. |
1.3.1 | IP-Zugriffsbeschränkung | Ihre IP befindet sich nicht auf der Zulassungsliste für dieses Konto |
1.3.2 | Zeitbasierte Zugriffsbeschränkung | Die Anfrage liegt außerhalb des erlaubten Zeitfensters für dieses Konto |
Nächste Schritte
- Umgebungen — Sandbox vs. Produktions-Hosts
- Web & SDK — Prozess erstellen — erster Aufruf nach der Authentifizierung
- API — Prozess erstellen — erster Aufruf nach der Authentifizierung