質問

Web ページは存在するが、ユーザーが十分な権限を持っていない (ログインしていないか、適切なユーザー グループに属していない) 場合、適切な HTTP 応答は何でしょうか?

401 Unauthorized?
403 Forbidden?
他に何か?

私がこれまでにそれぞれについて読んだ内容では、この 2 つの違いはあまり明確ではありません。それぞれの応答にはどのようなユースケースが適していますか?

役に立ちましたか?

解決

からのわかりやすい説明 ダニエル・アーヴィン:

問題があります 401 不正, 、認証エラーの HTTP ステータス コード。それだけです:これは認証のためであり、認可のためではありません。401の応答を受信するのは、「あなたは認証されていない - まったく認証されていないか、誤って認証されていないが、再認証されてもう一度やり直してください」と言っているサーバーです。あなたを助けるために、それは常に WWW認証 認証方法を説明するヘッダー。

これは、一般的にWebサーバーによって返される応答であり、Webアプリケーションではありません。

それは非常に一時的なものでもあります。サーバーは、再試行するように求めています。

したがって、認証には、 403禁止します 応答。それは永続的であり、私のアプリケーションロジックに結び付けられており、401よりも具体的な反応です。

403 応答を受信すると、サーバーは「申し訳ありません。私はあなたが誰であるかを知っています - 私はあなたが誰であるかを信じています - しかし、あなたはこのリソースにアクセスする許可を持っていません。システム管理者にうまく尋ねると、許可が得られます。しかし、あなたの苦境が変わるまで、二度と私を悩ませないでください。」

要約すると、 401 不正 回答は、欠落または悪い認証に使用する必要があり、 403禁止します その後、ユーザーが認証されているが、指定されたリソースで要求された操作を実行することを許可されていない場合、応答を使用する必要があります。

別の 素敵な写真フォーマット http ステータス コードをどのように使用するかについて説明します。

enter image description here

他のヒント

見る RFC2616:

401 不正:

リクエストにすでに認可資格情報が含まれている場合、401 応答はそれらの資格情報に対する認可が拒否されたことを示します。

403禁止します:

サーバーはリクエストを理解しましたが、リクエストの実行を拒否しています。

アップデート

ユースケースから、ユーザーは認証されていないようです。401を返します。


編集: RFC2616 は時代遅れです、参照してください RFC7231 そして RFC7235.

他の回答に欠けているのは、RFC 2616 のコンテキストにおける認証と認可は、RFC 2617 の HTTP 認証プロトコルのみを参照していることを理解する必要があることです。RFC2617 以外のスキームによる認証は HTTP ステータス コードではサポートされていないため、401 と 403 のどちらを使用するかを決定する際には考慮されません。

簡潔で簡潔な

「未承認」は、クライアントが RFC2617 認証されておらず、サーバーが認証プロセスを開始していることを示します。「禁止」は、クライアントが RFC2617 認証されているが権限を持っていないこと、またはサーバーが要求されたリソースに対して RFC2617 をサポートしていないことを示します。

つまり、独自のロールユアオウン ログイン プロセスがあり、HTTP 認証をまったく使用しない場合、403 が常に適切な応答となり、401 は決して使用すべきではありません。

詳細かつ詳細

RFC2616より

10.4.2 401 不正

リクエストにはユーザー認証が必要です。応答には、要求されたリソースに適用可能なチャレンジを含む WWW-Authenticate ヘッダー フィールド (セクション 14.47) が含まれなければなりません (MUST)。クライアントは、適切な Authorization ヘッダーフィールドを使用してリクエストを繰り返すことができます (セクション 14.8)。

そして

10.4.4 403禁止サーバーは要求を理解していましたが、それを満たすことを拒否しています。認可は役に立たないので、リクエストを繰り返してはなりません。

まず覚えておいていただきたいのは、このドキュメントの文脈における「認証」と「認可」は、特に RFC 2617 の HTTP 認証プロトコルを指すということです。これらは、ログイン ページなどを使用して作成した独自の認証プロトコルを指すものではありません。RFC2617 以外の方法による認証と認可を指す場合に「ログイン」を使用します。

したがって、本当の違いは、問題が何であるか、あるいは解決策があるかどうかではありません。違いは、サーバーがクライアントに次に何を行うかを期待することです。

401 は、リソースを提供できないが、サーバーがクライアントが HTTP 認証を通じてログインすることを要求しており、プロセスを開始するための応答ヘッダーを送信していることを示します。おそらくリソースへのアクセスを許可する承認があるかもしれませんし、ないかもしれませんが、試してみて何が起こるか見てみましょう。

