Auth-Guard-Modul
Mit dem Auth-Guard-Modul kannst du während des Anmeldevorgangs des Benutzers zusätzliche Authentifizierungs- und Autorisierungsprüfungen implementieren. Dieses Modul wird nach der Standardauthentifizierung (Passwort, MFA, Geräteüberprüfung), aber vor der Gewährung des Zugriffs ausgeführt. Es eignet sich ideal zur Durchsetzung von Compliance-Richtlinien (z. B. rechtliche Vereinbarungen, Sicherheitsprüfungen), zum Hinzufügen benutzerdefinierter Multifaktor-Autorisierung oder zur Validierung von mTLS-Zertifikaten.
{ "modules": { "auth-guard": [ { "key": "your-module-key", "name": "IP Whitelist Check", "description": "Verifies user IP address", "url": "/api/auth/verify", "options": { "type": "direct", "applyToAdmins": false } } ] }}key | Typ: Erforderlich: ja Beschreibung: Kennung des Moduls innerhalb der Crowdin-App. |
name | Typ: Erforderlich: ja Beschreibung: Für Benutzer während der Überprüfung angezeigter, für Menschen lesbarer Name. |
description | Typ: Erforderlich: nein Beschreibung: Zusätzliche Beschreibung, die Benutzern angezeigt wird. Nur für den Überprüfungstyp |
url | Typ: Erforderlich: ja Beschreibung: Endpunkt-URL für die Überprüfung. Relativ zu |
options | Typ: Erforderlich: nein Beschreibung: Konfigurationsoptionen des Moduls. |
options.type | Typ: Zulässige Werte: Standard: Beschreibung: Interaktionstyp der Überprüfung. |
options.applyToAdmins | Typ: Standard: Beschreibung: Gibt an, ob diese Prüfung auf Organisationsadministratoren angewendet werden soll. |
options.url | Typ: Erforderlich: ja (wenn der Typ Beschreibung: Für Benutzer sichtbare URL für die Interaktion. |
Kommunikation zwischen Auth-Guard-App und Crowdin
Abschnitt betitelt „Kommunikation zwischen Auth-Guard-App und Crowdin“Das Auth-Guard-Modul fungiert als Sicherheitskontrollpunkt innerhalb des Authentifizierungsprozesses. Es wird nach den standardmäßigen Überprüfungsschritten (Passwort, MFA, Gerätevertrauen), aber vor der Gewährung des Zugriffs auf die Organisation aufgerufen.
Je nach Konfiguration kann das Modul auf eine von drei Arten mit dem Benutzer interagieren:
- Direkter Typ: Genehmigt oder verweigert den Zugriff automatisch über einen Backend-API-Aufruf.
- Weiterleitungstyp: Leitet den Benutzer zur Überprüfung auf eine externe Seite weiter.
- Frame-Typ: Zeigt einen eingebetteten Iframe zur Überprüfung innerhalb der App an.
Das folgende Diagramm zeigt, an welcher Stelle das Auth-Guard-Modul in den Anmeldevorgang des Benutzers eingebunden ist:
User Login ↓Password Authentication ↓MFA Verification (if enabled) ↓Device Trust Verification (if enabled) ↓┌─────────────────────────┐│ Auth Guard Module(s) │ ← Your App└─────────────────────────┘ ↓Remember Me Confirmation (if enabled) ↓Access GrantedPro Organisation können mehrere Auth-Guard-Module konfiguriert werden. Sie werden nacheinander ausgeführt, und alle müssen erfolgreich durchlaufen werden, damit der Benutzer Zugriff erhält.
Der direkte Typ ist die einfachste Interaktionsmethode und eignet sich ideal für automatisierte Prüfungen, die keine Benutzereingabe erfordern (z. B. Zertifikatsvalidierung). Crowdin führt einen synchronen Server-zu-Server-API-Aufruf an deine App durch, die sofort (< 10 Sekunden) antworten muss.
┌─────────────┐ ┌──────────────┐│ Crowdin │ │ Your App │└──────┬──────┘ └──────┬───────┘ │ │ │ POST /api/auth/verify │ │ Authorization: Bearer <JWT> │ │ { │ │ "userId": 12345, │ │ "organizationId": 67890, │ │ "ipAddress": "192.168.1.1", │ │ "moduleKey": "your-module-key" │ │ } │ ├─────────────────────────────────────────────────>│ │ │ │ Process verification │ │ (IP check, etc.) │ │ │ │ { "success": true } │ │ or │ │ { │ │ "success": false, │ │ "message": "Access denied: IP not allowed" │ │ } │ │<─────────────────────────────────────────────────┤ │ │HTTP-Anfrage:
POST {AppBaseUrl}/api/auth/verifyAnfrage-Header
Die Anfrage an deine App enthält die folgenden Header:
Authorization: Bearer \<JWT_TOKEN>Content-Type: application/json
Beispiel für den Anfrageinhalt:
{ "userId": 12345, "organizationId": 67890, "ipAddress": "192.168.1.1", "moduleKey": "your-module-key"}Die App muss ein JSON-Objekt zurückgeben, das Erfolg oder Misserfolg angibt.
Beispiel für den Antwortinhalt (Erfolg):
{ "success": true}Beispiel für den Antwortinhalt (Fehler):
{ "success": false, "message": "Access denied: Your IP address is not in the allowlist"}Der Weiterleitungstyp leitet den Benutzer zur Überprüfung auf eine externe Seite weiter und anschließend zurück zu Crowdin. Dieser Typ eignet sich, wenn eine Benutzerinteraktion erforderlich ist (z. B. das Akzeptieren von Bedingungen, das Lösen eines CAPTCHA oder die Integration externer OAuth-/SAML-Anbieter).
┌─────────┐ ┌──────────────┐ ┌──────────┐│ User │ │ Crowdin │ │ Your App │└────┬────┘ └──────┬───────┘ └────┬─────┘ │ │ │ │ 1. Login attempt │ │ ├───────────────────────────────────>│ │ │ │ │ │ │ Try POST /api/auth/verify │ │ │ (with empty body initially) │ │ ├─────────────────────────────────>│ │ │ │ │ │ { "success": false } │ │ │ (needs user interaction) │ │ │<─────────────────────────────────┤ │ │ │ │ 2. HTTP 302 Redirect │ │ │ Location: https://your-app/page │ │ │ ?jwtToken=<JWT>&state=<STATE> │ │ │<───────────────────────────────────┤ │ │ │ │ │ 3. GET /page?jwtToken=...&state=... │ ├──────────────────────────────────────────────────────────────────────>│ │ │ │ │ │ Verify JWT token │ │ │ Show verification UI │ │ │ │ │ 4. Display verification page │ │<──────────────────────────────────────────────────────────────────────┤ │ │ │ │ 5. User completes verification │ │ (clicks approve/deny) │ │ ├──────────────────────────────────────────────────────────────────────>│ │ │ │ │ │ Generate code │ │ │ │ │ 6. HTTP 302 Redirect back │ │ Location: https://accounts.../callback │ │ ?state=<STATE>&code=<CODE> │ │ │ or ...?state=<STATE>&error=... │ │ │<──────────────────────────────────────────────────────────────────────┤ │ │ │ │ 7. GET /callback?state=...&code=... │ ├───────────────────────────────────>│ │ │ │ │ │ │ POST /api/auth/verify │ │ │ { │ │ │ "code": "<CODE>", │ │ │ "userId": ..., │ │ │ "organizationId": ..., │ │ │ "ipAddress": ..., │ │ │ "moduleKey": "..." │ │ │ } │ │ ├─────────────────────────────────>│ │ │ │ │ │ { "success": true } │ │ │<─────────────────────────────────┤ │ │ │ │ 8. Access granted │ │ │<───────────────────────────────────┤ │ │ │ │Crowdin versucht zunächst eine direkte Prüfung, um festzustellen, ob der Zugriff automatisch gewährt werden kann.
HTTP-Anfrage:
POST {AppBaseUrl}/api/auth/verifyAnfrage-Header
Die Anfrage an deine App enthält die folgenden Header:
Authorization: Bearer \<JWT_TOKEN>Content-Type: application/json
Beispiel für den Anfrageinhalt:
{ "userId": 12345, "organizationId": 67890, "ipAddress": "192.168.1.1", "moduleKey": "your-module-key"}Erwartete Antwort (Weiterleitung auslösen):
Um den Weiterleitungsablauf auszulösen, muss deine App success: false zurückgeben.
{ "success": false }Wenn die erste Prüfung false zurückgibt, leitet Crowdin den Benutzer an die in den Manifestoptionen definierte url weiter.
Struktur der Weiterleitungs-URL:
https://{your-app-url}?jwtToken=<JWT>&state=<STATE>Deine App muss das jwtToken validieren, die Überprüfungsoberfläche anzeigen und den Benutzer nach erfolgreicher Prüfung über eine HTTP-302-Weiterleitung zurück zu Crowdin leiten.
Bei Erfolg:
HTTP 302 RedirectLocation: https://accounts.crowdin.com/{domain}/guard/callback?state=<STATE>&code=<CODE>Bei Fehler:
HTTP 302 RedirectLocation: https://accounts.crowdin.com/{domain}/guard/callback?state=<STATE>&error=User+denied+accessSobald Crowdin den code aus dem Callback erhalten hat, sendet es eine abschließende Anfrage an deine App, um ihn zu überprüfen.
HTTP-Anfrage:
POST {AppBaseUrl}/api/auth/verifyAnfrage-Header
Authorization: Bearer \<JWT_TOKEN>Content-Type: application/json
Beispiel für den Anfrageinhalt:
{ "code": "abc123xyz", "userId": 12345, "organizationId": 67890, "ipAddress": "192.168.1.1", "moduleKey": "your-module-key"}Erwartete Antwort:
{ "success": true}Frame-Typ (eingebettete Benutzeroberfläche)
Abschnitt betitelt „Frame-Typ (eingebettete Benutzeroberfläche)“Der Frame-Typ zeigt deine Überprüfungsseite innerhalb eines Iframes in der Crowdin-Anmeldeoberfläche an. Dies ermöglicht eine nahtlose Benutzererfahrung für benutzerdefinierte Formulare oder mTLS-Prüfungen, während der Benutzer in der Crowdin-Umgebung bleibt.
┌─────────┐ ┌──────────────┐ ┌──────────┐│ User │ │ Crowdin │ │ Your App │└────┬────┘ └──────┬───────┘ └────┬─────┘ │ │ │ │ 1. Login attempt │ │ ├───────────────────────────────>│ │ │ │ │ │ │ Try POST /api/auth/verify │ │ ├─────────────────────────────────>│ │ │ │ │ │ { "success": false } │ │ │<─────────────────────────────────┤ │ │ │ │ 2. Show verification page │ │ │ with embedded iframe │ │ │<───────────────────────────────┤ │ │ │ │ │ 3. Iframe loads your URL │ │ │ GET /frame?jwtToken=... │ │ ├──────────────────────────────────────────────────────────────────>│ │ │ │ │ 4. Your verification UI │ │ │<──────────────────────────────────────────────────────────────────┤ │ │ │ │ 5. User interacts with iframe │ │ │ (clicks approve/deny) │ │ │────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ 6. JavaScript API call via │ │ │ │ Crowdin Apps SDK │ │ │ │ AP.verifyAuth({ code: "..."}) │ │ ├────────────────────────────────────────────────────────────────┼─>│ │ │ │ │ │ 7. Crowdin receives code │<──────────────────────────────┘ │ │ from iframe via postMessage│ │ │ │ │ │ │ POST /api/auth/verify │ │ │ { │ │ │ "code": "...", │ │ │ "userId": ..., │ │ │ "moduleKey": "..." │ │ │ } │ │ ├─────────────────────────────────>│ │ │ │ │ │ { "success": true } │ │ │<─────────────────────────────────┤ │ │ │ │ 8. Access granted │ │ │<───────────────────────────────┤ │ │ │ │Crowdin versucht zunächst eine direkte Prüfung, um festzustellen, ob der Zugriff automatisch gewährt werden kann.
HTTP-Anfrage:
POST {AppBaseUrl}/api/auth/verifyBeispiel für den Anfrageinhalt:
{ "userId": 12345, "organizationId": 67890, "ipAddress": "192.168.1.1", "moduleKey": "your-module-key"}Erwartete Antwort (Iframe auslösen):
Um den Iframe-Ablauf auszulösen, muss deine App success: false zurückgeben.
{ "success": false }Anzeige und Benutzeroberfläche des Iframes
Abschnitt betitelt „Anzeige und Benutzeroberfläche des Iframes“Wenn die erste Prüfung false zurückgibt, lädt Crowdin die url deiner App mit den folgenden Parametern in einem Iframe:
https://{your-app-url}?jwtToken=<JWT>Implementierung der Überprüfungsoberfläche:
Create an HTML page that initializes the Crowdin Apps SDK and handles the user interaction.
<!DOCTYPE html><html> <head> <title>Verification</title>
<script src="https://cdn.crowdin.com/apps/dist/host.js"></script> </head> <body> <h1>Security Verification</h1> <p>Please confirm your identity</p>
<button id="approve">Approve</button> <button id="deny">Deny</button>
<script> // Get parameters const urlParams = new URLSearchParams(window.location.search); const jwtToken = urlParams.get('jwtToken'); const state = urlParams.get('state');
document.getElementById('approve').addEventListener('click', async () => { // Generate verification code from your backend const code = await generateVerificationCode();
// Send success to Crowdin via SDK AP.verifyAuth({ code: code }); });
document.getElementById('deny').addEventListener('click', () => { // Send rejection to Crowdin AP.verifyAuth({ error: 'User denied access' }); });
async function generateVerificationCode() { // Call your backend to generate a code const response = await fetch('/api/generate-code', { method: 'POST', headers: { 'Authorization': `Bearer ${jwtToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ state }) }); const data = await response.json(); return data.code; } </script> </body></html>Verwende die Methode AP.verifyAuth(), um das Ergebnis an Crowdin zurückzumelden.
Erfolg:
AP.verifyAuth({ code: "your-verification-code"});Fehler:
AP.verifyAuth({ error: "Verification failed: device not trusted"});Sobald Crowdin den code vom SDK erhält, sendet es eine abschließende Anfrage an deine App, um ihn zu überprüfen.
HTTP-Anfrage:
POST {AppBaseUrl}/api/auth/verifyBeispiel für den Anfrageinhalt:
{ "code": "abc123xyz", "userId": 12345, "organizationId": 67890, "ipAddress": "192.168.1.1", "moduleKey": "your-module-key"}Erwartete Antwort:
{ "success": true}