1. ホーム
  2. 記事一覧
  3. JWTとは?アクセス制御に使う理由とSAMLとの違い

2024.04.14

JWTとは?アクセス制御に使う理由とSAMLとの違い

概要

マイクロサービスにおけるセッション管理の手法として再び注目されているJWTですが、今一度JWTについて理解を深めましょう!

JWTをしっかり理解すれば、アクセス制御、認証、認可においても困ることが少なくなるはずです。

JWTとは

JWT(JSON Web Token)とは、当事者間でデータをJSONとして安全に送信するための規格です。

コンパクトURLセーフな表記ルールが定められています。

jwt.io は、JSON Web Token (JWT) のデコード、検証、生成を可能にする無料のWebサイトです。開発者はこのツールを活用することで、JWT の仕組みを理解し、実際にトークンを生成・検証することができます。

JWTは、認証や認可の仕組みにおいて広く活用されており、セキュアなデータ交換を実現するための重要な技術となっています。

https://jwt.io/

JWTの特徴

まずはJWTの特徴を理解しておきましょう。

  • コンパクト

よく使うデータ項目のキー名を省略形にすることで、データサイズをコンパクトにしています。

  • URLセーフ

JSONデータをBASE64URLエンコードすることで、URLに直接記載できる(URLセーフな)エンコード方式を採用しています。

つまり、JWTは少ない文字数でエンコードされた文字列を送信する際に重宝されています。

JWTの主な利用用途

一般的なJWTの利用用途は以下のようなものがあります。

  • OAuth 2.0、OpenID Connectなどの認証プロトコルにおけるトークン
  • Cokkieを使うのが難しいマイクロサービスやモバイルアプリでのセッション管理
  • シングルサインオン(SSO)での認証
  • RESTful APIの認証
  • ステートレス認証

ここで疑問に思うのは、なぜエンコードされただけのJWTが認証に使われるのでしょうか?

その理由は、セキュアなデータ転送を実現するJWTのルールにあります。

JWTのルール

ルール

  • クレームをJSON形式で表現した文字列であること
  • JOSEに従って署名 or 暗号化がされていること
  • BASE64URLでエンコードされた文字列であること
  • 複数ブロックに分かれる場合は、 .(ピリオド) で区切る

(※クレーム、JOSEは後述)

クレームとは

  • JWTではJSONのキーと値のペアをクレームと呼び、キーをクレーム名、値をクレーム値と呼びます。
  • クレームの集合体はクレームセットと呼びます。

クレームには主にユーザー情報や、アプリケーションが利用する情報などが記載されています。

JWTの例

エンコード前

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

エンコード後

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

JOSEとは

「JOSEに従って署名 or 暗号化がされていること」がJWTのルールの一つとして出てきました。

この署名 or 暗号化のルールこそがJWTの肝になっています。

定義

JOSE(JSON Object Signing and Encryption)とは、JWTの署名と暗号化に関するルールを定めた規格です。

そのうち、JWTの署名に関するルールをJWS、JWTの暗号化に関するルールをJWEと呼びます。

(※JWSは後述)

JWSとは

定義

JWS(JSON Web Signature)とは、JWTにデジタル署名を付与する際のルールを定めた規格です。

JWTに署名を使用することで、JWTの改ざんを検知することができるようになります。

【補足】JWTの改ざんとは

JWT単体ではBASE64URLでエンコードしただけの文字列です。

もし悪意のある攻撃者がいれば、JWTをデコードした後、権限を修正し、再びエンコードするだけで簡単に不正アクセスできてしまいます。

そこで、改ざんされた場合のリスクが大きい情報の送受信にJWTを使う場合は、改ざんを検知できるJWSを使用しているのです。

(※トークンの有効期限を短く設定したり、クレームを正確に設定することも改ざんリスクの対策になります。)

JWSのルール

JWSは、ヘッダー.ペイロード.シグネチャーの3つから構成されます。

それぞれをBASE64URLエンコーディングした後、ピリオドで結合します。

ヘッダー

JWTの署名に必要な以下の2つの情報を記載する部分です。

  • 使用されている署名アルゴリズム (HMAC SHA256 や RSA など)
  • トークンの種類 (通常はJWTを指定)

ペイロード

実際のデータ(クレーム)を記載する部分です。

主にユーザー情報や有効期限、発行者などを記載します。

シグネチャー

署名を記載する部分です。

署名とは、 ヘッダーペイロードを結合したあと、暗号化して生成したトークンのことです。

この暗号化された署名と、実際のデータを照らし合わせることで、改ざんが行われたかどうかを検知することができます。

JWSの例

JWS準拠のJWTの例(エンコード前)

{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "1234567890",
  "exp": 1634710708
}
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secretKey
)

JWS準拠のJWTの例(エンコード後)

それぞれをエンコードした後、さらに .(ピリオド) で結合します。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwiZXhwIjoxNjM0NzEwNzA4fQ.
v40uDSCoa14j59CVD0bH-ZqnwYA_XF4aS7QEM_FZ8HM

