Auth0でIP制限を実現しようとしたが断念した話
特定グローバルIP(以下、GIP)からのリクエストのみ許可する機能(以下、IP制限)を実装する必要があった。
認証プラットフォームとしてAuth0を使用しているので、以下のように実装してみた。
どうやってAuth0のログイン後に処理を追加するのか
少し調べてみるとAuth0 Rules
機能を使ってる記事が結構ヒットしたので、とりあえず公式ドキュメントを確認してみた。
公式ドキュメントの冒頭に、If you want to extend Auth0, we highly recommend you use Actions, which are a cornerstone of our overall extensibility product. とあったので、Auth0 Actions
を使うことにした。
Auth0 Actions
簡単に説明すると、Auth0の特定タイミングで実行される関数をNode.jsで実装できる。
AWS Lambda
のようなイメージだと思ってもらえれば良いかなと。
2021/11/14時点だと、以下のタイミングで実行させることができる。
触ってみる
Step1: Auth0に関数を追加する
右上の「Build Custom」から作成していきます。
関数名とか入力するモーダルが表示されるので適当に入力してCreateする。
雛形が作成されるので、ここに関数を実装して右上の「Deploy」を叩けば作成できる。
使用できるオブジェクトはevent
とapi
で2種類ある。
exports.onExecutePostLogin = async (event, api) => { // 解説1 if (event.client.client_id === "hogefugabuzz") { // 解説2 if (event.request.ip !== "xxx.xxx.xxx.xxx") { api.access.deny(`Access to ${event.client.name} from ${event.request.ip} is not allowed.`) } // 解説3 api.idToken.setCustomClaim('allowed-ip', event.request.ip) } };
- 解説1
event.client.client_id === "hogefugabuzz"
- Auth0は複数Applicationから共通で使用される認証プラットフォーム
- 特定Applicationのみ関数を実行する場合は、関数側で制御するする必要がある
- 解説2
event.request.ip === "xxx.xxx.xxx.xxx"
- リクエスト元のGIPを取得して許可されたIPであることを確認する
- 解説3
- 発行されるJWTに許可されたGIPを追加する
Step2: 作成した関数をログイン処理に追加する
今回はLoginに対して処理を追加したいので、Choose FlowでLoginをクリックする。
すると、ログインしてからJWTを発行するまでのフローが表示された。
Add Actionから先程作成した関数をDrag&DropしてApplyするだけでOK!!
断念した理由
ここまで見ると順調に見えると思います。私もそう思ってました。
実際に動かしてみると、どうもうまくいきません。
デバッグしていくと... event.request.ip
で取得するIPアドレスがIPv6になってる!?!?!?!?!?!?
IPv4で制限をかけたいという要望だったのですが、どうやらv4とv6が混在するみたいです。
(以下、参考記事)
Context.Request.IP returns IPv6 address lately - #2 by john.gateley - Auth0 Community
In Rules, ipv6 IP address comes [sorry, resend] - #10 by tanver.hasan - Auth0 Community
最終的にどうしたか
Auth0で実現するのは断念して、アプリケーション側かEKS使ってるのでIstioでなんとか実現できないか再検討しています。
IPv6がこんな身近に迫ってきてるんだなというのを感じるいい機会でした。
皆さんもIP制限を実現しなければいけない時には、しっかり検証しておくことをオススメします。
クラメソさんの記事があったので、IP制限を検証するところまではスムーズに進みましたmm
Auth0のActionsでログイン時のIPアドレスを制限してみた | DevelopersIO