403 は、リソースを提供できず、現在のユーザーには RFC2617 を通じてこれを解決する方法がなく、試しても無駄であることを示します。これは、どのレベルの認証でも十分ではないことがわかっているため (たとえば、IP ブラックリストのため) である可能性がありますが、ユーザーがすでに認証されており、権限を持っていないことが原因である可能性があります。RFC2617 モデルは 1 ユーザー、1 資格情報であるため、ユーザーが承認される 2 番目の資格情報セットを持っている可能性がある場合は無視できます。これは、ある種のログイン ページやその他の RFC2617 以外の認証プロトコルが役立つかどうかを示唆も暗示するものでもありません。つまり、RFC2616 の標準と定義の範囲外です。


編集: RFC2616 は時代遅れです、参照してください RFC7231 そして RFC7235.

  +-----------------------
  | RESOURCE EXISTS ? (if private it is often checked AFTER auth check)
  +-----------------------
    |       |
 NO |       v YES
    v      +-----------------------
   404     | IS LOGGED-IN ? (authenticated, aka has session or JWT cookie)
   or      +-----------------------
   401        |              |
   403     NO |              | YES
   3xx        v              v
              401            +-----------------------
       (404 no reveal)       | CAN ACCESS RESOURCE ? (permission, authorized, ...)
              or             +-----------------------
             redirect          |            |
             to login       NO |            | YES
                               |            |
                               v            v
                               403          OK 200, redirect, ...
                      (or 404: no reveal)
                      (or 404: resource does not exist if private)
                      (or 3xx: redirection)

チェックは通常、次の順序で行われます。

  • 404 リソースがパブリックで存在しない場合、または 3xxリダイレクション
  • さもないと:
  • ログインしていないかセッションが期限切れの場合は 401
  • 403 ユーザーがリソース (ファイル、json など) にアクセスする権限を持っていない場合
  • 404 リソースが存在しないか、何も公開したくない場合、または 3xxリダイレクション

無許可:リクエストが必要であることを示すステータス コード (401) 認証, 、通常、これはユーザーがログイン (セッション) する必要があることを意味します。ユーザー/エージェントはサーバーによって認識されません。他の資格情報を使用して繰り返すことができます。注記:これには「unauthorized」ではなく「unauthenticated」という名前を付ける必要があるため、混乱を招きます。これは、セッションの有効期限が切れた場合、ログイン後に発生する可能性もあります。特別なケース:リソースの有無を明らかにするのを避けるために、404 の代わりに使用できます (クレジットは @gingerCodeNinja)

禁断:サーバーがリクエストを理解したが、それを実行することを拒否したことを示すステータス コード (403)。ユーザー/エージェントはサーバーによって認識されていますが、 資格情報が不十分です. 。資格情報が変更されない限り、リクエストを繰り返しても機能しませんが、短期間で変更される可能性は非常に低いです。特別なケース:リソースの有無を明らかにするのを避けるために、404 の代わりに使用できます (クレジットは @gingerCodeNinja)

見つかりません:要求されたリソースが利用できないことを示すステータス コード (404)。ユーザー/エージェントはわかっていますが、サーバーはリソースについて何も明らかにせず、リソースが存在していないかのように動作します。繰り返しても効果はありません。これは 404 の特別な使用法です (例: github が使用します)。

@ChrisHが述べたように、いくつかのオプションがあります リダイレクション 3xx (301、302、303、307、またはまったくリダイレ​​クトせずに 401 を使用):

によると RFC 2616 (HTTP/1.1) 403 は次の場合に送信されます。

サーバーはリクエストを理解しましたが、リクエストの実行を拒否しています。認可は役に立たないので、リクエストを繰り返してはなりません。リクエストメソッドが HEAD ではなく、サーバーがリクエストが満たされなかった理由を公開したい場合、エンティティ内に拒否の理由を記述する必要があります (SHOULD)。サーバーがこの情報をクライアントに公開したくない場合は、代わりにステータス コード 404 (見つかりません) を使用できます。

言い換えれば、クライアントが認証によってリソースにアクセスできる場合は、401 を送信する必要があります。

HTTP認証を前提としています (WWW認証 そして 認可 ヘッダー) 使用中です, 、別のユーザーとして認証することで、要求されたリソースへのアクセスが許可される場合は、401 Unauthorized が返される必要があります。

403 Forbidden は、HTTP 認証に関連しない限り、リソースへのアクセスが全員に禁止されている場合、特定のネットワークに制限されている場合、または SSL 経由でのみ許可されている場合に使用されます。

