> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorization-Code-Flow

> Verwenden Sie den OAuth 2.0 Authorization-Code-Flow mit PKCE, um Benutzer über ABBYY Vantage zu authentifizieren und Zugriffstoken für die Vantage-API zu erhalten.

export const VantageRegion = ({children}) => {
  const STORAGE_KEY = "abbyy.vantage.region";
  const REGIONS = [{
    code: "eu",
    label: "Europe"
  }, {
    code: "us",
    label: "North America"
  }, {
    code: "au",
    label: "Australia / Asia-Pacific"
  }];
  const [region, setRegion] = useState("eu");
  const [open, setOpen] = useState(false);
  const containerRef = useRef(null);
  const dropdownRef = useRef(null);
  function safeGetSavedRegion() {
    try {
      const saved = typeof window !== "undefined" ? window.localStorage.getItem(STORAGE_KEY) : null;
      const valid = new Set(REGIONS.map(r => r.code));
      return saved && valid.has(saved) ? saved : "eu";
    } catch {
      return "eu";
    }
  }
  function safeSetSavedRegion(code) {
    try {
      if (typeof window !== "undefined") {
        window.localStorage.setItem(STORAGE_KEY, code);
      }
    } catch {}
  }
  function dispatchRegionChanged(code) {
    try {
      if (typeof window !== "undefined") {
        window.dispatchEvent(new CustomEvent("abbyy:region-changed", {
          detail: {
            code
          }
        }));
      }
    } catch {}
  }
  function replaceRegionInString(text, currentRegion) {
    if (typeof text !== "string") return text;
    const hostRegex = /https:\/\/vantage-(eu|us|au)\.abbyy\.com/gi;
    const tokenRegex = /https:\/\/vantage-\[region\]\.abbyy\.com/gi;
    const bareHostRegex = /vantage-(eu|us|au)\.abbyy\.com/gi;
    const bareTokenRegex = /vantage-\[region\]\.abbyy\.com/gi;
    return text.replace(hostRegex, `https://vantage-${currentRegion}.abbyy.com`).replace(tokenRegex, `https://vantage-${currentRegion}.abbyy.com`).replace(bareHostRegex, `vantage-${currentRegion}.abbyy.com`).replace(bareTokenRegex, `vantage-${currentRegion}.abbyy.com`);
  }
  useEffect(() => {
    setRegion(safeGetSavedRegion());
  }, []);
  useEffect(() => {
    const root = containerRef.current;
    if (!root) return;
    const anchors = root.querySelectorAll("a[href]");
    anchors.forEach(a => {
      const href = a.getAttribute("href");
      if (href) {
        const next = replaceRegionInString(href, region);
        if (next !== href) {
          a.setAttribute("href", next);
        }
      }
    });
    const walker = typeof document !== "undefined" ? document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null) : null;
    if (walker) {
      const toUpdate = [];
      let node = walker.nextNode();
      while (node) {
        const updated = replaceRegionInString(node.nodeValue, region);
        if (updated !== node.nodeValue) {
          toUpdate.push([node, updated]);
        }
        node = walker.nextNode();
      }
      toUpdate.forEach(([textNode, value]) => {
        textNode.nodeValue = value;
      });
    }
  }, [region, children]);
  useEffect(() => {
    const root = containerRef.current;
    if (!root) return;
    const anchors = root.querySelectorAll("a[href]");
    anchors.forEach(a => {
      a.style.fontWeight = "600";
      a.style.textDecoration = "underline";
      a.style.textUnderlineOffset = "2px";
    });
  }, [region, children]);
  useEffect(() => {
    const onRegionChanged = evt => {
      const code = evt && evt.detail && evt.detail.code;
      if (!code || code === region) return;
      setRegion(code);
    };
    if (typeof window !== "undefined") {
      window.addEventListener("abbyy:region-changed", onRegionChanged);
    }
    return () => {
      if (typeof window !== "undefined") {
        window.removeEventListener("abbyy:region-changed", onRegionChanged);
      }
    };
  }, [region]);
  useEffect(() => {
    const onClickAway = e => {
      if (!dropdownRef.current) return;
      if (!dropdownRef.current.contains(e.target)) {
        setOpen(false);
      }
    };
    document.addEventListener("click", onClickAway, true);
    return () => document.removeEventListener("click", onClickAway, true);
  }, []);
  const onSelect = code => {
    setRegion(code);
    safeSetSavedRegion(code);
    dispatchRegionChanged(code);
    setOpen(false);
  };
  const current = REGIONS.find(r => r.code === region) || REGIONS[0];
  return <div className="not-prose">
      <div className="mb-4 inline-flex items-center gap-2" ref={dropdownRef}>
        <span className="text-sm text-zinc-950/80 dark:text-white/80">Tenant Region:</span>
        <div className="relative">
          <button type="button" aria-haspopup="listbox" aria-expanded={open ? "true" : "false"} onClick={() => setOpen(v => !v)} className="h-8 px-3 rounded-md bg-zinc-900/5 dark:bg-white/5 border border-zinc-950/20 dark:border-white/20 text-sm inline-flex items-center gap-2">
            <span className="text-zinc-950 dark:text-white">{current.label}</span>
            <svg width="8" height="24" viewBox="0 -9 3 24" className="transition-transform text-gray-400 overflow-visible dark:text-gray-600 ml-auto" style={{
    transform: open ? "rotate(270deg)" : "rotate(90deg)"
  }}>
              <path d="M0 0L3 3L0 6" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"></path>
            </svg>
          </button>
          {open ? <div role="listbox" className="absolute z-50 left-full top-0 ml-2 w-56 rounded-xl border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-900 shadow-lg p-2">
              {REGIONS.map(r => {
    const selected = r.code === region;
    return <button key={r.code} type="button" role="option" aria-selected={selected ? "true" : "false"} onClick={() => onSelect(r.code)} className={"w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm hover:bg-zinc-950/5 dark:hover:bg-white/10 text-zinc-950 dark:text-white" + (selected ? " font-medium" : "")}>
                    <span style={selected ? {
      color: "#ff2038"
    } : undefined}>{r.label}</span>
                    <span className={selected ? "ml-3" : "ml-3 invisible"} style={selected ? {
      color: "#ff2038"
    } : undefined}>✓</span>
                  </button>;
  })}
            </div> : null}
        </div>
      </div>
      <div ref={containerRef} className="prose dark:prose-invert max-w-none">{children}</div>
    </div>;
};

