Spring Securityは、Javaアプリケーションに認証・認可機能を提供する、業界標準のセキュリティフレームワークです。本記事では、Spring Securityの基本概念を理解し、Spring Bootプロジェクトに最小構成でセキュリティを導入する方法を解説します。
実行環境と前提条件
本記事の内容を実践するにあたり、以下の環境を前提としています。
| 項目 | バージョン・要件 |
|---|---|
| Java | 17以上 |
| Spring Boot | 3.4.x |
| Spring Security | 6.4.x |
| ビルドツール | Maven または Gradle |
| IDE | VS Code または IntelliJ IDEA |
事前に以下の準備を完了してください。
- JDK 17以上のインストール
- Spring Bootプロジェクトの基本的な理解(REST APIの作成経験があると望ましい)
Spring Securityとは
Spring Securityは、Spring Frameworkのサブプロジェクトとして開発されている、認証と認可を中心としたセキュリティフレームワークです。Webアプリケーションやマイクロサービスに対して、包括的なセキュリティ機能を提供します。
Spring Securityの主な機能
Spring Securityが提供する主要な機能は以下のとおりです。
| 機能カテゴリ | 内容 |
|---|---|
| 認証(Authentication) | ユーザー名/パスワード、OAuth2、SAML、LDAPなど多様な認証方式をサポート |
| 認可(Authorization) | URLベース、メソッドベースのアクセス制御を実現 |
| 攻撃対策 | CSRF、セッション固定攻撃、クリックジャッキングなどへの防御機能を内蔵 |
| セキュリティヘッダー | X-Content-Type-Options、X-Frame-Optionsなどのレスポンスヘッダーを自動付与 |
| セッション管理 | セッションの有効期限、同時ログイン制限などを制御 |
認証(Authentication)と認可(Authorization)の違い
Spring Securityを理解するうえで最も重要なのは、「認証」と「認可」の概念を明確に区別することです。
認証(Authentication)とは
認証とは、「あなたは誰ですか?」という問いに答えるプロセスです。ユーザーが主張するアイデンティティを検証し、本人であることを確認します。
sequenceDiagram
participant User as ユーザー
participant App as アプリケーション
participant Auth as 認証システム
User->>App: ログイン要求(ID/パスワード)
App->>Auth: 資格情報を検証
Auth-->>App: 検証結果
alt 認証成功
App-->>User: 認証トークン発行
else 認証失敗
App-->>User: 401 Unauthorized
end認証の代表的な手段には以下があります。
- ユーザー名とパスワードによる認証
- OAuth 2.0 / OpenID Connect(Google、GitHubなどのソーシャルログイン)
- SAML 2.0(エンタープライズシングルサインオン)
- 証明書ベースの認証(X.509)
認可(Authorization)とは
認可とは、「あなたは何ができますか?」という問いに答えるプロセスです。認証済みのユーザーが、特定のリソースやアクションにアクセスする権限を持っているかを判定します。
flowchart LR
A[認証済みユーザー] --> B{認可チェック}
B -->|権限あり| C[リソースへアクセス]
B -->|権限なし| D[403 Forbidden]認可の実装パターンは主に以下の2種類があります。
| パターン | 説明 | 例 |
|---|---|---|
| ロールベース(RBAC) | ユーザーに割り当てられた役割に基づく | ADMIN、USER、GUESTなど |
| 権限ベース | 個別の権限(Permission)に基づく | READ_USERS、WRITE_ARTICLESなど |
認証と認可の関係
認証と認可は密接に関連していますが、独立した概念です。Spring Securityでは、まず認証を行い、その後に認可を行う順序で処理が進みます。
| 処理 | 失敗時のHTTPステータス | 意味 |
|---|---|---|
| 認証 | 401 Unauthorized | 本人確認ができない |
| 認可 | 403 Forbidden | 権限がない |
Spring SecurityのFilterChainアーキテクチャ
Spring Securityは、Servlet Filterの仕組みを活用してセキュリティ機能を実現しています。このアーキテクチャを理解することは、Spring Securityをカスタマイズする際に不可欠です。
Filterの基本構造
ServletコンテナはHTTPリクエストを処理する際、FilterChainを通じて複数のFilterを順番に実行します。
flowchart LR
A[HTTPリクエスト] --> B[Filter 1]
B --> C[Filter 2]
C --> D[Filter N]
D --> E[Servlet]
E --> F[HTTPレスポンス]DelegatingFilterProxy
Spring SecurityはDelegatingFilterProxyを使用して、ServletコンテナのFilterとSpringのApplicationContextを橋渡しします。これにより、Spring Beanとして定義されたFilterをServletコンテナで使用できます。
FilterChainProxy
FilterChainProxyは、Spring Securityの中核となる特別なFilterです。複数のSecurityFilterChainを管理し、リクエストURLに応じて適切なフィルターチェーンを選択します。
flowchart TB
A[HTTPリクエスト] --> B[DelegatingFilterProxy]
B --> C[FilterChainProxy]
C --> D{URLパターン判定}
D -->|/api/**| E[SecurityFilterChain 0]
D -->|/**| F[SecurityFilterChain N]
E --> G[認証Filter]
G --> H[認可Filter]
F --> I[別の設定のFilter群]SecurityFilterChain
SecurityFilterChainは、特定のリクエストパターンに対して適用されるセキュリティフィルターのリストを定義します。Spring Boot環境では、HttpSecurityを使用して設定します。
デフォルトで有効になる主要なフィルターは以下のとおりです。
| フィルター | 役割 |
|---|---|
| SecurityContextHolderFilter | セキュリティコンテキストのライフサイクル管理 |
| CsrfFilter | CSRF攻撃からの保護 |
| LogoutFilter | ログアウト処理 |
| UsernamePasswordAuthenticationFilter | フォームログイン認証 |
| BasicAuthenticationFilter | HTTP Basic認証 |
| AnonymousAuthenticationFilter | 匿名ユーザーの認証情報設定 |
| ExceptionTranslationFilter | セキュリティ例外のHTTPレスポンスへの変換 |
| AuthorizationFilter | アクセス権限のチェック |
Spring BootプロジェクトへのSpring Security導入
ここからは、実際にSpring BootプロジェクトにSpring Securityを導入する手順を解説します。
依存関係の追加
Spring Bootプロジェクトでは、spring-boot-starter-securityを追加するだけでSpring Securityが有効になります。
Mavenの場合、pom.xmlに以下を追加します。
|
|
Gradleの場合、build.gradleに以下を追加します。
|
|
デフォルトの動作確認
依存関係を追加してアプリケーションを起動すると、Spring Securityがデフォルト設定で有効になります。コンソールに以下のようなメッセージが出力されます。
|
|
この状態でhttp://localhost:8080にアクセスすると、Spring Securityが提供するデフォルトのログインページにリダイレクトされます。
デフォルトの認証情報は以下のとおりです。
| 項目 | 値 |
|---|---|
| ユーザー名 | user |
| パスワード | コンソールに出力された値 |
デフォルト設定の挙動
Spring Boot + Spring Securityのデフォルト設定では、以下の動作が自動的に有効になります。
- すべてのエンドポイントに対して認証を要求
- フォームベースのログイン/ログアウト機能を提供
- HTTP Basic認証をサポート
- CSRF保護を有効化
- セッション固定攻撃対策を有効化
- セキュリティ関連のHTTPヘッダーを自動付与
- デフォルトユーザー(user)を自動生成
SecurityFilterChainのカスタマイズ
デフォルト設定を変更するには、SecurityFilterChainをBeanとして定義します。
基本的なSecurityFilterChain設定
以下は、最小構成のカスタム設定例です。
|
|
設定項目の解説
上記の設定コードの各部分について説明します。
| 設定 | 説明 |
|---|---|
@EnableWebSecurity |
Spring Securityの設定を有効化するアノテーション |
authorizeHttpRequests() |
URLベースの認可ルールを定義 |
requestMatchers() |
特定のURLパターンに対するルールを設定 |
permitAll() |
認証なしでアクセスを許可 |
hasRole() |
指定したロールを持つユーザーのみアクセスを許可 |
authenticated() |
認証済みユーザーのみアクセスを許可 |
formLogin() |
フォームベースログインの設定 |
logout() |
ログアウト機能の設定 |
REST API向けの設定
REST APIを構築する場合、フォームログインの代わりにHTTP Basic認証やJWT認証を使用することが一般的です。以下は、REST API向けの最小設定例です。
|
|
この設定では以下の変更を行っています。
| 設定 | 理由 |
|---|---|
| CSRF無効化 | ステートレスなREST APIではCSRFトークンの管理が困難なため |
| セッション無効化 | REST APIはステートレスであるべきため |
| HTTP Basic認証 | シンプルな認証方式として採用 |
インメモリユーザーの設定
開発・テスト目的で、メモリ上にユーザー情報を定義することができます。
|
|
PasswordEncoderの重要性
Spring Security 5以降では、パスワードは必ずエンコード(ハッシュ化)して保存する必要があります。平文パスワードを使用すると、起動時にエラーが発生します。
推奨されるエンコーダーはBCryptPasswordEncoderです。BCryptは以下の特徴を持ちます。
- ソルト(Salt)を自動生成してレインボーテーブル攻撃を防止
- コストファクターによる計算量調整が可能
- 将来のハードウェア性能向上に対応可能
動作確認
設定が完了したら、以下の手順で動作を確認します。
アプリケーションの起動
|
|
認証なしでのアクセステスト
|
|
期待される結果は401 Unauthorizedです。
認証ありでのアクセステスト
|
|
期待される結果は200 OKまたは対応するレスポンスです。
デバッグとトラブルシューティング
Spring Securityの動作を詳細に確認するには、ログレベルを変更します。
application.propertiesに以下を追加します。
|
|
これにより、各フィルターの実行順序や認証・認可の判定結果がログに出力されます。
|
|
まとめ
本記事では、Spring Securityの基本概念と、Spring Bootプロジェクトへの導入方法を解説しました。
要点を整理すると以下のとおりです。
- 認証は「誰であるか」を確認し、認可は「何ができるか」を判定する
- Spring SecurityはSecurityFilterChainを通じてリクエストを処理する
- Spring Bootでは
spring-boot-starter-securityを追加するだけでセキュリティが有効化される - SecurityFilterChain Beanを定義することでカスタマイズが可能
- パスワードは必ずPasswordEncoderでエンコードする
次のステップとして、以下のトピックの学習を推奨します。
- UserDetailsServiceによるデータベース認証の実装
- JWT(JSON Web Token)を使用したステートレス認証
- OAuth 2.0 / OpenID Connectによるソーシャルログイン
- メソッドレベルセキュリティ(
@PreAuthorize、@Secured)