コンテンツにスキップ

認証アーティファクトによる分類@認証

はじめに

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


01. 認証アーティファクト

種類

セッション ID JWT トークン Opaque トークン API キー
概説 ランダムで一意な文字列 JWT 仕様(RFC 7519)からなる署名済トークン ランダムな文字列からなるトークン ランダムな文字列からなるトークン
署名方法 無 RSA など 無 無
検証方法 セッションストレージにあるセッション ID との照合 ID プロバイダーから取得した公開鍵による署名検証 ID プロバイダーのイントロスペクションエンドポイントからのレスポンス 登録した API キーとの照合
使用例 フォーム認証など OIDC や OAuth2 など OAuth2 など API の簡易的な認証など


認証と運搬方法の関係

認証 セッションベース トークンベース ワンタイムコードベース
Cookie ヘッダーによる運搬 セッション ID を認証アーティファクトとして、Cookie ヘッダーで運搬する。セッション ID は、再利用のためにブラウザの Cookie に保存する。
(例) フォーム認証など
トークンを認証アーティファクトとして、Cookie ヘッダーで運搬する。トークンは、再利用のためにブラウザの Cookie に保存する。認証後にレスポンスの Set-Cookie ヘッダーにアクセストークンを設定する必要があり、さまざまなフロントエンドアプリケーション (SST、CSR、SSR など) で実装できる。
(例) OAuth2、OIDC、SAML など
なし
Authorization ヘッダーによる運搬 なし トークンを認証アーティファクトとして、Authorization ヘッダーで運搬する。トークンは、再利用のためにブラウザの SessionStorage や LocalStorage に保存する。ブラウザの DOM を操作できるフロントエンドアプリケーション (CSR など) で実装できる。
(例) OAuth2、OIDC、SAML、パーソナルアクセストークン認証など
ワンタイムコードを認証アーティファクトとして、Authorization ヘッダーで運搬する。


02. セッションベース認証

セッションベース認証とは

セッション ID を運搬する認証方法である。

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

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

作成と削除が頻繁に起こるコンテナでは、セッション ID の消失する可能性がある。その結果、コンテナとセッションベース認証の相性はよくないと言える。

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


フォーム認証

▼ フォーム認証とは

セッションベース認証、かつ Cookie ヘッダーによる運搬の認証スキームのこと。

トークン (ID トークン、アクセストークン) を使用する場合、Cookie ヘッダーによる運搬であっても、フォーム認証とは言わない。

ステートフル化を行うため、HTTP 認証には所属していない。

認証アーティファクトの一時的な保管は、サーバーのセッション ID で行うため、認証解除 (ログアウト) をサーバー側で制御できる。

Cookie ヘッダーによる送受信では、CSRF の危険性がある。


ベーシック認証

▼ ベーシック認証とは

認証時に、平文の ID とパスワードを使用する認証スキームのこと。


▼ ベーシック認証の仕組み

ベーシック認証

役割 説明
クライアント リクエストの送信元アプリケーションのこと。文脈によっては、ブラウザがクライアントである場合とそうでない場合 (例:OAuth) がある。
ユーザー クライアントを使用している人物のこと。
サーバー クライアントからリクエストを受信し、レスポンスを返信するアプリケーションのこと。
(1)

最初、クライアントは、認証後にリクエストを送信できる Web ページのリクエストをサーバーに送信する。

GET https://example.com/foo-form
(2)

サーバーは、これ拒否し、401 ステータスで realm 名を設定し、レスポンスを返信する。

これにより、realm名の値をユーザーに示して、ユーザー名とパスワードの入力を求められる。

ユーザーに表示するためのrealm名には、任意の値を持たせられ、サイト名が設定されることが多い。

401 Unauthorized
---
WWW-Authenticate: Basic realm="<realm名>", charaset="UTF-8"
(3)

『<ユーザー名>:<パスワード>』を base64 方式でエンコードした値を Authorization ヘッダーに割り当て、リクエストを送信する。

POST https://example.com/foo-form
---
Authorization: Basic bG9naW46cGFzc3dvcmQ=
(4)

サーバーは、ユーザー名とパスワードを照合し、合致していれば、認証後の Web ページを返信する。

また、認証アーティファクトをブラウザのWebストレージに保管する。

200 OK
---
WWW-Authenticate: Basic realm=""
(5)

認証の解除時は、誤った認証アーティファクトをブラウザに意図的に送信させて認証を失敗する。

POST https://example.com/foo-form/logout
---
authorization: Basic <誤った認証アーティファクト>
(6)

サーバーは、401 ステータスでレスポンスを返信し、認証が解除される。

401 Unauthorized
---
WWW-Authenticate: Basic realm="<realm名>", charaset="UTF-8"


ダイジェスト認証

▼ ダイジェスト認証とは

認証時に、ハッシュ化された ID とパスワードを使用する認証スキームのこと。


▼ ダイジェスト認証の仕組み

200 OK
---
WWW-Authenticate: Basic realm="<realm名>", charaset="UTF-8"
POST https://example.com/foo-form
---
authorization: Digest realm="<realm名>" nonce="<サーバー側が作成した任意の文字列>" algorithm="<ハッシュ関数名>" qoq="auth"


03. トークンベース認証

トークンベース認証とは

