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

> Utilisez le flux OAuth 2.0 Resource Owner Password Credentials pour vous authentifier directement à l’API Vantage d’ABBYY à l’aide d’un nom d’utilisateur et d’un mot de passe (sans navigateur).

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>;
};

Ce schéma d’authentification est relativement simple et permet à l’application de se connecter au système de l’utilisateur sans passer par le navigateur en traitant directement le nom d’utilisateur et le mot de passe.

Si un fournisseur d’identité externe est configuré pour un tenant, le schéma d’authentification Resource Owner Password Credentials ne fonctionnera pas.

Pour obtenir le jeton d’accès, procédez comme suit :

1. Envoyez une requête POST.
2. Utilisez le point de terminaison du jeton. Si votre adresse e‑mail est associée à plusieurs comptes dans différents tenants et que vous utilisez cette authentification, utilisez `https://vantage-<region>.abbyy.com/auth2/{tenantId}/connect/token`. La ressource `https://vantage-<region>.abbyy.com/auth` est obsolète.
3. Ajoutez un en‑tête `Content-Type` avec l’encodage `application/x-www-form-urlencoded`.
4. Fournissez un corps de requête avec les paramètres suivants :

| Parameter                                | Description                                                |
| ---------------------------------------- | ---------------------------------------------------------- |
| grant\_type=password                     | Indique que le type d’octroi par mot de passe est utilisé. |
| scope=openid permissions global.wildcard | Indique le périmètre d’autorisation.                       |
| username and password                    | Vos identifiants.                                          |
| client\_id                               | Identifiant de l’application.                              |
| client\_secret                           | Clé secrète de l’application.                              |

Exemple de requête :

Pour 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>

Pour 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>

La réponse du serveur à votre requête contiendra le jeton d’accès :

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

Pour plus d’informations sur les informations d’identification du propriétaire de la ressource (Resource Owner Password Credentials), consultez [ce lien](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3).