HTTP認証を使用していない場合 現在の標準である Cookie ベースの認証スキームをサービスに使用している場合は、403 または 404 が返されるはずです。

401 に関しては、これは RFC 7235 (ハイパーテキスト転送プロトコル (HTTP/1.1)) からのものです。認証):

3.1.401 不正

401(不正な)ステータスコードは、ターゲットリソースの有効な認証資格情報がないため、リクエストが適用されていないことを示しています。Origin Serverは、ターゲットリソースに適用可能な少なくとも1つの課題を含むwww-authenticateヘッダーフィールド(セクション4.4)を送信する必要があります。 リクエストに認証資格情報が含まれている場合、401応答は、これらの資格情報に対して承認が拒否されたことを示します. 。クライアントは、新しいまたは交換された承認ヘッダーフィールド(セクション4.1)でリクエストを繰り返すことができます。401応答に以前の応答と同じ課題が含まれており、ユーザーエージェントが既に認証を少なくとも1回試みている場合、ユーザーエージェントは通常、関連する診断情報が含まれているため、ユーザーに囲まれた表現を提示する必要があります。

403 (および 404) のセマンティクスは時間の経過とともに変化しました。これは 1999 年のものです (RFC 2616)。

10.4.4 403 禁止

サーバーはリクエストを理解しましたが、リクエストの実行を拒否しています。
認可は役に立たない そしてそのリクエストは繰り返されるべきではありません。
リクエストメソッドが HEAD ではなく、サーバーが
リクエストが満たされていない理由は、エンティティの拒否の理由を説明する必要があります。サーバーがこの情報をクライアントが利用できるようにしたい場合、ステータスコード404
(見つかりません) を代わりに使用できます。

2014 年の RFC 7231 (ハイパーテキスト転送プロトコル (HTTP/1.1)):セマンティクスとコンテンツ) により、403 の意味が変更されました。

6.5.3.403禁止します

403(禁止)ステータスコードは、サーバーがリクエストを理解したが、それを承認することを拒否したことを示します。リクエストが禁止されている理由を公開したいサーバーは、応答ペイロード(ある場合)でその理由を説明できます。

認証資格情報がリクエストで提供された場合、
サーバーは、それらがアクセスを許可するには不十分であるとみなします。クライアント
同じリクエストを自動的に繰り返すべきではありません
資格。クライアントは、新規または異なる資格情報でリクエストを繰り返すことができます。ただし、諸事情によりリクエストをお断りする場合がございます
資格情報とは関係ありません。

現在の存在を「隠蔽」したいオリジンサーバー。
禁止されたターゲットリソースは、代わりに次のステータスコードで応答してもよい(MAY)
404お探しのページが見つかりませんでした)。

したがって、403 (または 404) は、現在では何らかの意味を持っている可能性があります。新しい認証情報を提供すると役立つ場合があります...あるいはそうではないかもしれない。

これが変更された理由は、RFC 2616 が、今日の Web アプリが実際にフォームや Cookie などを使用してカスタム認証スキームを構築するときに HTTP 認証が使用されると想定しているためだと思います。

  • 401 不正:あなたが誰なのか知りません。 これは認証エラーです。
  • 403禁止します:あなたが誰であるかは知っていますが、このリソースにアクセスする権限がありません。 これは認証エラーです。

これは古い質問ですが、実際には取り上げられなかった選択肢の 1 つは、404 を返すというものでした。セキュリティの観点から見ると、投票数が最も多かった回答は潜在的な影響を受けます。 情報漏洩の脆弱性. 。たとえば、問題の安全な Web ページがシステム管理ページであるか、あるいはおそらくより一般的には、ユーザーがアクセスできないシステム内のレコードであるとします。理想的には、悪意のあるユーザーに、アクセス権がないことはもちろん、そこにページやレコードがあることさえ知られたくないでしょう。このようなものを構築するとき、非認証/未承認のリクエストを内部ログに記録しようとしますが、404 が返されます。

OWASP にはいくつかの機能があります 詳しくは 攻撃者がこの種の情報を攻撃の一部としてどのように使用するかについて。

この質問は少し前にされましたが、人々の考えは進化しています。

セクション6.5.3 このドラフト (Fielding と Reschke によって作成) では、ステータス コード 403 に、に記載されているものとは若干異なる意味が与えられています。 RFC 2616.

これは、多くの一般的な Web サーバーおよびフレームワークで採用されている認証および認可スキームで何が起こっているかを反映しています。

最も重要だと思われる部分を強調しました。

6.5.3.403禁止します

