コンテンツにスキップ

認証@認証/認可

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. 認証とは

通信しているユーザーが誰であるかを特定する。

基本的に、認証の実装は認可に依存しない。


02. 認証の種類

HTTP認証


Form認証


APIキー認証

▼ APIキー認証とは

事前にAPIキーとなる文字列を配布し、認証フェーズは行わずに認可フェーズのみでユーザーを照合する認証スキームのこと。

信頼されたクライアントに発行することが前提のため、トークンよりも有効期限が長い。

▼ 照合情報の送信方法

自前ヘッダーとして、x-api-keyヘッダーを定義する。これにAPIキーを割り当て、リクエストを送信する。

POST https://example.com/foo
---
x-api-key: <APIキー>


PAT:パーソナルアクセストークンによる認証

▼ PATによる認証

クライアントがパーソナルアクセストークン (個人用アクセストークン) の付与をリクエストし、認証フェーズは行わずに認可フェーズのみでユーザーを照合する。

AuthorizationヘッダーにPATを割りあてて、リクエストを送信する。

作成時以降、アクセストークンを確認できなくなるため、クライアントがアクセストークンを管理する必要がある。

POST https://example.com/foo
---
Authorization: <パーソナルアクセストークン>
サービス例 トークン名 説明
GitHub パーソナルアクセストークン HTTPSプロトコルを使用して、プライベートリポジトリにリクエストを送信するために必要。HTTPSプロトコルを使用する場面として、アプリケーションの拡張機能のGitHub連携、リポジトリのパッケージ化などがある。
- https://docs.github.com/ja/github/authenticating-to-github/creating-a-personal-access-token


03. 認証属性

realm

認証管理におけるテナントのようなもの。

realmごとに認証を管理する。

例えばKeycloakであれば、Adminユーザーの認証はmaster realmで、それ以外はユーザー定義のrealm、で管理する。


04. 認証情報の伝播方法の種類

セッションベースの伝播

▼ セッションベースの伝播とは

セッションデータで認証情報を伝播する認証方法 (例:Form認証など) である。

システムの各コンポーネントがセッションデータを持つ必要がある。

セッションは有効期限が短く、漏洩した場合に脆弱性が高くなる。

作成と削除が頻繁に起こるコンテナでは、セッションデータが消失する可能性があるため、セッションベースとコンテナの相性は悪い。

いずれかのコンポーネントでセッションデータが消失しても復元できるように、SessionStorageを使用する必要がある。


トークンベースの伝播

▼ トークンベースの伝播とは

トークン (例:JWT仕様あるいはそうではないアクセストークン、IDトークンなど) で認証情報を伝播する認証方法 (例:APIキー認証、PAT、SSOなど) である。

システムの各コンポーネントはトークンを持つ必要がない。

作成と削除が頻繁に起こるコンテナでは、トークンの消失を考慮する必要がなく、トークンベースとコンテナの相性は良い。

一方で、トークンは無効化が難しく漏洩した場合に脆弱性が高くなる、有効期限を短く設定する必要がある。

▼ トークンの種類

トークンには以下の種類がある。

Self-containedトークンでは、トークン自体に署名と有効期限が含まれている。

Opaqueトークンでは、トークンはランダム値で、署名と有効期限はDBで管理されている。

トークンの種類 トークンの情報タイプ
JWT仕様でないアクセストークン Self-containedトークン、Opaqueトークン
JWT仕様のアクセストークン JWT仕様なためSelf-containedトークン
IDトークン 必ずJWT仕様であり、Self-containedトークン
リフレッシュトークン Self-containedトークン、Opaqueトークン


05. 認証情報の運搬方法の種類

▼ セッションIDで認証情報を伝播する場合

(1)

セッションIDをCookieヘッダーに割り当て、リクエストを送信する。

(2)

最初、ユーザー作成の段階で、クライアントが認証情報をサーバーに送信する。サーバーは、認証情報をDBに保管する。

POST https://example.com/users
---
# ボディ
{"email_address": "foo@gmail.com", "password": "foo"}
(3)

次回の認証時に、再びユーザーが認証情報を送信する。

POST https://example.com/foo-form
---
# ボディ
{"email_address": "foo@gmail.com", "password": "foo"}
(4)

サーバーは、DBの認証情報を照合し、ログインを許可する。サーバーは、セッションIDを作成し、セッションデータに書き込む。

# セッションデータ
{ sessionid: ***** }
(5)

レスポンスのSet-CookieヘッダーにセッションIDを割り当て、クライアントに送信する。

200 OK
---
Set-Cookie: sessionid=<セッションID>
(6)

サーバーは、セッションIDとユーザーIDを紐付けてサーバー内に保管する。

加えて次回のログイン時、クライアントは、リクエストのCookieヘッダーにセッションIDを割り当て、クライアントに送信する。

サーバーは、保管されたセッションIDに紐付くユーザーIDから、ユーザーを特定し、ログインを許可する。

