Zum Hauptinhalt springen

Erstelle ein benutzerdefiniertes Zugangstoken-Skript

Um benutzerdefinierte Ansprüche zum Zugangstoken hinzuzufügen, musst du ein Skript bereitstellen, das ein Objekt mit diesen Ansprüchen zurückgibt. Das Skript sollte als JavaScript-Funktion geschrieben werden, die ein Objekt mit den benutzerdefinierten Ansprüchen zurückgibt.

  1. Navigiere zu Konsole > Benutzerdefiniertes JWT.

  2. Es gibt zwei verschiedene Typen von Zugangstokens, für die du die Zugangstoken-Ansprüche anpassen kannst:

    • Benutzer-Zugangstoken: Das Zugangstoken, das für Endbenutzer ausgestellt wird. Z. B. für Webanwendungen oder mobile Anwendungen.
    • Maschine-zu-Maschine-Zugangstoken: Das Zugangstoken, das für Dienste oder Anwendungen ausgestellt wird. Z. B. für Maschine-zu-Maschine-Anwendungen.

    Verschiedene Typen von Zugangstokens können unterschiedliche Token-Payload-Kontexte haben. Du kannst die Token-Ansprüche für jeden Typ von Zugangstoken separat anpassen.

    Wähle einen beliebigen Typ von Zugangstoken aus, für den du die Token-Ansprüche anpassen möchtest, und klicke auf die Schaltfläche Benutzerdefinierte Ansprüche hinzufügen, um ein neues Skript zu erstellen.

hinweis:

Die Funktion für benutzerdefinierte Token-Ansprüche ist nur verfügbar für:

Implementiere die Funktion getCustomJwtClaims()​

Auf der Benutzerdefiniertes JWT-Detailseite findest du den Skript-Editor, um dein benutzerdefiniertes Token-Ansprüche-Skript zu schreiben. Das Skript sollte eine JavaScript-Funktion sein, die ein Objekt mit benutzerdefinierten Ansprüchen zurückgibt.

Detailseite für benutzerdefinierte Token-Ansprüche

Schritt 1: Bearbeite das Skript​

Nutze den Code-Editor auf der linken Seite, um das Skript zu bearbeiten. Eine Standardfunktion getCustomJwtClaims mit einem leeren Objekt als Rückgabewert wird dir als Ausgangspunkt bereitgestellt. Du kannst die Funktion anpassen, um ein Objekt mit deinen eigenen benutzerdefinierten Ansprüchen zurückzugeben.

const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
return {};
};

Dieser Editor verwendet den JavaScript Language Server, um grundlegendes Syntax-Highlighting, Code-Vervollständigung und Fehlerprüfung bereitzustellen. Die Eingabeparameter sind gut typisiert und im jsDoc-Stil dokumentiert. Du kannst die IntelliSense-Funktion des Editors nutzen, um korrekt auf die Eigenschaften des Eingabeobjekts zuzugreifen. Die detaillierten Parameterdefinitionen findest du auf der rechten Seite der Seite.

hinweis:

Diese Funktion wird als Modul exportiert. Stelle sicher, dass der Funktionsname getCustomJwtClaims bleibt, damit das Modul die Funktion korrekt exportieren kann.

Bei Benutzer-Zugangstokens sind die Authentifizierungskontext-Ansprüche acr, amr und auth_time von Logto reserviert (siehe Step-up Authentifizierung). Wenn dein Skript einen dieser Schlüssel zurückgibt, ignoriert Logto sie und behält seinen abgeleiteten Authentifizierungskontext bei.

Schritt 2: Eingabeparameter​

Die Funktion getCustomJwtClaims nimmt ein Objekt als Eingabeparameter entgegen. Das Eingabeobjekt enthält die folgenden Eigenschaften:

token​

Das Token-Payload-Objekt. Dieses Objekt enthält die ursprünglichen Token-Ansprüche und Metadaten, auf die du im Skript zugreifen kannst.

