Azure AD B2CをPHPと使う (4) JWT検証について

サーバー側はAPI実装に専念し、APIではトークンの検証を行います。

Azure AD B2CをPHPと使う (2) SPAから送られてきたトークンを検証する - noopableの日記 (hatenablog.jp)

という記事を先日書きましたが、現在のところJWTの検証が中心課題となります。

総合雑感

認証用のサービスとしても、提供されているSDKの品質でもAuth0が先行している感じですね。

個人的には、firebase/jwtがよいかなと思っています。

 

JWT検証の仕組みなど

まずは、こちらの記事がわかりやすいです。

Get Started with JSON Web Tokens - Auth0

 

日本語ではこちらでどうでしょう。

webbibouroku.com

 

JSON Web Tokens - jwt.io で、具体的に、エンコード、デコードを試すことができます。実装中にデバッグするときなど便利ですね。

これを基本として、

JWT検証について考えるべきこと

Auth0さんで、セキュリティ上の問題などを指摘していただいています。

auth0.com

いろいろと参考になります。自分で実装する場合やライブラリの検証を行う際には注意してみたいと思います。

この記事で、

これだけのベスト プラクティスに対応するのは荷が重すぎると思われる場合は、一部作業を外部プロバイダーに委託するのも一案です。その際にはぜひ Auth0 の利用をご検討ください。外部に委託できない場合は、この記事で挙げた推奨事項について入念に検討しましょう。そして、暗号化の方法は決して自作せず、テストを重ねた実績あるコードを利用するようにしてください。

 まったく賛成で、Auth0かAzure AD B2Cを候補に考えています。

それでもサーバー側の実装については知識や経験を持っていることが求められると思います。たとえば、上記のページに出ている攻撃パターンなどについてチェックすることはもちろん、安全側に振ったチェックも必要ですし、仮に後述するfirebase/php-jwtを使うとしても、現行サービスで利用していないアルゴリズムは検証する前に弾くとか、オプションのclaimでも追加でチェックするといった形で手堅くいきたいですね。

 

JWT用のPHPライブラリの一覧など

JSON Web Tokens - jwt.io

こちらのサイトでは登録されたライブラリがトークンのチェックなどにどのように対応しているのかが示されているようです。

結構たくさんありますね。

いくつか見てみましたが、これが究極的にシンプル!

luciferous/jwt: PEAR package for JWT (github.com)

JWTクラスだけが定義してあります。

こういった、濁りのない基底クラスをキッチリ作って始めていく習慣が必要だと思います。他のフレームワーク用のライブラリなどではフレームワークと密結合してしまい流用できないものが多く悲しくなります。

最も基本的なクラスだけでは仕事にならないので、上をフォークしたFirebaseプロジェクトのphp-jwtを見てみます。

github.com

これいいですね。テストもわかりやすく、安心感があります。

ライセンスはBSD v3。

 

他にめぼしいところというと、これからな。

nowakowskir/php-jwt: JSON Web Tokens (JWT) implementation for PHP 7. (github.com)

PHP7用となっていますが、中身はシンプルで必要なものが揃っている感じはします。

 

JWT用のAuth0用ライブラリなど

そのAuth0がPHP用のライブラリを公開していることは有名かもしれません。

Auth0 PHP API SDK Quickstarts: Authentication

Auth0-PHP Basic Use

Validate JWTs with Auth0-PHP

基本通りに書かれていて、他のフレームワーク等で流用しやすくなっています。MITライセンスですし、Auth0だけではなく、Azure AD B2Cで使用する際にも、微調整で対応できるかもしれません。

クラス構成で考えると、これも有力

lcobucci/jwt: A simple library to work with JSON Web Token and JSON Web Signature (github.com)

Symfony界隈はどうなのか。

本格的にSymfonyを使っているわけではないので、他によいソリューションがあるのかもしれませんが、

lexik/LexikJWTAuthenticationBundle: JWT authentication for your Symfony REST API (github.com)

このバンドルが使われているケースが多いでしょうか。

Symfony用のバンドルですから、フレームワーク用のファイルが増えるのはやむを得ないと思いますが、他のフレームワークや素のPHPで使いやすいかというと、全く使えないです。クラス構成など、正規化されていないDBを見るようで憂鬱です。これがSymfonyバンドルの標準なのでしょうか・・・

Securing Symfony API with JWT | OAuth and OpenID Connect Done Better (curity.io)

これならむしろ、Azure AD B2C用の古いサンプルがLaravel用で公開されていましたが、そちらに軍配を上げる感じ。

 

Introduction - JWT Framework (spomky-labs.com)

web-token/jwt-framework: JWT Framework (github.com)

その名もJWT Framework。Symfony Insight シルバーメダルがついています。

JWS (RFC 7515)、JWE (RFC 7516)、JWK (RFC 7517)、JWT (RFC 7519)などにも対応しているようです。