認証と認可
認証と認可の違いを学び、これらが現代のアプリケーションでどのようにアクセスを保護するかを理解しましょう。
認証と認可
認証は本人確認を行います。認可は権限を決定します。これらは異なる問題を解決し、順番に行われます。
資格情報によって本人確認済み
本人確認済み → 権限確認済み
- 認証 (AuthN) は「あなたは誰ですか?」に答えます。
- 認可 (AuthZ) は「何をしてよいですか?」に答えます。
- 認証されていても、認可によってブロックされることがあります。
詳細
認証は本人確認を確立します。システムは、ユーザーが主張している本人であることを確認します。通常は、パスワード、トークン、外部の identity provider などの認証情報を使います。
認可は本人確認の後に行われます。システムは、その本人に特定の操作を実行したり、特定のリソースにアクセスしたりする権限があるかを評価します。
これらの関心事は分けて扱う必要があります。本人確認ができたからといって、自動的にアクセス権があるとは限りません。ログイン済みのユーザーでも、特定のデータの閲覧や管理操作の実行が許可されていない場合があります。
概念的には: User → Login → Identity Verified → Permission Check → Resource Access.
認証が先に行われます。認可はその後に行われ、通常は各リクエストごとに実施されます。
認証 — アイデンティティがどのように検証されるか
認証は、主張されたアイデンティティが有効な認証情報によって裏付けられていることを確認します。
パスワード資格情報
ハッシュ化されたパスワード
サーバー検証
- 認証情報には、パスワード、OAuth ログイン、API キー、または多要素認証の証明が含まれます。
- サーバーは、それらの認証情報を保存済みデータまたは信頼できるプロバイダーと照合して検証します。
- 検証に失敗した場合、リソースにアクセスする前にリクエストは拒否されます。
詳細
認証は、ユーザーまたはシステムがアイデンティティを主張し、その証明として認証情報を提示したときに始まります。
ユーザー名 + パスワード は従来の方法です。サーバーは送信された認証情報を保存済みのアカウントデータと照合します。
OAuth ログイン は、認証を信頼できる外部プロバイダー(Google や GitHub など)に委任し、そのプロバイダーが検証済みのアイデンティティをアプリケーションに返します。
API キー は、主にサーバー間認証で使用され、人間のユーザーではなくアプリケーションを識別します。
多要素認証 (MFA) は、2つ目の証明(ワンタイムコードやハードウェアトークンなど)を要求することで、アイデンティティ検証を強化します。
概念的な流れ: ログイン → 認証情報の送信 → サーバーが検証 → アイデンティティ確認。
有効なアイデンティティがなければ、リクエストはここで停止します。
セッションベース認証
セッションストア
セッション作成: ログインがサーバーに送られ、セッションが保存され、その後Cookieがブラウザに送信されます。
- ログイン後、サーバーは認証済みユーザーに紐づくセッションを作成します。
- セッション ID はクライアントの cookie に保存されます。
- サーバーはセッション状態を保持し、各リクエストごとにそれを参照します。
詳細
従来の Web アプリケーションでは、認証はサーバーサイドのセッションを使って処理されます。
ユーザーが正常にログインすると、サーバーは識別情報を含むセッションオブジェクトを生成します。このセッションはサーバー側に保存されます。一般的には、メモリ、データベース、または分散キャッシュに保存されます。
サーバーはセッション ID をクライアントに返し、通常は cookie に保存されます。以降のリクエストでは、ブラウザがその cookie を自動的に含めます。
サーバーはセッション ID を読み取り、対応するセッションデータを取得して、ユーザーの識別情報を判断します。
重要な考え方はシンプルです。サーバーがセッション状態を保存し、クライアントはその参照だけを保存します。
トークンベース認証
| ステップ | アクション |
|---|---|
| 1 | ログイン → サーバーが署名付きJWTを発行 |
| 2 | クライアントがリクエストとともにトークンを送信 |
| 3 | サーバーがトークンの署名を検証 |
| 4 | リクエストを処理(セッション検索なし) |
- 認証情報を検証した後、サーバーはトークン(JWT など)を発行します。
- クライアントは各リクエストでトークンを送信します。通常は Authorization ヘッダーに含めます。
- サーバーはユーザーごとのセッション状態を保存せずにトークンを検証します。
詳細
現代の API や分散システムでは、認証はしばしばステートレスです。
ログインが成功すると、サーバーは ID 情報を含む署名付きトークンを生成します。このトークンはクライアントに返されます。
その後のすべてのリクエストで、クライアントはトークンを含めます。一般的には Authorization ヘッダー内の Bearer トークンとして送信します。
サーバー側のストアでセッションデータを検索する代わりに、サーバーはトークンの署名を検証し、そこからユーザー ID を直接取り出します。
セッションベース認証との重要な違いは、サーバーがユーザーごとのセッション状態を保持しないことです。ID の検証はトークン自体を検証することで行われます。
このモデルでは、共有セッションストレージがなくてもどのサーバーインスタンスでもトークンを検証できるため、水平スケーリングが簡単になります。
JWTとは何か?
- JWTは、Header、Payload、Signature の3つの部分で構成されます。
- 署名により、トークンが改ざんされていないことが保証されます。
- JWTはデフォルトで署名されますが、暗号化はされません。
詳細
JWTは、ドットで区切られた3つのBase64エンコードされたセクションから成る構造化された文字列です:
Header → トークンと署名アルゴリズムに関するメタデータ
Payload → クレーム(ユーザーIDやロールなど)
Signature → トークンが変更されていないことを示す暗号学的な証明
サーバーがJWTを発行するとき、秘密鍵または公開鍵を使ってトークンに署名します。後でそのトークンが提示されたとき、サーバーは署名を検証して、Payload が変更されていないことを確認します。
重要な補足: JWTはデフォルトでは暗号化されません。Payload はトークンを持っている人なら誰でもデコードできます。署名が保証するのは完全性であり、機密性ではありません。
JWTが便利なのは、サーバー側のセッション保存を必要とせず、検証可能な形でアイデンティティ情報をリクエストと一緒に運べるからです。
認可 — 権限の強制
- 認可は、本人確認の後に権限をチェックします。
- RBAC は、ロールに基づいて権限を割り当てます。
- 認可は、保護されたすべてのリクエストで評価されます。
詳細
ユーザーの本人確認が完了すると、システムはそのユーザーにどのような操作が許可されているかを判断する必要があります。
認可はアクセス制御ルールを適用します。ユーザーが認証されていても、特定のリソースにアクセスしたり、特定の操作を実行したりする権限がない場合があります。
一般的なモデルの1つは Role-Based Access Control (RBAC) です。ここでは、ユーザーに「admin」「editor」「viewer」などのロールが割り当てられ、各ロールにあらかじめ定義された権限が設定されています。
もう1つのモデルは Attribute-Based Access Control (ABAC) です。これは、ユーザー属性、リソース属性、リクエストのコンテキストなどの属性に基づいて判断を行います。
認証は通常、セッションごと、またはトークン発行ごとに1回だけ行われます。一方、認可は、アクセスルールが一貫して適用されるように、保護されたすべてのリクエストで評価されます。
リクエストフローにおける認証の発生箇所
- リクエストはサーバーに到達し、認証ミドルウェアを通過します。
- 資格情報が無効な場合、サーバーは 401 Unauthorized を返します。
- ID は有効でも権限が不十分な場合、サーバーは 403 Forbidden を返します。
詳細
リクエストがサーバーに届いても、すぐにアプリケーションのロジックが実行されるわけではありません。まず認証レイヤーを通過します。これは通常、Express、Django、FastAPI などのフレームワークでミドルウェアとして実装されています。
このミドルウェアは、セッション Cookie や認可トークンなどの資格情報を確認します。資格情報がない、または無効な場合、サーバーは 401 Unauthorized レスポンスでリクエストを拒否します。
ID の確認に成功すると、次にシステムは権限を評価します。ユーザーが要求されたリソースへのアクセス権を持っていない場合、サーバーは 403 Forbidden を返します。
認証と認可のチェックを通過して初めて、リクエストはハンドラーに到達し、ビジネスロジックが実行されます。これにより、機密性の高い操作が不正アクセスから保護されます。
セキュリティに関する考慮事項
- パスワードは保存前にハッシュ化しなければなりません — 平文で保存してはいけません。
- 認証トラフィックは、傍受を防ぐために HTTPS を使用しなければなりません。
- トークンには有効期限を設定すべきであり、更新にはリフレッシュ トークンを使用できます。
詳細
正しく実装された認証フローでも、基本的な保護が欠けていれば安全ではない場合があります。
パスワードは、データベースに保存する前にハッシュ化しなければなりません。ハッシュ化により、データベースが侵害されても生のパスワードが露出しないようにできます。
すべての認証トラフィックは HTTPS で送信しなければなりません。通信中の暗号化がないと、資格情報やトークンが攻撃者に傍受される可能性があります。
アクセス トークンには有効期限を設定すべきです。短命なトークンは、トークンが盗まれた場合の被害を軽減します。多くのシステムでは、ユーザーが何度もログインし直さなくても新しいアクセス トークンを取得できるように、リフレッシュ トークンを使用します。
セキュリティは、単に本人確認を行うことだけではありません。本人確認を行う仕組みそのものを保護することです。
質問セクション
1 / 5