Die detaillierte Typdefinition des Token-Payload-Objekts und des Benutzerdaten-Objekts findest du auf der rechten Seite der Seite. Die IntelliSense-Funktion des Editors hilft dir ebenfalls, auf diese Eigenschaften des Eingabeobjekts korrekt zuzugreifen.

  • Benutzer-Zugangstoken-Datenobjekt
    EigenschaftBeschreibungTyp
    jtiDie eindeutige JWT-IDstring
    audDie Zielgruppe des Tokensstring
    scopeDie Berechtigungen des Tokensstring
    clientIdDie Client-ID des Tokensstring
    accountIdDie Benutzer-ID des Tokensstring
    expiresWithSessionOb das Token mit der Sitzung abläuftboolean
    grantIdDie aktuelle Authentifizierungs-Grant-ID des Tokensstring
    gtyDer Grant-Typ des Tokensstring
    kindDie Token-ArtAccessToken
  • Maschine-zu-Maschine-Zugangstoken-Datenobjekt
    EigenschaftBeschreibungTyp
    jtiDie eindeutige JWT-IDstring
    audDie Zielgruppe des Tokensstring
    scopeDie Berechtigungen des Tokensstring
    clientIdDie Client-ID des Tokensstring
    kindDie Token-ArtClientCredentials

context (Nur verfügbar für Benutzer-Zugangstoken)​

