> ## 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.

# Resource Owner Password Credentials

> Verwenden Sie den OAuth 2.0 Resource Owner Password Credentials Flow, um sich mit Benutzername und Kennwort direkt bei der ABBYY Vantage-API zu authentifizieren (ohne Browser).

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 ist relativ einfach und ermöglicht der Anwendung, sich ohne Browseranwendung anzumelden, indem Benutzername und Passwort direkt verarbeitet werden.

Wenn für einen Mandanten ein externer Identity Provider konfiguriert ist, funktioniert das Authentifizierungsverfahren Resource Owner Password Credentials nicht.

So erhalten Sie das Zugriffstoken:

1. Eine POST-Anfrage.
2. Den Token-Endpunkt. Wenn Ihre E-Mail-Adresse mehreren Konten in verschiedenen Mandanten zugeordnet ist und Sie dieses Verfahren verwenden, nutzen Sie `https://vantage-<region>.abbyy.com/auth2/{tenantId}/connect/token`. Die Ressource `https://vantage-<region>.abbyy.com/auth` ist veraltet.
3. Einen `Content-Type`-Header mit der Kodierung `application/x-www-form-urlencoded`.
4. Einen Request-Body mit den folgenden Parametern:

| Parameter                                | Beschreibung                                         |
| ---------------------------------------- | ---------------------------------------------------- |
| grant\_type=password                     | Gibt an, dass der Passwort-Grant-Typ verwendet wird. |
| scope=openid permissions global.wildcard | Gibt den Berechtigungsumfang an.                     |
| username and password                    | Ihre Zugangsdaten.                                   |
| client\_id                               | Anwendungsbezeichner.                                |
| client\_secret                           | Geheimer Anwendungsschlüssel.                        |

Beispielanfrage:

Für Windows:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST "https://vantage-us.abbyy.com/auth2/connect/token" \
    --data-urlencode "grant_type=password" \
    --data-urlencode "scope=openid permissions global.wildcard" \
    --data-urlencode "username=e-mail" \
    --data-urlencode "password=password" \
    --data-urlencode "client_id=client_id" \
    --data-urlencode "client_secret=client_secret"
  ```
</VantageRegion>

Für Linux:

<VantageRegion>
  ```shell theme={null}
  curl --location --request POST 'https://vantage-us.abbyy.com/auth2/connect/token' \
    --data-urlencode 'grant_type=password' \
    --data-urlencode 'scope=openid permissions global.wildcard' \
    --data-urlencode 'username=e-mail' \
    --data-urlencode 'password=password' \
    --data-urlencode 'client_id=client_id' \
    --data-urlencode 'client_secret=client_secret'
  ```
</VantageRegion>

Die Serverantwort auf Ihre Anfrage enthält das Zugriffstoken:

```json theme={null}
{
  "access_token": "<redacted>",
  "expires_in": 2592000,
  "token_type": "Bearer",
  "scope": "openid permissions global.wildcard"
}
```

Weitere Informationen zu den Resource Owner Password Credentials finden Sie unter [diesem Link](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3).