これにより、改めて認証情報を送信せずに、素早くログインできるようになる。

POST https://example.com/foo-form
---
cookie: sessionid=<セッションID>
(7)

認証解除時、サーバーでセッションデータを削除する。

▼ トークンで認証情報を伝播する場合

トークン (例:アクセストークン、IDトークンなど) をCookieヘッダーに割り当て、リクエストを送信する。

CSRFトークンと組み合わせるとさらに良くなる。

なお、APIではリクエストの送受信時にCookieヘッダーよりもAuthorizationヘッダーの方が扱いやすいため、Authorizationヘッダーでトークンを運ぶことになる。

また、スマホアプリもCookieヘッダーよりAuthorizationヘッダーがいいらしい。

JWT


Authorizationヘッダーによる運搬

Authorizationヘッダーでトークンを運ぶ。

POST https://example.com/foo
---
authorization: Bearer <ヘッダーJSONエンコード値>.<ペイロードJSONエンコード値>.<署名JSONエンコード値>

なお不便ではあるが、AuthorizationヘッダーはCookieヘッダーとは異なり、ローカルマシンに保管できない。

その代わり、ブラウザの設定によって、ブラウザのWebストレージで保管できる (Chromeでは、LocalStorageあるいはSessionStorage) 。

なお、APIではリクエストの送受信時にCookieヘッダーよりもAuthorizationヘッダーの方が扱いやすいため、Authorizationヘッダーでトークンを運ぶことになる。

また、スマホアプリもCookieヘッダーよりAuthorizationヘッダーがいいらしい。


クエリストリングによる運搬


06. 認証情報の保管の種類

SessionStorage

▼ SessionStorage

セッションIDで認証情報を伝播した場合に、初回認証以降に、認証の成功状態を維持する必要がある。

ブラウザは、SessionStorageにセッションIDを保管する。

ブラウザを閉じると、ブラウザはSessionStorageのセッションIDを破棄し、認証はやり直しになる。

▼ 場所

*例*

ローカルマシンがMacOSであれば、Chromeは~/Library/Application Support/Google/Chrome/<Profile>/Local Storage/ディレクトリに保管する。


LocalStorage

▼ LocalStorageとは

トークンで認証情報を伝播した場合に、初回認証以降に、認証の成功状態を維持する必要がある。

ブラウザは、LocalStorageにトークンを保管する。

ブラウザを閉じても、ブラウザはLocalStorageのトークンを破棄せず、認証の成功状態を維持できる。

LocalStorageはSessionStorageと比べて保管期間が長いため、XSSの危険性がより高い。

▼ 場所

*例*

ローカルマシンがMacOSであれば、Chromeは~/Library/Application Support/Google/Chrome/<Profile>/Local Storage/ディレクトリに保管する。


トークン (例:アクセストークン、IDトークンなど) で認証情報を伝播した場合に、初回認証以降に、認証の成功状態を維持する必要がある。

ブラウザは、ローカルマシンのCookieディレクトリにトークンを保管する。

ブラウザを閉じても、ブラウザはローカルマシンのディレクトリのトークンを破棄せず、認証の成功状態を維持できる。

▼ 場所

*例*

ローカルマシンがMacOSであれば、Chromeは/Users/<ユーザー名>/Library/Application Support/Google/Chrome/Default/CookiesディレクトリにCookieヘッダーの値を保管する。


07. 複数の認証の組み合わせ

TSV:Two Step Verification (二段階認証)

▼ 二段階認証とは

2個の認証方法を設定し、クライアントを照合する。

一段階目の認証例 二段階目の認証例 説明 備考
IDとパスワード IDとパスワード IDとパスワードによる方法の後、別のIDとパスワードによる方法を設定する。
秘密の質問 IDとパスワードによる方法の後、質問に対してあらかじめ設定した回答による方法を設定する。
SMS IDとパスワードによる方法の後、SMS宛に送信した認証コードによる方法を設定する。 異なる要素のため、これは二要素認証でもある。
指紋 IDとパスワードによる方法の後、指紋の解析結果による方法を設定する。 異なる要素のため、これは二要素認証でもある。


TFA:Two Factor Authorization (二要素認証)

▼ 二要素認証とは

二段階認証のうちで特に、認証時に異なる要素の方法を使用して、段階的にクライアントを照合すること方法のこと。

一要素目の認証例 二要素目の認証例
IDとパスワード (知識) 事前に連携登録されたPC端末のQRコード読込アプリで発行したワンタイムパスワード (所持)
事前に連携登録されたスマホ端末のQRコード読込アプリで発行したワンタイムパスワード (所持)
事前登録されたスマホ端末の電話番号のSMSで受信したワンタイムパスワード (所持)
事前登録されたスマホ端末の電話番号のSMSで受信した認証コード (所持)
OAuth (所持)
指紋 (生体)
暗証番号 (知識) キャッシュカード (所持)


MFA:Multiple Factor Authorization (多要素認証)

▼ 多要素認証とは

記入中...