認証シリーズ(第1部):アプリケーションエンジニアリングの実践
March 8, 2024
はじめに
インターネットアプリケーションにおいて、特に企業の内部アプリケーションにおいて、データアクセスとユーザーのプライバシーを保護するために、ID認証は重要な役割を果たします。このシリーズの記事では、さまざまな視点からID認証について探求し、特に本記事ではアプリケーションエンジニアリングにおけるID認証の実践に焦点を当てます。
さまざまなアプリケーションにおいて、ID認証は一般的に以下の2つの技術を使用します:
-
Cookie & Session: この伝統的な認証メカニズムは、主にブラウザ内で使用されるウェブアプリケーションで広く利用されています。Cookieとセッションを使用してユーザーの身元を確認し、セッション状態を維持します。
-
Bearer Token: これはより現代的な認証メカニズムで、ブラウザのCookieに依存せず、代わりにHTTPプロトコルを使用して認証を行います。APIシナリオに特に適しており、モバイルアプリケーションでも使用できます。
どの方法を選択するにせよ、開発者は自社の製品に適した認証アプローチを選択し、データのセキュリティ、ユーザーのプライバシー、そしてシームレスなユーザー体験を確保する必要があります。
伝統的なウェブアプリケーション
以前は、Java JSPを使用して直接ウェブアプリケーションを構築し、クライアントのブラウザに保存されたCookie内のセッションIDであるJSESSIONIDを使用してユーザーを識別していました。
しかし、このアプローチにはいくつかの問題がありました。Cookieはブラウザによってクライアントデバイス上で管理および保存されるため、悪意のある攻撃者が保存されたセッションIDを盗み、ユーザーになりすますことができ、セキュリティリスクが生じます。また、開発者はCookieとセッションに対して合理的な有効期限とセキュリティ要件を設定するのに苦労することがありました。
これらのアプリケーションを開発する際、開発者は各システムに対して独立した認証を個別に実装する必要があり、異なるIDシステムを使用していました。これにより、繰り返し作業が必要でした。このような場合、シングルサインオン(SSO)を使用することで、統一された認証システムを利用し、各ウェブアプリケーションで最小限の統合作業を行うだけで認証機能を実現できます。
近年、フロントエンドとバックエンドの技術が急速に進歩し、開発者はより現代的な技術スタックに移行し始め、古い技術で動作するアプリケーションはレガシープラットフォームとして残されています。しかし、新しいIDセキュリティ要件が発生しても、古いコードを変更できない場合があります。そのような場合、リバースプロキシとして動作するミドルウェアを使用して認証を行う代替アプローチがあります。クライアントがアプリケーションに到達する前に、ミドルウェアはユーザーを外部の認証インターフェースにリダイレクトし、ユーザーがログインします。その後、ミドルウェアはユーザーの身元情報を取得し、リクエストに添付して古いアプリケーションに渡します。これにより、開発者は既存のコードを変更せずに古いアプリケーションに新しい認証メカニズムを追加できます。
ウェブアプリケーションの進化:フロントエンドとバックエンドの分離
VueやReactなどの新しいフロントエンド技術の出現により、ウェブのインタラクションは革新されました。以前は、ユーザーはウェブページ上でフォームを記入して送信し、HTMLフォームとボタンを使用してバックエンドとやり取りしていましたが、これはスムーズなユーザー体験を提供しませんでした。現在、ページ上のインタラクションはリアルタイムで行われ、開発者はJavaScriptスクリプトを使用してバックエンドAPIとやり取りし、より一貫性のある連続的な体験を提供します。ユーザーのインタラクションは、直接のHTTPリクエストからさまざまなAPIの呼び出しに移行しました。
ウェブページ指向のアプリケーションとAPI指向のアプリケーションでは、ID認証メカニズムにいくつかの違いがあります。古いCookieはまだ使用できますが、現代のフロントエンド技術には適していません。新しい技術により、開発者はより表現力のあるコードを使用して、フロントエンドでユーザーアカウントを切り替えるなどの操作を行うことができます。しかし、これをフロントエンドで直接Cookieを使用して実装することは困難です(セキュリティ上の理由から、ユーザーIDに関連するCookieはしばしばhttpOnlyとして設定され、JavaScriptスクリプトが読み取ったり操作したりできないようにされています)。
通常、現代のフロントエンドアプリケーションはユーザーセッションを自身で管理します。ユーザーがログインに成功すると、フロントエンドはバックエンドによって生成されたトークンを管理し、API呼び出し時にリクエストヘッダーに追加して、バックエンドがユーザーの身元を識別できるようにします。APIはトークンを使用してユーザー情報を識別します。JSON Web Tokens(JWT)を使用してトークンメカニズムを手動で実装するなど、さまざまな技術的手段があります。JWTのペイロードにはユーザーIDなどの識別情報が保存され、署名されてバックエンドがトークンを検証し、ユーザーの身元情報を取得できるようになります。
しかし、JWTにはいくつかの欠点もあります:
-
JWTの有効期限は固定されており、署名が完了すると変更できません。通常、バックエンドに保存されず、署名検証のみが行われるため、トークンを無効にすることができず、トークンが盗まれるリスクがあります。
-
ペイロードデータは平文で保存され、クライアントによって解析されるため、機密情報の保存には適していません。
幸い、これらの欠点を解決する新しいJWT仕様が登場しています。JWTのペイロードには、JWTの一意の識別子を保存する「jti」フィールドを含めることができ、バックエンドのキャッシュに保存してJWTのライフサイクルを制御できます。また、JSON Web Encryption(JWE)仕様では、非対称暗号化と対称暗号化の利点を組み合わせた暗号化JWT拡張が定義されており、ペイロードが暗号文形式で送信されるため、漏洩を防ぐことができます。
さらに、JWTベースの他の技術もあり、より成熟したソリューションを提供しています。例えば、OpenID Connectがあります。OpenID ConnectはJWTに依存しませんが、一緒に使用することができます。OpenID Connectはアクセストークンとリフレッシュトークンのメカニズムを標準化し、開発者が短期トークンを使用してトークン盗難のリスクを軽減できるようにします。OpenID Connectのエコシステムも繁栄しており、多くのサーバーとクライアントの実装が利用可能で、開発者がOpenID Connectプロトコルに基づいたID認証システムを構築するのに役立ちます。また、KeycloakなどのオープンソースのID認証ソリューションも、開発者が安全なID認証サービスを実装するのに役立ちます。
Next.jsなどの新しいフロントエンド技術の実践では、サーバーサイドレンダリング技術がフロントエンド領域に導入されつつあります。これは、Reactとバックエンドプログラムを組み合わせてユーザー体験をさらに向上させる、古いウェブ開発パラダイムの新しい進化です。NextAuthなどのライブラリも登場し、開発者がこのメカニズムを使用してID認証を実装するのを支援し、認証プロセスをより開発者フレンドリーにしています。
APIゲートウェイとID認証
モバイルアプリケーションがデータとどのようにやり取りするかを考えてみましょう。APIも使用していますか?モバイルアプリケーションでは、ブラウザのようなCookieメカニズムがないため、主にHTTPリクエストヘッダーを介して情報を渡すためにトークンを使用します。
APIサービスはどうでしょうか?成功したアプリケーションのバックエンドは通常、多くの複雑なAPIシステムで構成されており、統一されたID認証メカニズムが必要です。そうでなければ、開発者は各サービスに対して同じ認証メカニズムを実装する必要があり、煩雑です。
APIゲートウェイは、この問題を解決するのに役立ちます。Cookieやトークンに似た認証と解析タスクを処理し、解析された身元情報を直接バックエンドサービスに渡すことで、作業の重複を減らします。Apache APISIXとAPI7 Enterpriseも、OpenID Connect認証機能をすぐに使用できるようにサポートしており、ユーザーが直接ID認証サービスを統合するのを支援します。さらに、APIゲートウェイはスクリプトを使用して任意の認証メカニズムを実装できるため、カスタムのID認証メカニズムであっても、APIゲートウェイに統合してアプリケーション開発を簡素化できます。
まとめ
ユーザーインタラクション方法の発展が、ID認証の進歩を推進しています。API中心のアプローチが主流のトレンドになりつつあり、APIはマイクロサービスアーキテクチャによって提供される可能性があるため、冗長な開発を減らすために統一されたID認証メカニズムが必要です。したがって、OpenID ConnectやJWTなどのより現代的なメカニズムを選択し、APIゲートウェイを使用することで、API開発に追加の機能を提供できます。