🪪

認証基盤統合の企画から設計過程を紹介します!

2024/12/25に公開

はじめに

ユニフォームネクスト株式会社でテックリードをしているぽてぽぽです。
弊社では2024年夏頃に、現状の認証基盤を廃止し、新しい認証基盤にリプレースする「認証基盤刷新PJ」が立ち上がりました。
本記事では、プロジェクトの企画フェーズから設計フェーズまでどのように進めてきたかをお話ししていこうと思います。
自システムの認証基盤に課題感を抱いていて、これからリプレースしていきたいと考えている開発者の皆様の参考になれば幸いです。

背景

弊社では、自社サービスを内製化しており、現在で主に以下の2つのサービスを開発・運用しております。

  • ユニフォームECサイト(BtoC・BtoB Eコマース)
    • レガシーな技術スタック
    • モノリシックアーキテクチャ
    • 独自の認証システム
  • ユニフォーム申請管理サービス(BtoB SaaS)
    • モダンな技術スタック
    • マイクロサービスアーキテクチャ
    • Firebase Authenticationによる認証

課題点

現在の認証基盤では、以下の課題や懸念を抱えておりました。

  • シングルサインオンが困難で、ログイン画面が別れておりユーザー体験が悪い
    • 独自の認証システムはCookieベースのためドメインを跨ぎのセッション維持ができない
    • Firebase AuthenticationはOIDC認可サーバーとしての機能を有していない
  • ユーザーの一元的なID管理ができない
    • ユーザーごとにサービス間で重複したアカウントが存在する
  • ソーシャルログインがなく、会員登録時の離脱が生じている
    • 独自の認証システムを改修するのは現実的ではない
  • 運用コストやセキュリティリスクが大きい
    • 脆弱性管理や保守対応に2倍の労力がかかる
    • 独自の認証システムでは、セキュリティを担保するのに膨大なコストがかかる

このような課題から、認証基盤の統合を進めていくことが決まりました。

構想

As-Is

To-Be

  • 認証・認可サービス
    • 各サービスにシングルサインオン可能
    • ソーシャルログイン可能
  • 顧客管理サービス
    • 顧客マスタの一元化
    • 顧客情報を管理する機能

今回認証基盤を統合するにあたり、顧客情報が重複しているという課題もあったため、同時に顧客管理機能も切り離し、マイクロサービス化することにしました。
顧客情報管理が切り離されることで、事業面と技術面で以下のメリットがあります。

  • 顧客情報の分析が行いやすくなる
  • 受発注などの情報は顧客に紐づいているため、今後それらをマイクロサービス化しやすくなる

また開発方針について、顧客管理サービスは、要件に柔軟に対応できるスクラッチ開発で行い、認証認可サービスは高度な技術が要求されるため、OSSまたはSaaSを利用し、開発コストを下げるという方針を取りました。

認証・認可サービス選定

選定において以下のような軸を定めました。

  • フロントのUIやバックエンドロジックのカスタマイズ性の観点
  • 移行の際のユーザー離脱など、ビジネス的インパクトの観点
  • 導入コスト・運用コストの観点
  • セキュリティの観点

比較

ID管理(IAM)の機能を提供するソフトウェアは、OSSだとJavaベースのKeycloakやGoベースのHydra、SaaSだとAuth0Amazon Cognite、国産SaaSではAutheleteなどが挙げられます。
今回はその中から、要件を達成できそう、かつ比較的実装コストが軽そうなKeycloakAuth0Amazon Cogniteの3つを比較対象としました。

keycloak

項目 評価 コメント
ランニングコスト OSSなのでライセンス費用はなし
別途インフラ費用がかかる
初期開発コスト 環境構築やカスタマイズ、インフラ構築などが必要
技術的難易度 × 専門のJavaエンジニアが少なく、学習コストもかかる
サービス市場投入時間 初期開発が必要で即時の投入は困難
カスタマイズ性 SPI[1]によりUIやロジック共に柔軟なカスタマイズが可能
移行性 標準では一括移行のみで、パスワードの引き継ぎが難しい
セキュリティ 基本的なセキュリティ機能は有しているが、高度なセキュリティ機能は別途実装が必要
機能追加 × 自社で設計構築が必要
アップデート・パッチ適応 定期的なアップデートが行われているが、適用するのは手動

Auth0

項目 評価 コメント
ランニングコスト × 高額、MAU[2]数の従量課金
初期開発コスト 画面のカスタマイズ、コネクションやアプリケーション、APIの設定
技術的難易度 GUI管理コンソール上から設定が可能
サービス市場投入時間 カスタマイズ度合いによるが即時の投入も可能
カスタマイズ性 クラシックログインでは、柔軟にUIをカスタマイズできるが、機能制限が存在し非推奨
ユニバーサルログインでは、レイアウト・スタイルなどの変更は可能
ロジック部分はActionsによってある程度の拡張が可能
移行性 一括移行・自動移行が選択可パスワードの引き継ぎが可能
セキュリティ リスクベース認証など、高度なセキュリティ機能がある
機能追加 標準で提供される機能は、有効化すれば即時に使用可能
アップデート・パッチ適応 活発にアップデートが行われており自動

Amazon Cognite