アクセストークン (例:JWT トークン、JWT 仕様あるいはそうではないアクセストークン、Opaque トークン、Paseto トークンなど) を運搬する認証方法 (例:SSO、パーソナルアクセストークンなど) である。

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

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

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


認証方法の種類

  • JWT トークンによる認証
  • Opaque トークンによる認証
  • Paseto トークンによる認証
  • SSO


トークン

▼ 種類

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

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

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

トークンの種類 認証 トークンの情報タイプ
アクセストークン OIDC JWT トークン、JWT 仕様あるいはそうではないアクセストークン、Opaque トークン、Paseto トークンなどがある。ID プロバイダーのツールによっては JWT 仕様 (例:Keycloak) なため Self-contained トークン
ID トークン OIDC 必ず JWT 仕様であり、Self-contained トークン
リフレッシュトークン OAuth2、OIDC Self-contained トークン、Opaque トークン
パーソナルアクセストークン パーソナルアクセストークン認証 記入中...
XML ベースのトークン SAML 記入中...
API キー API キーベース認証 記入中...

▼ アクセストークン

  • JWT 仕様ではないアクセストークン
  • JWT トークン
  • Opaque トークン
  • Paseto トークン

▼ ID トークン

記入中...

▼ リフレッシュトークン

記入中...

▼ パーソナルアクセストークン

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

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

▼ API キーベース認証

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

信頼されたクライアントに発行することが前提であり、トークンよりも有効期限は長い (有効期限がない場合もある) 。

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

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


03-02. Bearer 認証

Bearer 認証とは

認証時に、Bearer トークンを使用する認証スキームのこと。


Bearer トークンとして使用できるトークン

▼ Bearer トークン (署名なしトークン) とは

単なる文字列で定義したアクセストークン。

Bearer 認証にて、トークンとして使用する。

署名なしトークンとも呼ばれ、実際に認証済みの本人か否かを判定する機能は無く、トークンを持っていればそれを本人として認可する。

そのため、アクセストークン文字列が流出してしまわないよう、厳重に管理する必要がある。

▼ JWT


Bearer 認証の仕組み

(1)

指定されたエンドポイントに対して、POST リクエストを送信する。

この時、Content-Typeヘッダーをapplication/x-www-form-urlencodedとする。

必要なボディパラメーターはAPIの提供元によって異なる。クライアントID、付与タイプなどが必要なことが多い。

POST https://example.com/foo
---
Content-Type: application/x-www-form-urlencoded
---
# ボディ
client_id=*****&grant_type=client_credentials&scope=messaging:push
(2)

レスポンスボディに Bearer トークンを含むレスポンスが返信される。

他に、有効期限、権限のスコープ、指定できる認証スキーマなどが提供されることが多い。

200 OK
---
X-Amzn-RequestId: d917ceac-2245-11e2-a270-0bc161cb589d
Content-Type: application/json
---
{
  "access_token": "*****",
  "expires_in": 3600,
  "scope": "messaging:push",
  "token_type": "Bearer",
}
(3)

発行された Bearer トークンを指定された認証スキーマで Authorization ヘッダーに割り当て、リクエストを送信する。

ここでは詳しく言及しないが、Bearerトークンをフォーム認証のようにCookieヘッダーに割り当てることもある。

POST https://example.com/foo
---
authorization: Bearer <Bearerトークン>
(4)

サーバーは、Bearer トークンを照合し、合致していれば、認証後の Web ページを返信する。

無効なBearerトークンをブラックリストとしてRedis/DBで管理しておく。

DBでブラックリストを管理すると、リクエストの度にDBアクセス処理が実行されることなってしまうため、Redisでこれを管理したほうが良い。

200 OK
---
WWW-Authenticate: Bearer realm=""
(5)

認証の解除時は、Redis/DB で Bearer トークンの状態を無効化する。

またサーバーは、401ステータスでレスポンスを返信し、認証が解除される。

401 Unauthorized
---
WWW-Authenticate: Basic realm="<realm名>", charaset="UTF-8"


正常系/異常系レスポンス

成功の場合は、realm 属性を空にしたレスポンスを返信する。

200 OK
---
WWW-Authenticate: Bearer realm=""

失敗の場合は、error 属性にエラメッセージを割り当てたレスポンスを返信する。

400 Bad Request
---
WWW-Authenticate: Bearer error="invalid_request"
401 Unauthorized
---
WWW-Authenticate: Bearer realm="token_required"
403 Forbidden
---
WWW-Authenticate: Bearer error="insufficient_scope"


04. 証明書ベース認証

クライアント認証、サーバー認証、相互 TLS 認証の仕組みのなかで使用する。


05. チケットベース認証

  • ケルベロス認証
  • SAML


06. ワンタイムコードベース認証

所有を表すコードを一時的に発行する。 多要素認証の仕組みのなかで使用する。

  • メール OTP
  • SMS OTP
  • TOTP (Google Authenticator 等)


07. ログアウト

▼ ブラウザを閉じたタイミング

ブラウザを閉じたときに、ブラウザは Cookie を削除する。

そのため、ログアウトが起こる。

▼ レスポンスの Expires ヘッダーで設定されたタイミング

レスポンスの Expires ヘッダーには Cookie の有効期限を設定できる。

ブラウザは有効期限に応じて Cookie を削除する。

そのため、ログアウトが起こる。

有効期限がない場合、Expires ヘッダーの値は Session となり、この Cookie を特に『Session Cookie』という。