JSON Web Token
概要
JWTでは、トークン内に任意の情報(クレーム)を保持することが可能であり、例えばサーバはクライアントに対して「管理者としてログイン済」という情報を含んだトークンを生成することができる。クライアントはそのトークンを、自身が管理者としてログイン済であることの証明に使用することができる。トークンは当事者の一方(通常はサーバ)または両方(もう一方は公開鍵を提供する)の秘密鍵により署名されており、発行されたトークンが正規のものか確認することができる。
JWTのトークンはコンパクトな設計となっており[1]、またURLセーフであり[2]、特にウェブブラウザでシングルサインオン (SSO) を行う場合に使いやすくなっている。トークンには一般的に認証プロバイダやサービスプロバイダが認証したユーザー識別情報が格納される他、各々のサービスで必要な情報も格納される[3][4]。
JWTは他のJSONベースのオープン標準であるJSON Web Signature (JWS, RFC 7515) とJSON Web Encryption (JWE, RFC 7516) に拠って立っている[5][6][7]。
構造
JWTのトークンは以下の3つの要素から構成される。
| ヘッダー | {
"alg" : "HS256",
"typ" : "JWT"
}
|
署名生成に使用したアルゴリズムを格納する。
左記の 署名アルゴリズムとしては、SHA-256を使用したHMAC (HS256) や、SHA-256を使用したRSA署名 (RS256) がよく用いられる。JSON Web Algorithms (JWA, RFC 7518) では認証や暗号化用のさらに多くのアルゴリズムが提示されている[8]。 |
|---|---|---|
| ペイロード | {
"loggedInAs" : "admin",
"iat" : 1422779638
}
|
認証情報などのクレームを格納する。JWTの仕様では、トークンに一般的に含まれる7つの標準フィールドが定義されている[9]。また用途に応じた独自のカスタムフィールドを含むこともできる。
左記の例では、トークン発行日時を示す標準のクレーム ( |
| 署名 | HMAC-SHA256(
base64urlEncoding(header) + '.' +
base64urlEncoding(payload),
secret
)
|
トークン検証用の署名。署名は、ヘッダーとペイロードをBase64urlエンコーディングしてピリオドで結合したものから生成する。署名はヘッダーで指定された暗号化アルゴリズムにより生成される。左記はHMAC-SHA256形式でのコード例である。Base64url方式は、Base64を元に特殊記号やパディングの扱いを変えたものである。 |
これら3つの要素は、Base64urlエンコーディングされた上で、ピリオドにより結合される。以下にコード例を示す。
const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)
上記データは、秘密鍵が"secretkey"の場合、以下のようなトークンとなる。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
使用
ユーザーがサーバにログインを行う場合、従来のセッションによる認証ではCookieにてセッションIDが返されるが、JWTにおいてはトークンが返され、それをローカルに保存して利用する(主にlocal storageやsession storageが用いられる。セッションIDのようにCookieを用いる場合もある)。
ユーザーが認証が必要な機能やリソースにアクセスする際、クライアントはトークンを何らかの手段、主としてAuthorizationヘッダーでBearerスキーマを用いてサーバに送信する。この場合、Authorizationヘッダーは以下のような形式となる。
Authorization: Bearer eyJhbGci...(中略)...yu5CSpyHI
JWTは、サーバ上に認証状態を保持しないステートレスな認証方式である。サーバはAuthorizationヘッダーで渡されたトークンが正しいかだけを検証し、アクセスを許可する。JWTにおいては、認証に必要な情報は全てトークン内に格納されており、データベースへの問い合わせを削減することができる。
標準フィールド
RFCにおいては、ペイロードに含める以下のような標準フィールド(クレーム)が定義されている。
| コード | 名称 | 説明 |
|---|---|---|
iss |
Issuer | トークン発行者の識別子。 |
sub |
Subject | トークンの主題の識別子。 |
aud |
Audience | トークンが意図している受信者の識別子。トークンを受け付ける受信者は、この値に自身が含まれるかを識別しなければならない。もしaudクレームが存在し、かつ自身が含まれない場合、トークンを拒否しなければならない。 |
exp |
Expiration Time | トークンの有効期限。この期限以降の場合、トークンを受け付けてはならない。有効期限は1970-01-01 00:00:00Zからの秒数を数値で指定する(UNIX時間)[10]。 |
nbf |
Not Before | トークンの開始日時。この期限以降の場合、トークンを受け付けてよい。秒数を数値で指定する。 |
iat |
Issued at | トークンの発行日時。秒数を数値で指定する。 |
jti |
JWT ID | 発行者ごとトークンごとに一意な識別子。 |
また、ヘッダーには以下のフィールドが使用可能である。
| コード | 名称 | 説明 |
|---|---|---|
typ |
Token type | トークンの形式。JWTとすることが推奨される。 |
cty |
Content type | JWTを入れ子にして署名や暗号化を行う場合、このフィールドにJWTを指定する。それ以外では通常指定しない。[9] |
alg |
Message authentication code algorithm | 発行者が使用した署名アルゴリズム。任意のアルゴリズムが指定可能だが、いくつかのアルゴリズムは安全ではない。[11] |
| その他、JWSとJWE由来のヘッダーが存在する[6][7]。 | ||
脆弱性と批判
JWTはステートレスであることから、JWT単体ではトークンを無効にすることが出来ない。従来のセッション同様、サーバに状態を保持すれば可能だが、その場合ステートレスの利点は失われる[12]。
セキュリティコンサルタントのTim McLeanは、複数のJWTライブラリがalgクレームに署名無し (none) 等を指定した不正なトークンを処理してしまう脆弱性を報告した。これらの脆弱性は修正されたが、McLeanは同様の問題を防ぐためalgクレーム自体を廃止すべきだと主張している[11]。
署名アルゴリズムの脆弱性については、以下のような方法で対策が可能である[13]。
- JWTヘッダーだけを見て検証しない。
- アルゴリズムについて知る。
- 適切なキーサイズを用いる。
出典
- Nickel, Jochen (2016). Mastering Identity and Access Management with Microsoft Azure. p. 84. ISBN 9781785887888 2018年7月20日閲覧。
- “JWT.IO - JSON Web Tokens Introduction”. jwt.io. 2018年7月20日閲覧。
- Sevilleja, Chris. “The Anatomy of a JSON Web Token”. 2015年5月8日閲覧。
- “Atlassian Connect Documentation”. developer.atlassian.com. 2015年5月8日閲覧。
- “draft-ietf-oauth-json-web-token-32 - JSON Web Token (JWT)”. tools.ietf.org. 2015年5月8日閲覧。
- “draft-ietf-jose-json-web-signature-41 - JSON Web Signature (JWS)”. tools.ietf.org. 2015年5月8日閲覧。
- “draft-ietf-jose-json-web-encryption-40 - JSON Web Encryption (JWE)”. tools.ietf.org. 2015年5月8日閲覧。
- “draft-ietf-jose-json-web-algorithms-40 - JSON Web Algorithms (JWA)”. tools.ietf.org. 2015年5月8日閲覧。
- John, Bradley. “JSON Web Token (JWT)”. tools.ietf.org. 2016年11月14日閲覧。
- John, Bradley,. “JSON Web Token (JWT)” (英語). tools.ietf.org. 2017年12月20日閲覧。
- McLean, Tim (2015年3月31日). “Critical vulnerabilities in JSON Web Token libraries”. Auth0. 2016年3月29日閲覧。
- “Stop using JWT for sessions”. joepie91 Ramblings. 2018年8月1日閲覧。
- “Common JWT security vulnerabilities and how to avoid them” (英語). 2018年5月14日閲覧。
外部リンク
- jwt.io(英語) - Auth0によるJWT特設サイト
- JSON Validator(英語) – JWTのバリデート
- OpenID Foundation Japan - JSON Web Token (JWT) - RFC 7519ドラフト版の日本語訳
- RFC 8725 JSON Web Token Best Current Practices