今回も失敗談を書き連ねていきたいと思います。Nest JSを用いて、Azure AD B2Cのアクセストークンを検証する方法を調べてみました。公式が提供しているライブラリではなく、Auth0が提供しているライブラリとpassportというライブラリを組み合わせて、アクセストークンの検証を実装しています。わからん!
挨拶というか導入というか…
どもども!最近は暑くて寒いのでドアを窓という窓を全開にして換気している龍ちゃんです。いつもは、検証して納得した内容をブログに書いているのですが、今回は上司に質問するために現情報を報告するためだけにブログ化していきたいと思います。ちなみにプロジェクトではないので、そんな急ぎの内容ではないことだけ、先に書いておきます。
今回は、「フロントとバックエンドの接続時にアクセストークンを使用してセキュアに運用する」で触れていた内容に対して、具体的な対処法のサンプルが動いたのでまとめていきたいと思います。具体的なシナリオとしては「アクセストークンをを検証する方法をNest.jsで実装したい」になります。
以下が簡単なアーキ図になります。
今回のブログでは、前提知識として「Azure AD B2Cでのログイン」と「Headerにアクセストークンを挿入する」の2つが求められます。以下が、それぞれについてまとめたブログになっているので、もしお時間があれば読んでみてください。
さて、前提知識や物語の導入は終わりました。
本題のようなもの…
今回は、いつもの形式と異なる感じでブログを執筆していきたいと思います。若干の物語形式で書いていこうと思います。失敗談がたくさんありますので、供養もかねて書いていこうと思います。
Step.1 公式のライブラリが非推奨というちょっと怖い話
導入でも触れましたが今回は、「アクセストークンをを検証する方法をNest.jsで実装したい」になります。もちろんこの方法については、公式で解説されています。どうやら以下のライブラリを使用するようです。
npm install passport passport-azure-ad
公式が解説を載せているので、これを「Nest.js」用にカスタマイズするだけで済みそうです….
と!!思うじゃないですか?というか僕も思っていました。なかなか動かないので、公式のGitHubを覗きに行ったときに問題が発覚しました。この「passport-azure-ad」というライブラリがアーカイブされていました。はい、しかも明確に非推奨になっていました。
とりあえず、これを見つけてから頭を抱えましたね。とりあえず、一度見なかったことにして実装しました。実装に必要だった足跡だけ記載しておきました。
非推奨のpassport-azure-adを使用してトークンの検証を行うための足跡
Step.2 自前でトークンの検証を行うことはムリゲー
さて、Nest.jsの公式を見ると、トークンの検証にpassortを使用することは問題なさそうであるということまではわかりました。
もう一度、公式のAuthenticationのページを見るとJWTを自前で発行して、自前で検証する方法についての記載はありました。どうやらNest,jsの@nestjs/jwt
内のJwtService
を使用すると、トークンをデコードできるようです。そのため、トークンの検証を自前で実行することはできそうです。とりあえず、デコードして値を抽出する部分まで実装することができました。
今度は、Azureの公式にある「署名の検証」というページにたどりつきました。トップに書いてある文言を引用します。
To validate a token, your application should check both the signature and claims of the token. Many open-source libraries are available for validating JWTs, depending on your preferred language. It’s recommended that you explore those options rather than implement your own validation logic.
要約すると「自前で署名の検証すると危ないよ~ライブラリを使おうね~」とのことです。さて全力で困りました。とりあえず、こちらも実装のめどが立ったので足跡だけ記載しておきます。
Azureがおすすめしない自前でトークンを検証するための足跡
Step.3 そもそもトークンの検証って何をしたいんや??
とりあえず、3日ほどかけてやっていたことは非推奨であるという結論が出てフリーズしていました。そういえば、アクセストークンの検証はどうするものか?ということについて疑問を持ったので調べてみました。
とりあえず、3つの要素から構成されていることがわかりました。厳密に署名の検証をする場合は、本文の中の検証だけでなく、ヘッダーと署名両方をチェックする必要があり、自前で実装するとなると骨が折れるというところまでは理解できました。こちらのサイトで勉強しました。
なんとなくですが、検証に必要な知識を手に入れることに成功しつつあるような気がするので、いったんここで図に起こしておきます。
「JWTの発行元から検証に必要な情報を取得して、それを用いてトークン検証を実行する」までが一連の流れかと思います。そして、この憲章に必要な形式もOpen ID Connectの標準仕様という便利な言葉によって共通化されているようです。つまり、「トークンの検証に必要な情報」をAzure AD B2Cから取得することができれば、passport
のライブラリで検証することができるようです。
Step.4 別のライブラリで解消したっていう解決策
最終的にこちらの記事にたどりつきました。こちらの記事では、Auth0が提供しているpassport-jwks
というライブラリを使用して、検証に必要な情報を収集しています。Azureのこちらのページから情報を取得して、jwks_uri
を取得してJWKSを取得してます。ひとまず、こちらで非推奨のpassport-azure-ad
と同等の結果が得られました。
passportとjwks-rsaを用いてトークンの検証を行う足跡
終わりに
お疲れ様です。今回は、一週間の行動ログみたいな流れでブログを書いてみました。フロント側の実装は簡単に実装できたのですが、バックエンドの検証がうまくいっていないので悩ましいです。
ひとまず動くものは実装することができたので、「上手くいった」といっても良いかもしれません。
といいますか!!バックエンドの検証をしたい理由はStripeをもっと素振りしたいからなんですよね!ひとまず、ここは実装としてうまくいったとして次に進みます。2つしかStripe関連の記事は書いていないのですが、これが増えると良いですね。
今回のサムネは結構お気に入りです!
ではまた~~!グッ!( •̀ᴗ•́ )و ̑̑