403 (禁止) ステータス コードは、サーバーがリクエストを理解したが、承認を拒否したことを示します。リクエストが禁止された理由を公開したいサーバーは、その理由を応答ペイロード (存在する場合) に記述することができます。

リクエストで認証資格情報が提供された場合、サーバーは、それらがアクセスを許可するには不十分であるとみなします。 クライアントは同じ資格情報を使用してリクエストを繰り返してはなりません (SHOULD NOT)。クライアントは、新しいまたは異なる資格情報を使用してリクエストを繰り返すことができます (MAY)。 ただし、認証情報とは関係のない理由でリクエストが禁止される場合があります。

禁止されたターゲットリソースの現在の存在を「隠蔽」したいオリジンサーバーは、代わりにステータスコード 404 (Not Found) で応答してもよい(MAY)。

どのような規則を使用する場合でも、重要なことは、サイト/API 全体で統一性を提供することです。

TL;DR

  • 401:認証に関係する拒否
  • 403:認証とは何の関係もない拒否

実践例

もし アパッチ 認証が必要です (経由 .htaccess)そしてあなたはヒットしました Cancel, と応答します。 401 Authorization Required

もし nginx ファイルは見つかりましたが、ファイルがありません アクセス権 (ユーザー/グループ) で読み取り/アクセスすると、次のように応答します。 403 Forbidden

RFC (2616 セクション 10)

401 不正 (10.4.2)

意味1: 認証が必要です

リクエストにはユーザー認証が必要です。...

意味2: 認証が不十分です

...リクエストにすでに認可資格情報が含まれている場合、401 応答はそれらの資格情報に対する認可が拒否されたことを示します。...

403 禁止 (10.4.4)

意味: 認証とは無関係

...認可は役に立ちません...

詳細:

  • サーバーはリクエストを理解しましたが、リクエストの実行を拒否しています。

  • エンティティ内で拒否の理由を説明する必要があります。

  • ステータス コード 404 (見つかりません) を代わりに使用できます。

    (サーバーがこの情報をクライアントから保持したい場合)

ログインしていないか、適切なユーザー グループに属していません。

あなたは 2 つの異なるケースについて述べました。それぞれのケースで異なる応答が返されるはずです。

  1. まったくログインしていない場合は、戻る必要があります 401 不正
  2. ログインしていても適切なユーザー グループに属していない場合は、戻る必要があります。 403禁止します

この回答に対して受け取ったコメントに基づく RFC に関するメモ:

ユーザーがログインしていない場合、ユーザーは認証されていません。これに相当する HTTP は 401 であり、RFC では誤解を招きやすいように Unauthorized と呼ばれています。として セクション10.4.2 の状態 401 不正:

「リクエストにはユーザーが必要です 認証."

認証されていない場合は、401 が正しい応答です。ただし、権限がない場合は、意味的に正しい意味で、403 が正しい応答です。

英語で:

401

あなたは潜在的にアクセスを許可されていますが、何らかの理由でこのリクエストであなたは拒否されました。パスワードが間違っているなど?再試行してください。正しいリクエストを使用すると、代わりに成功応答が得られます。

403

あなたは決して許されません。あなたの名前はリストに載っていません、あなたは決して入って、立ち去ることはありません、再試行要求を送らないでください、それは常に拒否されます。どこかに行って。

これらの意味は次のとおりです。

401:ユーザーが(正しく)認証されていません。リソース/ページには認証が必要です

403:ユーザーは認証されましたが、そのロールまたは権限では、要求されたリソースへのアクセスが許可されていません。たとえば、ユーザーは管理者ではなく、要求されたページは管理者用です。

これは私の頭の中でここで説明するよりも簡単なので、次のようになります。

401:これを表示するには HTTP 基本認証が必要です。

403:これは表示されず、HTTP 基本認証は役に立ちません。

ユーザーがサイトの標準 HTML ログイン フォームを使用してログインする必要があるだけの場合、401 は HTTP 基本認証に固有であるため、適切ではありません。

403 を使用して次のようなものへのアクセスを拒否することはお勧めしません。 /includes, なぜなら、ウェブに関する限り、それらのリソースはまったく存在しないため、404 にする必要があるからです。

これにより、403 は「ログインする必要があります」のままになります。

つまり、403 は、「このリソースには HTTP 基本認証以外の何らかの形式の認証が必要である」ことを意味します。

https://www.w3.org/プロトコル/rfc2616/rfc2616-sec10.html#sec10.4.2