項目 評価 コメント
ランニングコスト MAU数の従量課金だが、低額
初期開発コスト 画面のカスタマイズ、コネクションやアプリケーションの登録
技術的難易度 AWS管理コンソール上から設定が可能
サービス市場投入時間 カスタマイズ度合いによるが即時の投入も可能
カスタマイズ性 UIのカスタマイズが困難で、日本語に対応していない
ロジック部分はLambdaである程度の拡張が可能
移行性 標準では一括移行のみ
独自のLambdaを定義すれば、自動移行、パスワード引き継ぎも可能
セキュリティ 一定のセキュリティ機能が付随している
機能追加 標準で提供される機能は、有効化すれば即時に使用可能
アップデート・パッチ適応 自動だが、活発なアップデートが行われていない

検討概要

Keycloakは、Reactなどのフロントエンドライブラリを用いて画面を実装できたり、SPIによってサーバー側の機能が抽象化されているため、ロジック部分を柔軟に拡張することができます。
また、OSSなので、ライセンス費用等が発生しないのがメリットですが、弊社のエンジニアにJavaエンジニアが少なく、脆弱性管理等のセキュリティ面でも保守のコストが増大しそうなので断念しました。

Amazon Cogniteは、SaaSなので初期開発コストや保守コストも低く、何より1MAUあたりの料金単価が非常に安いのが魅力でした。
しかし、標準で提供されるHosted UIの部分のカスタマイズ性がほとんどなく、日本語に対応していない点が問題でした。

Auth0は、CIAM[3]に特化したSaaSであるため、カスタマイズ性やセキュリティ機能についてはかなり充実している印象でした。
また、標準で自動移行(ユーザーのログイン処理をトリガーにして、オリジナルのデータソースから認証を確認し、ユーザープールに追加する)をサポートしており、一括移行の場合でもパスワードのハッシュアルゴリズムを同時にインポートできるため、パスワードのリセットが発生しません。
これにより移行時のユーザーの離脱が発生しにくく、ビジネス的にインパクトが抑えられる点が非常に優秀です。
ただ、1MAUあたりの料金がそれなりに高いので、ビジネスモデル次第で費用対効果が出しにくく、選択のハードルも高そうだと感じました。

結論

最終的に、Auth0が機能面およびビジネス面の要件をバランスよく満たすソリューションであると判断しました。

  • 移行時のユーザー体験を損なわない仕組み
  • 柔軟なカスタマイズ性と高いセキュリティ機能
  • 迅速な導入と運用の効率性

以上の観点で優れており、弊社の今後の事業展開や開発体制を鑑みて、最適な選択肢であると結論づけました。

アーキテクチャ

最終的なAWS上での構成がこちらです。
※フロントエンド部分や各サービスの細かいリソースなどは省略しています。

解説

  • サービス間通信は全てLattice Service Networkを経由

    • VPC間を閉域で通信可能
    • ルーティングなどのIPレイヤー上の設定をオフロードできる
    • ターゲットグループにECSクラスターが対応しており、ALBが不要になる
  • API部分をAPI Gatewayで一元管理

    • Lambda Authorizerでアクセストークンの検証を行い、キャッシングできる
    • VPC Linkによって内部NLBへプロキシすることで、オリジンのELBエンドポイントをパブリックネットワークから隠蔽できる
    • Fargate Service上でGraphQL Federation Serverを起動し、Lattice Network経由で各サブグラフのサーバーへ通信
  • サービス間の認可はAuth0のM2M認可を利用

    • Lattice ServiceでのIAM認証も考えたが、アクセストークンによる認可で統一できるのがメリット
    • VPCからAuth0に抜けるトラフィック(M2M通信用のトークン取得など)を顧客管理のFargate Serviceでプロキシすることで、余分なNAT Gatewayを削減

課題

  • Auth0のエンドポイントのIPアドレスが動的なので、Nat Gatewayから抜けるトラフィックのIP制限ができない
    → Route 53 Resolver DNS Firewallで名前解決の制限をする、もしくはAuth0に設定したカスタムドメインでAuth0へプロキシするサービスに静的IPを設定しそのIPで制限をかける
  • あるサービスからGraphQL Federationにリクエストした時、そのサービス自身のサブグラフを含めてしまうと、通信がループしてしまう可能性がある
    → 自分自身のサブグラフを参照するパターンは、原則的に存在しないと考えられるため、
    アクセストークンのsubの値とサービスのクライアントIDを比較して、等価であればエラーをスローする

おわりに

今回は、弊社での認証基盤統合の企画から設計過程を紹介しました。
もちろん、ビジネスモデルやビジネス規模などの事業的な視点や、開発体制や開発リソース、既存のシステムのアーキテクチャなどの技術的な理由により、取りうる選択肢は変わってくると思います。
あくまで、認証基盤統合の事例の1つとして、認証・認可サービスの選定やアーキテクチャについて参考にしていただければと思います!

脚注
  1. Service Provider Interfaceの略。 独自のプロバイダーでロジックを拡張できる。 ↩︎

  2. Monthly Active Usersの略。月当たりのアクティブユーザー。 ↩︎

  3. Customer Identity and Access Managementの略。顧客のIDやアクセス管理をするサービス。 ↩︎

ユニフォームネクスト株式会社

Discussion