Dieses Authentifizierungsverfahren gilt als das sicherste, da die Anwendung die Authentifizierungsanfrage nicht an den Benutzer, sondern an den Vantage-Authorization-Server richtet. Der Authorization-Server authentifiziert anschließend den Benutzer und gibt den Autorisierungscode an den Client zurück.

Um zu verhindern, dass der Autorisierungscode abgefangen wird, verwendet dieses Authentifizierungsszenario eine Sicherheitserweiterung namens PKCE (Proof Key for Code Exchange). Diese Erweiterung funktioniert wie folgt: Für jede Autorisierungsanfrage wird eine kryptografische Zufallszahl erzeugt und in **code\_verifier** gespeichert. Diese wird anschließend verwendet, um einen kryptografisch abgeleiteten Wert zu erzeugen, der in **code\_challenge** gespeichert ist. Dieser neue Wert wird dann an den Authorization-Server gesendet, um einen Autorisierungscode zu erhalten.

Weitere Informationen zu PKCE finden Sie unter [diesem Link](https://datatracker.ietf.org/doc/html/rfc7636).

<div id="getting-the-authorization-code">
  #### Abrufen des Autorisierungscodes
</div>

Um den Authentifizierungsprozess zu starten, leiten Sie den Benutzer an den Authorize-Endpunkt weiter und übergeben dabei die folgenden Parameter:

| Parameter                                      | Beschreibung                                                                                                                                                                               |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| client\_id                                     | Die Anwendungskennung. Informationen zum Erstellen eines Vantage-API-Clients (**client\_id** und **client\_secret**) finden Sie im Artikel zur Verwaltung von Mandant Vantage API Clients. |
| redirect\_uri                                  | Die URL Ihrer Anwendung oder Website, an die der Browser weitergeleitet wird, sobald Zugriffsberechtigungen erteilt wurden.                                                                |
| response\_type=code                            | Gibt an, dass der Antworttyp „authorization code“ verwendet wird.                                                                                                                          |
| scope=openid permissions global.wildcard       | Gibt den Berechtigungsumfang an.                                                                                                                                                           |
| state                                          | Ein beliebiger string-Wert, der das Autorisierungsergebnis in der Antwort enthält.                                                                                                         |
| code\_challenge                                | Digital signierter Wert des **code\_verifier** (unter Verwendung der **code\_challenge\_method**).                                                                                         |
| code\_challenge\_method                        | Die Signaturmethode für den **code\_verifier** (S256).                                                                                                                                     |
| productId=a8548c9b-cb90-4c66-8567-d7372bb9b963 | Die Vantage-Kennung.                                                                                                                                                                       |

<Warning>
  Die Werte für response\_type, scope, productId müssen genau wie oben angegeben sein. Diese Schlüssel – außer response\_type – können sich ändern. Erwägen Sie, sie in der Konfiguration zu halten.
</Warning>

Beispielanforderung

<VantageRegion>
  ```shell wrap theme={null}
  https://vantage-us.abbyy.com/auth2/connect/authorize?client_id=client_id&redirect_uri=https%3A%2F%2Fvantage-us.abbyy.com%2Flogin-callback&response_type=code&scope=openid%20permissions%20global.wildcard&state=ef30939211cc4ecb9a7a349b855c6a10&code_challenge=tA6ayQ5VUjLX2tufAKaHh-9bTAQ4hQQY5VZAoB2kG9o&code_challenge_method=S256&productId=a8548c9b-cb90-4c66-8567-d7372bb9b963
  ```
</VantageRegion>

Ein Parameter mit dem Namen redirect\_uri, der den Bezeichner Ihrer Ressource enthält, wird in OAuth 2.0 verwendet, damit Vantage den Autorisierungscode an Ihre Ressource senden und diesen Code anschließend gegen das Zugriffstoken eintauschen kann, das für die Authentifizierung bei allen nachfolgenden API-Aufrufen erforderlich ist. Bei Verwendung dieser Authentifizierungsmethode muss der Wert des Parameters redirect\_uri dem technischen Support von ABBYY bereitgestellt werden, damit er von den Administratoren auf die Allowlist gesetzt wird.

Sobald die mit dem Parameter scope angeforderten Zugriffsberechtigungen als gewährt verifiziert wurden, wird der Browser auf eine spezielle Webseite weitergeleitet, die vom Vantage-Server bereitgestellt wird. Diese Webseite enthält ein Dialogfenster, über das Sie sich mit Ihrem Konto autorisieren. Diese Seite sollte in einem Browser geöffnet werden, der eine sichtbare Adressleiste hat, sodass Sie die Seiten-URL und den Status des SSL-Zertifikats der Verbindung überprüfen können.

Wenn Ihre E-Mail-Adresse mit mehreren Konten in verschiedenen Mandanten verknüpft ist, werden Sie aufgefordert, einen Mandanten auszuwählen und Ihr Passwort einzugeben, nachdem Sie Ihre E-Mail-Adresse angegeben haben. Sie können Ihren Mandant-Bezeichner (den Parameter tokenId) auch direkt über eine der folgenden Ressourcen übermitteln:

<VantageRegion>
  ```shell wrap theme={null}
  https://vantage-us.abbyy.com/auth2/{tenantId}/connect/authorize?client_id=client_id&redirect_uri=external_app_redirect_uri&response_type=code
  &scope=openid%20permissions%20global.wildcard&state=state&code_challenge=code_challenge
  &code_challenge_method=S256&productId=a8548c9b-cb90-4c66-8567-d7372bb9b963
  ```
</VantageRegion>

oder

<VantageRegion>
  ```shell wrap theme={null}
  https://vantage-us.abbyy.com/auth2/connect/authorize?client_id=client_id&redirect_uri=external_app_redirect_uri&response_type=code
  &scope=openid%20permissions%20global.wildcard&state=state&code_challenge=code_challenge
  &code_challenge_method=S256&productId=a8548c9b-cb90-4c66-8567-d7372bb9b963&tenantId=tenantId
  ```
</VantageRegion>

Sie werden aufgefordert, das Passwort für Ihr Mandantenkonto einzugeben. Nachdem Sie Ihre Anmeldedaten eingegeben haben, wird die Autorisierung serverseitig abgeschlossen, die Anwendung erhält Zugriff auf die Vantage-API, und Sie erhalten den Autorisierungscode in der Antwort auf Ihre Anfrage.

Bitte beachten Sie, dass Vantage-Benutzer, wenn eine Website oder Anwendung diesen Authentifizierungstyp verwendet, dieser Website oder App, die Sie zur Liste der zulässigen Redirect-URLs hinzufügen, in ihrem Namen Zugriff auf die Vantage-API gewähren. Um der Website oder App Zugriff zu gewähren, werden Benutzer aufgefordert, sich mit ihrem Benutzernamen und Passwort in Vantage zu authentifizieren. Sobald ein Benutzer authentifiziert ist, erhält die Website oder App die folgenden Berechtigungen:

* Verwalten von Datenkatalogen im Vantage-Tenant im Namen des Benutzers,
* Zugriff auf Skills im Vantage-Tenant im Namen des Benutzers,
* Erstellen von und Zugriff auf Vantage-Vorgänge im Namen des Benutzers.

Die Website oder App kann das Passwort des Benutzers nicht ändern, die Liste der Benutzer in einem Vantage-Tenant nicht ändern oder Skills bearbeiten. Es wird nur Zugriff auf die Vantage-API gewährt. Der Benutzer kann den einmal gewährten Zugriff nicht widerrufen.

<div id="getting-the-authorization-token">
  #### Abrufen des Autorisierungs-Tokens
</div>

Sobald Sie den Autorisierungscode erhalten haben, haben Sie eine Minute Zeit, ihn gegen das Zugriffstoken einzutauschen. Senden Sie dazu eine POST-Anfrage an den Token-Endpunkt mit Daten im Format `application/x-www-form-urlencoded`.

Parameter des Anfragetexts:

| Parameter                                                | Beschreibung                                                                                                      |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| code\_verifier                                           | Der von Ihnen generierte Code. Wird benötigt, um die Einleitung der Autorisierungsanfrage zu bestätigen.          |
| client\_id                                               | Die Anwendungs-ID.                                                                                                |
| client\_secret                                           | Sicherer Anwendungsschlüssel.                                                                                     |
| code                                                     | Ihr vom Server erhaltener Autorisierungscode.                                                                     |
| redirect\_uri                                            | Die in Schritt „authorize“ verwendete Weiterleitungs-URL.                                                         |
| grant\_type=authorization\_code                          | Gibt an, dass der Grant-Typ „authorization code“ verwendet wird.                                                  |
| scope=openid permissions global.wildcard offline\_access | Gibt den Berechtigungsumfang an. Um ein Refresh-Token zu erhalten, fügen Sie **offline\_access** zum Scope hinzu. |

Beispielanfrage:

Für Windows:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST "https://vantage-eu.abbyy.com/auth2/connect/token" \
    --data-urlencode "code_verifier=code_verifier" \
    --data-urlencode "client_id=client_id" \
    --data-urlencode "client_secret=client_secret" \
    --data-urlencode "code=authorization code" \
    --data-urlencode "redirect_uri=external app redirect uri" \
    --data-urlencode "grant_type=authorization_code"
  ```
</VantageRegion>

Für Linux:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST 'https://vantage-eu.abbyy.com/auth2/connect/token' \
    --data-urlencode 'code_verifier=code_verifier' \
    --data-urlencode 'client_id=client_id' \
    --data-urlencode 'client_secret=client_secret' \
    --data-urlencode 'code=authorization code' \
    --data-urlencode 'redirect_uri=external app redirect uri' \
    --data-urlencode 'grant_type=authorization_code'
  ```
</VantageRegion>

Die Serverantwort auf Ihre Anfrage enthält das Zugriffstoken:

```json theme={null}
{
  "id_token": "<redacted>",
  "access_token": "<redacted>",
  "expires_in": 86400,
  "token_type": "Bearer",
  "refresh_token": "<redacted>",
  "scope": "openid permissions global.wildcard offline_access legacy.client"
}
```

Weitere Informationen zum Authorization-Code-Flow finden Sie unter [diesem Link](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1).

Für jeden Flow enthält der Schlüssel **access\_token** das Token, während der Schlüssel **expires\_in** angibt, nach wie vielen Sekunden das Token abläuft. Standardmäßig beträgt die Lebensdauer eines Zugriffstokens 24 Stunden (weitere Informationen finden Sie unter [Token lifetimes](#token-lifetimes)). Fügen Sie allen Ihren Anfragen den folgenden Authorization-Header hinzu und ersetzen Sie `token` durch den von Ihnen erhaltenen Wert:

```shell theme={null}
-H "Authorization: Bearer token"
```

Beachten Sie, dass Sie mit demselben Konto mehrere Token anfordern können. Weitere Informationen zum Autorisierungs-Token finden Sie unter [diesem Link](https://datatracker.ietf.org/doc/html/rfc6749#section-7.1).

<div id="getting-the-refresh-token">
  #### Abrufen des Refresh-Tokens
</div>

Wenn die Option `Allow issuing refresh tokens to refresh access tokens` bei der Konfiguration des Vantage-API-Clients aktiviert war und die Anforderung zum Abrufen des Access-Tokens den Parameter `scope=openid permissions global.wildcard offline_access` enthielt, erhalten Sie in der Antwort zusätzlich ein Refresh-Token. Sobald Sie ein Refresh-Token haben, können Sie das Access-Token mit einer POST-Anforderung an den Token-Endpunkt und den folgenden Parametern aktualisieren:

| Parameter                  | Beschreibung                                                 |
| -------------------------- | ------------------------------------------------------------ |
| client\_id                 | Die Anwendungs-ID.                                           |
| client\_secret             | Ein sicherer Anwendungsschlüssel.                            |
| refresh\_token             | Ihr vom Server erhaltenes Refresh-Token.                     |
| grant\_type=refresh\_token | Gibt an, dass der Grant-Typ „refresh\_token“ verwendet wird. |

Beispielanforderung:

Für Windows:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST "https://vantage-eu.abbyy.com/auth2/connect/token" \
    --data-urlencode "client_id=client_id" \
    --data-urlencode "client_secret=client_secret" \
    --data-urlencode "refresh_token=refresh_token" \
    --data-urlencode "grant_type=refresh_token"
  ```
</VantageRegion>

Für Linux:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST 'https://vantage-eu.abbyy.com/auth2/connect/token' \
    --data-urlencode 'client_id=client_id' \
    --data-urlencode 'client_secret=client_secret' \
    --data-urlencode 'refresh_token=refresh_token' \
    --data-urlencode 'grant_type=refresh_token'
  ```
</VantageRegion>

<div id="token-lifetimes">
  #### Tokenlaufzeiten
</div>

Access- und Refresh-Token sind so konfiguriert, dass sie folgende Laufzeiten haben:

* **Laufzeit des Access-Tokens:** Definiert den Zeitraum, in dem das ausgegebene Access-Token dem Benutzer Zugriff auf Vantage gewährt. Die Standardlaufzeit eines Access-Tokens beträgt 24 Stunden.
* **Laufzeit des Refresh-Tokens:** Definiert den absoluten Zeitraum ab der Ausstellung des ersten Access-Tokens, in dem das ausgegebene Refresh-Token verwendet werden kann, um das Access-Token zu erneuern. Die Standardlaufzeit eines Refresh-Tokens beträgt 30 Tage.