Das Kontextobjekt enthält die Benutzerdaten und Grant-Daten, die für den aktuellen Autorisierungsprozess relevant sind.

  • Benutzerdaten-Objekt Für Benutzer-Zugangstoken stellt Logto zusätzlichen Benutzerdaten-Kontext zur Verfügung, auf den du zugreifen kannst. Das Benutzerdaten-Objekt enthält alle Benutzerdaten des Profils und Organisationsmitgliedschaften, die du benötigst, um die benutzerdefinierten Ansprüche einzurichten. Siehe Benutzer und Organisationen für weitere Details.

  • Organisationsdaten-Objekt Für Organisations-Zugangstokens (ein Zugangstoken, das für eine bestimmte Organisation angefordert wurde), stellt Logto die Zielorganisation über context.organization bereit, sodass du organisationsspezifische Ansprüche anhängen kannst – zum Beispiel die Zuordnung der Logto-Organisations-ID zu einer internen ID, die in den benutzerdefinierten Daten der Organisation gespeichert ist. Dieses Datenobjekt ist nur vorhanden, wenn das Token für eine bestimmte Organisation ausgestellt wird, und enthält:

    EigenschaftBeschreibungTyp
    idDie eindeutige Organisations-IDstring
    nameDer Name der Organisationstring
    descriptionDie Beschreibung der Organisationstring | null
    customDataDie benutzerdefinierten Daten der OrganisationRecord<string, unknown>

    Siehe Organisationen für weitere Details.

  • Grant-Daten-Objekt Für Benutzer-Zugangstoken, die durch Impersonation-Token-Austausch gewährt wurden, stellt Logto zusätzlichen Grant-Daten-Kontext zur Verfügung. Das Grant-Daten-Objekt enthält den benutzerdefinierten Kontext aus dem Subjekt-Token. Siehe Benutzermimikry für weitere Details.

  • Benutzerinteraktionsdaten-Objekt Für ein gegebenes Benutzer-Zugangstoken kann es Fälle geben, in denen du auf die Interaktionsdetails des Benutzers für die aktuelle Autorisierungssitzung zugreifen musst. Zum Beispiel musst du möglicherweise die Enterprise SSO-Identität des Benutzers abrufen, die für die Anmeldung verwendet wurde. Dieses Benutzerinteraktionsdaten-Objekt enthält die zuletzt vom Benutzer übermittelten Interaktionsdaten, einschließlich:

    EigenschaftBeschreibungTyp
    interactionEventDas Interaktionsereignis der aktuellen BenutzerinteraktionSignIn oder Register
    userIdDie Benutzer-ID der aktuellen Benutzerinteraktionstring
    verificationRecordsEine Liste von Verifizierungsdatensätzen, die vom Benutzer eingereicht wurden, um seine Identität während der Interaktionen zu identifizieren und zu verifizieren.VerificationRecord[]

    Verifizierungsdatensatz-Typ:

    // VerificationType.Password
    {
    id: string;
    type: 'Password';
    identifier: {
    type: 'username' | 'email' | 'phone' | 'userId';
    value: string;
    }
    verified: boolean;
    }
    // VerificationType.EmailVerificationCode
    {
    id: string;
    templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
    verified: boolean;
    type: 'EmailVerificationCode';
    identifier: {
    type: 'email';
    value: string;
    }
    }
    // VerificationType.PhoneVerificationCode
    {
    id: string;
    templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
    verified: boolean;
    type: 'PhoneVerificationCode';
    identifier: {
    type: 'phone';
    value: string;
    }
    }
    // VerificationType.Social
    {
    id: string;
    type: 'Social';
    connectorId: string;
    socialUserInfo?: {
    id: string;
    email?: string | undefined;
    phone?: string | undefined;
    name?: string | undefined;
    avatar?: string | undefined;
    rawData?: Record<string, unknown> | undefined;
    } | undefined;
    }
    // VerificationType.EnterpriseSso
    {
    id: string;
    type: 'EnterpriseSso';
    connectorId: string;
    enterpriseUserInfo?: {
    id: string;
    email?: string | undefined;
    phone?: string | undefined;
    name?: string | undefined;
    avatar?: string | undefined;
    [key: string]?: unknown;
    } | undefined;
    issuer?: string | undefined;
    }
    // VerificationType.Totp (MFA)
    {
    id: string;
    type: 'Totp';
    userId: string;
    verified: boolean;
    }
    // VerificationType.WebAuthn (MFA)
    {
    id: string;
    type: 'WebAuthn';
    userId: string;
    verified: boolean;
    }
    // VerificationType.BackupCode (MFA)
    {
    id: string;
    type: "BackupCode";
    userId: string;
    code?: string | undefined;
    }
    // VerificationType.OneTimeToken
    {
    id: string;
    type: "OneTimeToken";
    verified: boolean;
    identifier: {
    type: "email";
    value: string;
    };
    oneTimeTokenContext?: {
    jitOrganizationIds?: string[] | undefined;
    } | undefined;
    }
    hinweis:

    Es kann mehrere Verifizierungsdatensätze im Benutzerinteraktionsdaten-Objekt geben, insbesondere wenn der Benutzer mehrere Anmelde- oder Registrierungsprozesse durchlaufen hat.

    Z. B. hat sich der Benutzer mit einem Social-Verifizierungsdatensatz angemeldet, dann eine neue E-Mail-Adresse über einen EmailVerificationCode-Verifizierungsdatensatz gebunden und anschließend den MFA-Status mit einem Totp-Verifizierungsdatensatz verifiziert. In diesem Fall musst du möglicherweise alle Verifizierungsdatensätze entsprechend in deinem Skript behandeln.

    Jeder Typ von Verifizierungsdatensatz ist nur einmal im Benutzerinteraktionsdaten-Objekt vorhanden.

environmentVariables​

Nutze den Bereich Umgebungsvariablen festlegen auf der rechten Seite, um die Umgebungsvariablen für dein Skript einzurichten. Du kannst diese Variablen verwenden, um sensible Informationen oder Konfigurationsdaten zu speichern, die du nicht im Skript fest codieren möchtest, z. B. API-Schlüssel, Geheimnisse oder URLs.

Alle hier festgelegten Umgebungsvariablen stehen im Skript zur Verfügung. Verwende das Objekt environmentVariables im Eingabeparameter, um auf diese Variablen zuzugreifen.

api​