JWTを利用したアクセス制御

JWSを用いたJWTは、改ざんを検知できるうえに、ユーザー情報やアクセス権限を含むこともできるという利点があります。

これを活かして、アクセス制御を簡素化するためにJWTを使用することが多いようです。

Webサイトでの使用例

Webサイトで認証・認可にJWTを使用した場合、以下のようになります。

  1. クライアントがID・パスワードなどの認証情報をサーバーに送信
  2. サーバーがDBの情報と照合し、認証に成功すればJWT形式のアクセストークンを発行してレスポンスで返す(認証
  3. クライアントがリソースにアクセスするときは、発行されたアクセストークンを付けてリクエストを送信
  4. サーバーがアクセストークン(JWT)を検証し、トークンに含まれる権限に基づいてリソースへのアクセスを許可/拒否する(認可

このように、JWTのアクセストークンを使用することで、リソースへのアクセス制御が簡単かつ安全に実現できます。

認証プロトコルでの使用例

OpenID ConnectやOAuth 2.0という認証プロトコルでは、トークンの記述方法にJWTを採用しています。

  • 例 : OAuth 2.0 Authorization Grants (認可)

      POST /token.oauth2 HTTP/1.1
      Host: as.example.com
      Content-Type: application/x-www-form-urlencoded
    
      grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&
     assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJpc3Mi[...omitted for brevity...].J9l-ZhwP[...omitted for brevity...]

他にもOAuth 2.0の認証や、OpenID ConnectのIDトークンにも使用されています。

アクセス制御にJWTを使用するメリット

JWTをアクセス制御に使うメリットは、主に認可処理の簡素化にあります。

  • ステートレスな認可処理 JWT内にユーザー情報やスコープが含まれているので、サーバー側でセッション管理を実装する必要がなくなる
  • 整合性の確保 JWSでデータが改ざんを検知することができる
  • 発行者の証明 JWSで署名に発行者の秘密鍵が使用されるので、発行者によるリクエストであると証明できる
  • 機密性の確保 JWEと組み合わせることで暗号化もできる

認証処理自体へのメリットは少ないですが、一度認証が済めば、JWTによってユーザー情報やアクセストークンなどを安全にやり取りできるので、それ以降の認可処理が簡素化されるのです。

他の規格との比較

ここで、よく比較対象としてあがるSAMLについても少しだけ理解しておきましょう。

どちらも認証・認可に使用される規格です。

SAML (Security Assertion Markup Language)

  • XMLベースのトークンの規格 (※)
  • IDプロバイダ(IdP)がトークンを発行するので、セキュリティ面で安心できる
  • 有効期限や発行者など必須項目が多く、複数のサービス間で連携しやすい(相互運用性)という点でシングルサインオン(SSO)に特化した設計
  • 認証コンテキスト(ユーザーがどんな認証方式で認証されたかという情報)を記載できる

※JSONベースの形式(SAML2.0のJSONプロファイル)もある

JWTとSAMLの比較表

項目JWTSAML
主な目的認可処理の簡素化認証処理の相互運用性の向上
用途アクセストークンSSO認証
サイズコンパクト大きい
属性情報最小限の情報ユーザー情報などを多く記載
有効期限オプション(expで指定可)必須
認証コンテキスト記載できない記載できる
発行ロジックの実装者リソース所有者が自ら実装IdPが実装

JWTとSAMLのどちらを使うべきか

どちらも認証・認可に使う規格ですが、用途が異なるため適切な規格を選ばなければなりません。

それでもどちらを使用すべきか悩む場合は、以下の項目を参考にしてみてください。

【JWTを使うべきケース】

  • アクセストークンの発行を目的とする場合
  • ステートレスなアーキテクチャが求められる場合
  • モバイルアプリなどクライアント側でトークンを保持する必要がある場合
  • データペイロードをコンパクトに保ちたい場合
  • 柔軟性が求められ、独自の属性をクレームに含める場合
  • シンプルかつ簡単に認証を実装したい場合

【SAMLを使うべきケース】

  • シングルサインオン(SSO)の実現を主な目的とする場合
  • 統合された認証基盤が必要な場合(IDプロバイダからのトークン発行)
  • 認証コンテキストの伝達や、厳密な属性要件がある場合
  • XML形式での運用が前提の既存システムとの連携が必要な場合

まとめ

JWTは認証・認可、アクセス制御においてとても重要なので、理解しておけば必ず役に立ちます。

ここで豆知識ですが、JWTは「ジョット」と発音するのが一般的で、文脈によっては「ジェイ・ダブリュー・ティー」「ジェイソン・ウェブ・トークン」とも言います。

JWTの仕組みと合わせて発音も知っておけば、突然「ジョットが~」と話題に上がった時、焦らなくて済むでしょう。

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事