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

> 攻撃対策を有効にした状態で、サーバーサイド API を呼び出すために Resource Owner Password Flow を使用する際に発生しがちな問題を回避する方法を学びます。

# Resource Owner Password Flow と攻撃対策でよくある問題を回避する

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

<Warning>
  Resource Owner Password (ROP) Flow ではアプリケーションがユーザーのパスワードを扱うため、サードパーティのクライアントでは使用しないでください。
</Warning>

推奨はしていませんが、高信頼アプリケーションでは、[Resource Owner Password Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/resource-owner-password-flow) (<Tooltip tip="Resource Owner: 保護されたリソースへのアクセスを許可できるエンティティ（ユーザーやアプリケーションなど）。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Resource+Owner">リソース所有者</Tooltip> Password Grant または ROPG とも呼ばれます) を使用してサーバーサイド API を呼び出すことができます。このフローでは通常、対話型フォームを使用して、ユーザーに資格情報 (ユーザー名とパスワード) の入力を求めます。[総当たり攻撃対策が有効になっている](/docs/ja-jp/secure/attack-protection/brute-force-protection)場合、Auth0 が資格情報を検証する際に、[攻撃をチェックして](/docs/ja-jp/secure/attack-protection)、攻撃が検出されると適切な対応を行うこともあります。

ただし、このフローを<Tooltip tip="Brute-force Protection: 単一の IP アドレスから単一のユーザーアカウントを標的として行われる総当たり攻撃を防ぐ攻撃対策の一種。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=brute-force+protection">総当たり攻撃対策</Tooltip>と併用すると、一部の<Tooltip tip="Brute-force Protection: 単一の IP アドレスから単一のユーザーアカウントを標的として行われる総当たり攻撃を防ぐ攻撃対策の一種。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=attack+protection">攻撃対策</Tooltip>機能が正常に動作しないことがあります。ただし、よくある問題の一部は回避できます。

<div id="attack-protection-and-server-side-apis">
  ## 攻撃対策とサーバーサイド API
</div>

総当たり攻撃対策と<Tooltip tip="不審な IP スロットリング: 単一の IP アドレスから多数のアカウントを標的とする不審なログインからテナントを保護する攻撃対策の一種です。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=suspicious+IP+throttling">不審な IP スロットリング</Tooltip>では、ユーザーの IP アドレスが必要です。サーバーから API を呼び出すと、Auth0 はサーバーの IP アドレスをユーザーの IP アドレスとして扱い、総当たり攻撃対策と不審な IP スロットリングの判定に使用します。その結果、誤検知が発生し、正当なリクエストであっても攻撃対策によってユーザーがブロックされたり、警告がトリガーされたりする可能性があります。

これを避けるには、ユーザーの資格情報とあわせてユーザーの IP アドレスを Auth0 に送信し、その IP アドレスを信頼するようにアプリケーションを設定してください。

<Warning>
  セキュリティ上の理由により、この方法で設定できるのは、認証済みアプリケーション (クライアントシークレットに基づく認証を使用するものなど) に限られます。認証済みアプリケーションは、保護されたリソース (通常はサーバーサイド) からのみ使用してください。シークレットを保存できないため、ネイティブアプリケーションやシングルページアプリケーション (SPA) では使用しないでください。
</Warning>

<div id="configure-your-application-to-trust-the-ip-address">
  ## IP アドレスを信頼するようにアプリケーションを設定する
</div>

[通常の Web アプリケーション](/docs/ja-jp/get-started/auth0-overview/create-applications/regular-web-apps) または [Machine-to-Machine Application](/docs/ja-jp/get-started/auth0-overview/create-applications/machine-to-machine-apps) のいずれかを登録します。アプリケーションの設定時に、次のようにします。

1. **資格情報** で、`None` 以外の **認証方法** を選択します。
2. **設定 > 詳細設定** で **OAuth** タブを開き、**Trust Token Endpoint IP Header** を有効にします。これにより、`auth0-forwarded-for` ヘッダーが、総当たり攻撃対策のためにユーザーの IP アドレスの信頼できる送信元として使用されます。この設定は、認証を行わないアプリケーションでは使用できません。

<div id="send-the-users-ip-address-from-your-server">
  ## サーバーからユーザーの IP アドレスを送信する
</div>

