UD Day 17 アーキテクチャーの検討12(Authを考慮したアプリサーバー構成)

仮に認証方式としてJWTを採用する場合のアプリサーバーの構成がどのようになるか?について、考察してみたいと思います。

JWTには、有効期限の短いaccess tokenと有効期限の長いrefresh tokenの2つを用いるというやり方があります。
クライアントは、初回ログインで認証を行うサーバーから上記二つを得て、以降のやり取りでは、必ずaccess tokenをつけて、トランザクション処理を行います。
access tokenが期限切れとなったら、refresh tokenを使って、認証サーバーからaccess tokenを発行してもらい、以降のやり取りではこれをつけて、トランザクション処理を行います。refresh tokenと有効期限の情報は、DBに保存します。Refresh tokenがJWTの形式の場合、exp(有効期限)をtokenの2つ目のClaim内に含むので、tokenのみを保存すれば良いということになります。
実際のログイン時のHandshake(クライアント・サーバー間の処理の流れ)は別記事にて記載予定ですが、上記を踏まえると、サーバーの機能としては認証を行うものとそれ以外の処理を行うものの2つに分けることができそうです。つまり、以下のような構成になります。

サーバー構成と利用するTokenの種類

上記の構成でAuth ServerとResource Serverがそれぞれ認証サーバー、それ以外の処理用のサーバーとなりますが、これらの役割を共有にするという考え方もできます。しかしながら、トークンの生成・解読の際に利用する秘密鍵の漏洩に対するリスクを最小化する場合には、共有よりも役割を分けることが望ましいと考えました。その結果として、上記の構成を採用しています。(続く)

参考リンク)
JWTの実装方法についての質問

UD Day 16 アーキテクチャーの検討11(Auth)

認証と認可について、どのように行うかを考える場合、StatefulとStatelessの2つのどちらを採用するかを検討する必要があります。それぞれの特徴をまず見ていきます。

Stateful
 いわゆるウェブのセッション管理。
 タイムアウトは10分〜2時間が一般的。
Stateless
 JWT(JSON Web Token: RFC7519)というJSONのオブジェクトにセッション情報を保持し、サーバーでの保管が不要。
 JWTのtokenは、.(ドット)で3つに区切られた文字列(1つ)である。
 3つのセクションは、ヘッダー(アルゴリズムとJWTのタイプ)、Payload(ユーザー情報、メタデータ)、電子署名(左記2つとsecret(鍵)から作成)である。
 JWTで利用するライブラリーは脆弱性がないことを確認する必要がある。
 アルゴリズムがnoneの場合の脆弱性があるので、noneのものは一律failさせるべきである。
 secretはissuerとconsumerだけで保持し、外には出さない。
 sensitiveデータをJWTの中に含めない。含める場合には、JWEを利用する。
 replay attackに対する対策として、jti claim(nonce: ワンタイムパスワード)の利用、有効期限、作成日時の情報を含める。
 詳細は、OWASPのガイドラインなどを確認する。

OWASPでは、Statelessが徐々に増えており、脆弱性をクリアすれば、良い方法と記載されています。しかしながら、JWTを非推奨としているポストも多くあり、Statelessの採用を考えがたくしています。

まとめると、Statefulは、取り得るオプションですが、各トランザクションの頭にsession-idの確認があり、このreadがオーバーヘッドとして常に加算されます。また、セッションの時間が短いのもユーザービリティの観点で問題となり得る可能性があります。Statelessについては、最もメジャーなのは、JWTですが、色々と指摘されている問題があります。Webアプリの前提か、nativeアプリの前提かでも異なるので、これらの点を踏まえて決める必要があります。

ちなみに上記リンクで考慮すべきとしているポイントは以下のものになります。これらの観点で自分のアプリがどうなるかを考慮した上で、最終的な方式を決定しました。
 (1) They take up more space(サイズが小さくない)
 (2) They are less secure(セキュアではない)
 (3) You cannot invalidate individual JWT tokens(サーバー側で無効化できない)
 (4) Data goes stale(データが古くなる)
 (5) Implementations are less battle-tested or non-existent(長い期間の試行を経ていない)

仮にJWTを採用する場合どのようなサーバー構成にすべきでしょうか。また、一連のやり取りはどのようになるでしょうか。次はそれについて言及します。(続く)