M2M Client Credentials
Machine-to-Machine (M2M)-Authentifizierung wird verwendet, wenn ein Backend-Dienst oder automatisierter Prozess eine API aufrufen muss, ohne dass ein Mensch anwesend ist. Auris implementiert den OAuth2 client_credentials Grant (RFC 6749 Abschnitt 4.4) und stellt Access Tokens direkt an vertrauliche Clients aus.
Häufige Anwendungsfälle:
- Ein Hintergrund-Job, der Benutzerdaten aus der Auris Management API lesen muss
- Ein Microservice, der Berechtigungen für API-Anfragen validiert
- Eine CI/CD-Pipeline, die Rollen und Anwendungskonfiguration verwaltet
- Ein Backend-Dienst, der einen anderen Dienst aufruft, der Auris-Tokens validiert
Funktionsweise
Der client_credentials Flow umfasst keinen Benutzer, keine Login-Seite und keine Weiterleitung. Der Client sendet seine Anmeldeinformationen direkt an den Token-Endpunkt und erhält ein Access Token:
- Client sendet
client_id,client_secret,grant_type=client_credentialsund optionalescopean den Token-Endpunkt - Auris validiert die Anmeldeinformationen und prüft, ob die angeforderten Scopes für die Anwendung erlaubt sind
- Auris stellt ein JWT-Access-Token mit
type: 'm2m'und den gewährten Scopes imscope-Claim aus - Der Client präsentiert das Access Token als Bearer-Token bei nachgelagerten API-Aufrufen
Tokens sind kurzlebig (Standard: 60 Minuten) und sollten bis zum Ablauf gecacht und wiederverwendet werden.
Console-Einrichtung
M2M-Anwendung erstellen
Gehe in der Auris Console zu Applications → Create Application und wähle M2M als Anwendungstyp.
M2M-Anwendungen haben keine Redirect-URIs oder Login-Seiten — nur Anmeldeinformationen und Scopes.
Erlaubte Scopes konfigurieren
Wähle unter dem Tab M2M Scopes auf der Anwendungsdetailseite, welche Scopes die Anwendung anfordern darf. Verfügbare Scopes sind nach Ressource organisiert (z. B. read:users, manage:roles, view:organizations).
Anmeldeinformationen kopieren
Kopiere vom Tab Credentials die Client ID und das Client Secret.
Client Secrets werden nur einmal bei der Erstellung angezeigt. Speichere das Secret sicher (z. B. in einem Secrets Manager oder als Umgebungsvariable). Bei Verlust des Secrets verwende die Schaltfläche Rotate Secret, um ein neues zu generieren.
Anmeldeinformationen sicher speichern
Setze die Anmeldeinformationen als Umgebungsvariablen in deiner Deployment-Umgebung. Kodiere sie nie im Quellcode oder committe sie in die Versionskontrolle.
AURIS_CLIENT_ID=your-m2m-client-id
AURIS_CLIENT_SECRET=your-m2m-client-secret
AURIS_DOMAIN=auth.yourdomain.comImplementierung
JavaScript
import { AurisClient } from '@auris/js'
const auris = new AurisClient({
domain: process.env.AURIS_DOMAIN,
clientId: process.env.AURIS_CLIENT_ID,
})
// M2M-Access-Token mit bestimmten Scopes anfordern
const token = await auris.getM2MToken(
process.env.AURIS_CLIENT_SECRET,
['read:users', 'manage:roles'],
)
console.log('Access Token:', token.accessToken)
console.log('Läuft ab in:', token.expiresIn, 'Sekunden')
// Token verwenden, um die Auris Management API aufzurufen
const usersResponse = await fetch('https://auth.yourdomain.com/api/users', {
headers: { Authorization: `Bearer ${token.accessToken}` },
})
const users = await usersResponse.json()Token-Format
M2M-Access-Tokens sind JWTs mit folgenden Claims:
{
"iss": "https://auth.yourdomain.com",
"sub": "your-client-id",
"aud": "https://auth.yourdomain.com",
"exp": 1735000000,
"iat": 1734996400,
"type": "m2m",
"scope": "read:users manage:roles",
"clientId": "your-client-id"
}Der type: 'm2m'-Claim unterscheidet diese Tokens von Benutzer-Tokens (type: 'user'). Deine APIs können diesen Claim verwenden, um zwischen Benutzer- und Service-Anfragen zu unterscheiden.
Token-Caching
M2M-Tokens sollten für ihre gesamte Gültigkeitsdauer gecacht werden, um unnötige Netzwerkaufrufe an den Token-Endpunkt zu vermeiden:
class TokenCache {
#token = null
#expiresAt = 0
async getToken(auris, clientSecret, scopes) {
// Gecachten Token zurückgeben, wenn noch gültig (mit 60s Puffer)
if (this.#token && Date.now() < this.#expiresAt - 60_000) {
return this.#token
}
const result = await auris.getM2MToken(clientSecret, scopes)
this.#token = result.accessToken
this.#expiresAt = Date.now() + result.expiresIn * 1000
return this.#token
}
}
const cache = new TokenCache()
// In deinen API-Aufrufen:
const token = await cache.getToken(auris, clientSecret, ['read:users'])DPoP-Token-Bindung
Für Umgebungen, die senderkonstante Tokens erfordern, unterstützt Auris DPoP (Demonstrating Proof of Possession, RFC 9449). DPoP bindet das Access Token an den öffentlichen Schlüssel eines bestimmten Clients — ein gestohlenes Token kann ohne den entsprechenden privaten Schlüssel nicht von einem anderen Client verwendet werden.
DPoP für M2M-Anwendungen aktivieren:
- DPoP auf der M2M-Anwendung in Console → Applications → [App] → Settings → Require DPoP aktivieren
- Ein Schlüsselpaar in deinem Dienst generieren und bei jeder Token-Anfrage und jedem API-Aufruf einen DPoP-Proof-Header einschließen
import { createDpopProof } from '@auris/js'
// DPoP-Schlüsselpaar generieren (einmalig beim Dienst-Start)
const dpopKeyPair = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' },
false, // nicht extrahierbar
['sign', 'verify'],
)
// Token mit DPoP anfordern
const dpopProof = await createDpopProof(dpopKeyPair, 'POST', tokenEndpointUrl)
const tokenResponse = await fetch(tokenEndpointUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'DPoP': dpopProof,
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
}),
})Eigene APIs mit M2M-Tokens schützen
Wenn deine Backend-APIs Auris-M2M-Tokens von anderen Diensten akzeptieren, validiere die Token-Signatur mit dem Auris-JWKS-Endpunkt:
import { verifyToken } from '@auris/js/jwt-verify'
export async function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization
if (!authHeader?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Fehlender Authorization-Header' })
}
const token = authHeader.slice(7)
try {
const payload = await verifyToken(token, {
jwksUrl: 'https://auth.yourdomain.com/.well-known/jwks.json',
issuer: 'https://auth.yourdomain.com',
})
// Prüfen, ob es ein M2M-Token ist (kein Benutzer-Token)
if (payload.type !== 'm2m') {
return res.status(403).json({ error: 'Benutzer-Tokens nicht auf diesem Endpunkt erlaubt' })
}
// Erforderliche Scopes prüfen
const scopes = payload.scope?.split(' ') ?? []
if (!scopes.includes('call:your-service')) {
return res.status(403).json({ error: 'Unzureichende Scopes' })
}
req.clientId = payload.sub
next()
} catch (err) {
return res.status(401).json({ error: 'Ungültiges Token' })
}
}API-Endpunkte
/api/auth/tokenToken-Endpunkt. grant_type=client_credentials, client_id, client_secret und optionale scope setzen. Gibt ein Access Token und Ablaufzeit zurück.
/api/applications/:id/m2m-scopesRequires: manage:applicationsListet die erlaubten Scopes für eine M2M-Anwendung auf.
/api/applications/:id/m2m-scopesRequires: manage:applicationsAktualisiert die erlaubten Scopes für eine M2M-Anwendung.
Verwandte Anleitungen
- Hosted Login (PKCE) — Interaktive Benutzerauthentifizierung
- Rollen und Berechtigungen (RBAC) — Steuern, was M2M-Clients tun können
- Fine-Grained Authorization — Objekt-Level-Zugriffskontrolle für M2M-Dienste