JWT ステートレス認証 (こちらから入手可能) を設定した後、主要なコンポーネントとその相互作用を特定することで Spring Security の抽象化の下で何が起こるかを理解したいと思いました。この探索をより魅力的にするために、標準の HTTP ライブラリを使用して最小限のバージョンを Go に再実装しました。 3 つのコア フロー (登録、トークン生成、保護されたリソースへのアクセス) を分解し、Go で再構築することで、Spring Security の認証パターンをより単純なコンポーネントにマッピングすることに着手しました。
この投稿では、認可ではなく、認証フロー、つまりシステムがユーザー ID を検証する方法に特に焦点を当てています。 Spring Security のアーキテクチャのさまざまなコンポーネントを介してリクエストを追跡するシーケンス図を使用してフローを調べます。
システムは 3 つのエンドポイントを提供します:
次のセクションでは、各フローに含まれるコア コンポーネントについて、それぞれのシーケンス図を使用して説明します。
ユーザー名とパスワードを含む登録リクエストは、Spring Security フィルター チェーン を通過します。ここでは、登録エンドポイントが SecurityConfiguration で認証を必要としないように構成されているため、最小限の処理が発生します。次に、リクエストは Spring の DispatcherServlet を通過し、URL パターンに基づいて UserController の適切なメソッドにルーティングされます。リクエストは UserController の登録エンドポイントに到達し、ユーザー情報が ハッシュ化された パスワードとともに保存されます。
ユーザー名とパスワードを含むログイン要求は Spring Security フィルター チェーン を通過します。このエンドポイントは SecurityConfiguration で認証を必要としないように構成されているため、最小限の処理が発生します。リクエストは Spring の DispatcherServlet を介して UserController のログイン エンドポイントに移動し、AuthenticationManager に委任されます。 ApplicationConfiguration で定義された構成済み Bean を使用して、AuthenticationManager は提供された資格情報を保存されている資格情報と照合して検証します。認証が成功すると、UserController は JwtService を使用して、ユーザーの情報と作成時間などのメタデータを含む JWT トークンを生成します。これは、後続の認証されたリクエストのためにクライアントに返されます。
Authorization ヘッダーに JWT トークンを含むリクエストが到着すると、JwtService を使用してトークンを処理する JwtAuthenticationFilter (カスタム定義された OncePerRequestFilter) を通過します。有効な場合、フィルターは ApplicationConfiguration で構成された UserDetailsService を介してユーザーを取得し、SecurityContextHolder で認証を設定します。トークンが欠落しているか無効な場合、フィルターは認証を設定せずにリクエストを続行することを許可します。
チェーンの後半で、AuthorizationFilter は、リクエストが SecurityContextHolder を介して適切に認証されているかどうかをチェックします。認証の欠落を検出すると、AccessDeniedException をスローします。この例外は ExceptionTranslationFilter によってキャッチされ、ユーザーが匿名かどうかをチェックし、SecurityConfiguration で構成された JwtAuthenticationEntryPoint に委任して 401 Unauthorized 応答を返します。
すべてのフィルターが通過すると、リクエストは Spring の DispatcherServlet に到達し、UserController の getAuthenticatedUser エンドポイントにルーティングされます。このエンドポイントは、フィルター チェーン プロセス中に設定された SecurityContextHolder から認証されたユーザー情報を取得します。
注: Spring Security は、フィルターと特殊なコンポーネントの豊富なエコシステムを採用して、さまざまなセキュリティ上の懸念事項に対処します。核となる認証フローを理解するために、JWT トークンの検証とユーザー認証の主要なプレーヤーだけに焦点を当てました。
Go 実装は、主要な Spring Security コンポーネントにマップする簡素化されたアーキテクチャを通じて同様の機能を提供します。
フィルターチェーン
ディスパッチャー
認証コンテキスト
JwtFilter
認証フィルター
JwtService
どちらの実装にも、主要な認証シナリオを検証する統合テスト (auth_test.go と AuthTest.java) が含まれています。
登録の流れ
ログインの流れ
保護されたリソース アクセス
Java 実装には、Spring Security のフィルター チェーンを介した各テスト シナリオのフローを説明する詳細なコメントが含まれています。これらの同じフローは、同等のコンポーネントを使用して Go 実装で複製されます。
Spring Security の JWT 認証をフローとテスト ケースに分割して調べました。次に、これらのパターンを Go コンポーネントにマッピングしました。統合テストでは、リクエストが Spring Security のフィルター チェーンとコンポーネントをどのように流れるかを示しました。これらのパターンの単純なバージョンを構築することで、Spring Security の設計を理解することができました。テストでは、両方の実装が同じ方法で認証を処理することが証明されました。分析、テスト、再構築を通じて、Spring Security の認証がどのように機能するかをより深く理解できました。
以上がJWT 認証を理解する: Spring Security のアーキテクチャと Go 実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。