Das api-Objekt stellt eine Reihe von Hilfsfunktionen bereit, die du in deinem Skript für zusätzliche Zugangskontrolle über den Token-Ausgabeprozess verwenden kannst. Das api-Objekt enthält die folgenden Funktionen:

api.denyAccess(message?: string): void

Die Funktion api.denyAccess() ermöglicht es dir, den Token-Ausgabeprozess mit einer benutzerdefinierten Nachricht zu verweigern. Du kannst diese Funktion verwenden, um zusätzliche Zugangsvalidierungen über den Token-Ausgabeprozess durchzusetzen.

Laufzeit-APIs​

Benutzerdefinierte Zugangstoken-Skripte können diese Standard-Web-APIs sowohl in Logto Cloud als auch im selbst gehosteten Logto verwenden:

  • fetch, Request, Response und Headers
  • Web Crypto über crypto und crypto.subtle
  • TextEncoder und TextDecoder
  • URL und URLSearchParams

Zum Beispiel kannst du SHA-256- und HMAC-SHA-256-Werte mit Web Crypto berechnen:

const toHex = (buffer) =>
[...new Uint8Array(buffer)].map((byte) => byte.toString(16).padStart(2, '0')).join('');

const sha256 = async (input) =>
toHex(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input)));

const hmacSha256 = async (key, input) => {
const encoder = new TextEncoder();
const cryptoKey = await crypto.subtle.importKey(
'raw',
encoder.encode(key),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);

return toHex(await crypto.subtle.sign('HMAC', cryptoKey, encoder.encode(input)));
};

Skripte können keine Pakete importieren. Vermeide Node.js-spezifische globale Variablen und Module, da sie nicht zwischen selbst gehostetem Logto und Logto Cloud portierbar sind und nicht Teil des unterstützten Skriptvertrags sind.

Schritt 3: Externe Daten abrufen​

Du kannst die Standardfunktion fetch verwenden, um externe Daten in deinem Skript abzurufen. Die Funktion fetch ist eine Promise-basierte Funktion, mit der du HTTP-Anfragen an externe APIs stellen kannst.

const getCustomJwtClaims = async ({ environmentVariables }) => {
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${environmentVariables.API_KEY}`,
},
});

const data = await response.json();

return {
data,
};
};
hinweis:

Beachte, dass das Abrufen externer Daten zu einer Verzögerung beim Token-Ausgabeprozess führen kann. Stelle sicher, dass die externe API zuverlässig und schnell genug ist, um deine Anforderungen zu erfüllen.

Außerdem gilt:

  • Behandle Fehler und Timeouts in deinem Skript ordnungsgemäß, um zu vermeiden, dass der Token-Ausgabeprozess blockiert wird.
  • Verwende geeignete Autorisierungs-Header, um deine externe API vor unbefugtem Zugriff zu schützen.

Schritt 4: Teste das Skript​

Stelle sicher, dass du dein Skript testest, bevor du es speicherst. Klicke auf den Tab Testkontext auf der rechten Seite der Seite, um die Mock-Token-Payload und den Benutzerdaten-Kontext zum Testen zu bearbeiten.

Klicke auf Test ausführen in der rechten oberen Ecke des Editors, um das Skript mit den Mock-Daten auszuführen. Die Ausgabe des Skripts wird im Testergebnis-Drawer angezeigt.

Benutzerdefiniertes JWT-Skript testen
hinweis:

Das Testergebnis ist die Ausgabe der Funktion getCustomJwtClaims mit den von dir festgelegten Mock-Daten („zusätzliche Token-Ansprüche“, die nach Abschluss von Schritt 3 im Ablaufdiagramm erhalten wurden). Die tatsächliche Token-Payload und der Benutzerdaten-Kontext werden unterschiedlich sein, wenn das Skript im Token-Ausgabeprozess ausgeführt wird.

Klicke auf die Schaltfläche Erstellen, um das Skript zu speichern. Das Skript für benutzerdefinierte Token-Ansprüche wird gespeichert und im Zugangstoken-Ausgabeprozess angewendet.