ブラウザーにとって、401 はユーザーが新しい資格情報を入力するための認証ダイアログを開始しますが、403 は開始しないことを考慮することが重要だと思います。ブラウザは、401 が返された場合、ユーザーは再認証する必要があると考えます。したがって、401 は無効な認証を表し、403 は権限の欠如を表します。

以下に、そのロジックで認証または認可からエラーが返されるいくつかのケースを示します。重要な語句は太字で示しています。

  • リソースには認証が必要ですが、 資格情報がありません だった 指定された.

401:クライアントは資格情報を指定する必要があります。

  • 指定された資格情報は 無効な形式.

400:構文エラーは常に 400 を返すはずなので、これは 401 でも 403 でもありません。

  • 指定された資格情報は、 ユーザー どれの 存在しない.

401:クライアントは有効な資格情報を指定する必要があります。

  • 指定された 資格無効 ただし、有効なユーザーを指定してください (または、指定されたユーザーが必要ない場合はユーザーを指定しないでください)。

401:繰り返しますが、クライアントは有効な資格情報を指定する必要があります。

  • 指定された 資格 持っている 期限切れ.

401:これは、一般に無効な資格情報を持つことと実質的に同じであるため、クライアントは有効な資格情報を指定する必要があります。

  • 指定された資格情報は完全に有効ですが、有効ではありません。 十分です 特定の リソース, ただし、より多くの権限を持つ資格情報では可能性があります。

403:現在の資格情報はすでに有効ですが、権限がないだけであるため、有効な資格情報を指定してもリソースへのアクセスは許可されません。

  • 特定の リソースアクセスできない 資格情報に関係なく。

403:これは資格情報とは無関係であるため、有効な資格情報を指定しても役に立ちません。

  • 指定された資格情報は完全に有効ですが、特定の クライアントブロックされました それらを使用することから。

403:クライアントがブロックされている場合、新しい資格情報を指定しても何も起こりません。

この問題に関する最新の RFC を考慮すると (7231 そして 7235)ユースケースは非常に明確であるようです(斜体を追加)。

  • 401は 認証されていない (「有効な認証がありません」);つまり「私はあなたが誰なのか知りません、あるいはあなたが言うとおりの人であるとは信じません。」

401 不正

401(不正)ステータスコードは、リクエストが適用されていないことを示しています。 有効な認証がありません ターゲットリソースの資格情報。401応答を生成するサーバーは、ターゲットリソースに適用される少なくとも1つの課題を含むwww-authenticateヘッダーフィールド(セクション4.1)を送信する必要があります。

リクエストに認証資格情報が含まれている場合、401応答は、これらの資格情報に対して承認が拒否されたことを示します。ユーザーエージェントは、新しいまたは交換された認証ヘッダーフィールド(セクション4.2)でリクエストを繰り返すことができます。401応答に以前の応答と同じ課題が含まれており、ユーザーエージェントが既に認証を少なくとも1回試みている場合、ユーザーエージェントは通常、関連する診断情報が含まれているため、ユーザーに囲まれた表現を提示する必要があります。

  • 403は 無許可の (「許可を拒否する」);つまり「あなたが誰であるかは知っていますが、このリソースにアクセスする権限がありません。」

403禁止します

403(禁止)ステータスコードは、サーバーがリクエストを理解したことを示しますが 許可を拒否する それ。リクエストが禁止されている理由を公開したいサーバーは、応答ペイロード(ある場合)でその理由を説明できます。

リクエストで認証資格情報が提供された場合、サーバーはアクセスを付与するのに不十分であると考えます。クライアントは、同じ資格情報でリクエストを自動的に繰り返すべきではありません。クライアントは、新規または異なる資格情報でリクエストを繰り返すことができます。ただし、資格とは関係のない理由で要求が禁止される場合があります。

禁止されているターゲットリソースの現在の存在を「非表示」したいOrigin Serverは、代わりに404のステータスコードで応答する場合があります(見つかりません)。

401対403の場合、これは何度も答えられています。これは本質的には「HTTP リクエスト環境」に関する議論であり、「アプリケーション」に関する議論ではありません。

roll-your-own-login の問題 (アプリケーション) について質問があるようです。

この場合、HTTP 認証とログイン ページ (HTTP 認証の設定に関連付けられていない) を使用しない限り、単にログインしていないだけでは 401 または 403 を送信するのに十分ではありません。ファイルへのアプリケーションレベルのアクセス用に (要求されたリソースの代わりに) ロールユアオウンログイン画面が存在する「201 Created」を探しているようです。これはこう言います:

「聞こえました、ここにありますが、代わりにこれを試してください(見ることは許可されていません)」

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top