1. [Resource Owner Password Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/resource-owner-password-flow/call-your-api-using-resource-owner-password-flow) を使用してトークンをリクエストする場合は、ユーザーの IP アドレスを値に含む `auth0-forwarded-for` ヘッダーを含めます。指定する IP アドレスが実際にそのユーザーのものであることを必ず確認してください。

   <Warning>
     `auth0-forwarded-for` のようなヘッダー (または一般に、アプリケーションから送られるデータ) をユーザーの IP アドレスの情報源として信頼することには、リスクがあります。このヘッダーは簡単に偽装でき、攻撃対策の検証を回避できてしまうため、信頼できると確信できる場合にのみ使用してください。
   </Warning>
2. 総当たり攻撃対策と不審な IP スロットリングがトリガーされる際に無視する IP の許可リストを指定します。

<Card title="総当たり攻撃対策と不審な IP スロットリングでの許可リスト">
  認証済みのアプリケーションが `auth0-forwarded-for` ヘッダーを送信するよう設定されている場合:

  * `auth0-forwarded-for` ヘッダーに含まれる IP アドレスのみが、総当たり攻撃対策および不審な IP スロットリングの許可リストと照合されます。
  * プロキシの IP アドレスは総当たり攻撃対策および不審な IP スロットリングでは無視されるため、許可リストに追加する必要はありません。
  * プロキシを使用する特定のクライアントを総当たり攻撃対策または不審な IP スロットリングの対象にしたくない場合は、それらを許可リストに追加してください。

  `auth0-forwarded-for` ヘッダーは、クライアントシークレット を使用した認証済みの呼び出しでのみ受け入れられます。アプリケーションが認証されていない場合、または `auth0-forwarded-for` ヘッダーを送信するよう設定されていない場合:

  * 各リクエストの送信元 IP アドレスが、総当たり攻撃対策および不審な IP スロットリングの許可リストと照合されます。
  * IP プロキシを許可リストに追加すると、そのプロキシを通過するすべてのトラフィックが総当たり攻撃対策および不審な IP スロットリングの対象外になります。これはおそらく意図したものではありません。
</Card>

<div id="example">
  ### 例
</div>

export const codeExample = `var request = require("request");

app.post('/api/auth', function(req, res, next) {
  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {
      'content-type': 'application/x-www-form-urlencoded',
      'auth0-forwarded-for': req.ip // エンドユーザーの IP
    },
    form: {
      grant_type: 'password',
      username: 'USERNAME',
      password: 'PASSWORD',
      audience: 'YOUR_API_IDENTIFIER',
      scope: 'SCOPE',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}' // クライアントを認証
    }
  };

  request(options, function (error, response, body) {
    if (error) return next(error);

    // ...
  });
});`;

<AuthCodeBlock children={codeExample} language="javascript" />

<div id="handle-breached-password-detection-responses">
  ## 漏えいパスワードの検知のレスポンスを処理する
</div>

テナントで [漏えいパスワードの検知](/docs/ja-jp/secure/attack-protection/breached-password-detection) を有効にしている場合は、[Auth0 Authentication API](https://auth0.com/docs/api/authentication) からのレスポンスを適切に処理できるよう、アプリケーションを設定する必要があります。

たとえば、ROP フローを使用してパスワードを送信した際に、Auth0 がそのパスワードの漏えいを検知すると、Authentication API は HTTP `401 Unauthorized` ステータスコードと、次のボディを含むレスポンスを返します。

```json lines theme={null}
{
    "error": "password_leaked",
    "error_description": "This login attempt has been blocked because the password you're using was previously disclosed through a data breach (not in this application). Please check your email for more information."
}
```

アプリケーションはこのエラーを処理し、ユーザーにメッセージをレンダリングして、[対話型のパスワードリセットフローをトリガーする](/docs/ja-jp/authenticate/database-connections/password-change#authentication-api)必要があります。

<div id="validate-with-logs">
  ## ログで確認する
</div>

設定が正しく機能している場合、ログに次の内容が表示されます。

```bash lines theme={null}
type:  sepft
...
ip:  <ip from auth0-forwarded-for header>
client_ip:  <ip of actual client/proxy>
...
```

<div id="learn-more">
  ## 詳細はこちら
</div>

* [Resource Owner Password Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/resource-owner-password-flow)
* [Resource Owner Password Flow を使用して API を呼び出す](/docs/ja-jp/get-started/authentication-and-authorization-flow/resource-owner-password-flow/call-your-api-using-resource-owner-password-flow)
* [攻撃対策](/docs/ja-jp/secure/attack-protection)
