Spring Securityのデフォルトのアクセス制御の仕組みを完全解説!初心者でもわかるセキュリティの基本
新人
「Spring Securityを使うと自動でアクセス制御されるって聞いたんですが、本当ですか?」
先輩
「うん、それは本当だよ。Spring Securityはデフォルトでセキュリティが強く設定されていて、認証されていないリクエストは基本的にブロックされるんだ。」
新人
「へぇ…!それってどういう仕組みなんですか?」
先輩
「じゃあ、今回はSpring Securityのデフォルトのアクセス制御について、基本から解説していこうか!」
1. Spring Securityとは何か?(概要と目的)
Spring Security(スプリング セキュリティ)は、JavaのWebアプリケーションに認証や認可といったセキュリティ機能を簡単に追加できるフレームワークです。
たとえば、ログイン機能やアクセス制限、セッション管理、CSRF対策などを柔軟に構成できます。
Spring Bootと一緒に使うことで、設定ファイルを最小限にしつつ強力なアクセス制御を実現できる点が、Spring Securityの魅力のひとつです。
実はSpring Securityをプロジェクトに依存関係として追加しただけで、デフォルトで「全てのリクエストはログインしないとアクセスできない」ようにブロックされます。これは、セキュリティの初期設定として非常に強力です。
Spring Security アクセス制御の仕組みは、初心者にとっても理解しやすく、安全なアプリケーションを作る第一歩になります。
まずは、Spring Securityが提供するアクセス制御の土台である「認証」と「認可」について、順を追って学びましょう。
2. アクセス制御の基本概念(認証と認可の違い)
Spring Security 認証と認可の仕組みを理解するには、Authentication(認証)とAuthorization(認可)という2つの言葉の意味をきちんと区別することが重要です。
■ 認証(Authentication)とは?
認証とは、「このユーザーは誰なのか?」を確認するプロセスです。通常、ログイン画面でのIDとパスワードの入力が認証の処理にあたります。
Spring Securityでは、認証に成功すると、ユーザー情報がAuthenticationオブジェクトに保持され、セッションが作成されます。
■ 認可(Authorization)とは?
認可とは、「このユーザーにどの操作が許可されているのか?」を判定する処理です。
たとえば、「管理者だけがアクセスできるページ」や「ログインユーザーだけが使える機能」などを制御するのが認可です。
Spring Securityでは、デフォルトで以下のような強固なアクセス制御が適用されます。
- すべてのURLはログインしていないとアクセスできない
- CSRF対策(クロスサイトリクエストフォージェリ)も有効
- ログイン画面・ログアウト処理も自動で生成される
では実際に、Spring BootのプロジェクトにSpring Securityを追加してみましょう。Gradle環境での依存関係の追加は以下のとおりです。
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
上記を追加しただけで、アプリケーション全体がログイン必須状態になります。つまり、特別な設定をしていなくても、Spring Securityのアクセス制御がすでに機能しているのです。
試しに、コントローラで簡単な画面を返すコードを書いてみましょう。
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "index";
}
}
この状態でアプリケーションを起動してブラウザでアクセスすると、自動的にログイン画面が表示されます。これはSpring Securityが「まだ認証されていないユーザーのアクセスをブロック」しているからです。
このように、Spring Securityのセキュリティ仕組みは、初期状態でも十分に強力です。設定を追加しなくてもセキュアなアプリが作れるのは、初心者にとって大きなメリットです。
次回は、デフォルトで設定されているアクセス制御の動きや、ログイン・ログアウトの制御方法、SecurityFilterChainによる設定カスタマイズなど、さらに実践的な内容に進んでいきましょう。
3. デフォルトで適用されるアクセス制限(ログインが必要なURLの挙動)
Spring Security デフォルト設定では、明示的に設定しなくてもすべてのリクエストに対して認証が必要な状態になります。
たとえば、以下のような通常のコントローラを定義していた場合でも、ログインしていなければアクセスはブロックされます。
@Controller
public class SampleController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
このコードでは、/helloにアクセスした際に「hello.jsp」などの画面が表示されるはずです。
ところが、Spring Securityのデフォルトでは、ログインしていなければ自動的にログイン画面にリダイレクトされます。
このように、認証されていないリクエストはすべて認証ページに転送されるというのが、アクセス制御の基本の動きです。
これは「SecurityFilterChain」という仕組みによって実現されており、セキュリティフィルターがすべてのリクエストをチェックしているのです。
初心者がSpring Security アクセス制御の基本を理解する上で、「なぜ画面にアクセスできないのか」を明確にするには、このフィルターの存在を知っておくことが重要です。
4. WebSecurityConfigurerAdapterとSecurityFilterChainの基本
Spring Security デフォルト設定のままでも十分強力ですが、カスタマイズしたい場面もあります。
その際に重要になるのが、SecurityFilterChain(セキュリティフィルターチェーン)です。
以前のSpring SecurityではWebSecurityConfigurerAdapterを継承するスタイルが主流でしたが、現在のバージョンではこの方法は非推奨となっています。
代わりに使われるのがSecurityFilterChainです。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/css/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());
return http.build();
}
}
この設定では、/loginや/css/**のパスには誰でもアクセスできるようになり、それ以外はログインしないとアクセスできません。
このように、SecurityFilterChain 説明を通じて、自分のアプリケーションに適したアクセス制御を設定することができます。
初心者にとっては「フィルターチェーン」という言葉が少し難しく感じるかもしれませんが、実際にはリクエストの前にセキュリティのルールを確認してくれる番人のようなものです。
基本的に、SecurityFilterChainをBeanとして定義することで、細かなカスタマイズが可能になります。
5. ログイン・ログアウトの処理の流れ(デフォルト設定の動き)
Spring Security デフォルト設定では、ログインとログアウトの画面も自動で用意されています。
ログインページのURLは/login、ログアウトのURLは/logoutが初期値です。
これらの画面は、Spring Securityが内蔵するHTMLで表示され、特別なテンプレートを作らなくても使えます。
ログインに成功すると、認証情報がセッションに保存され、以降のアクセスが許可されます。
ログアウトの処理も非常に簡単で、/logoutにアクセスすることでセッションが無効化され、再びログイン画面へと戻されます。
以下はログインフォームの設定例です。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.formLogin(form -> form
.loginPage("/login") // 独自のログイン画面を使う場合
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
)
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
);
return http.build();
}
このように、ログイン・ログアウトの流れをカスタマイズすることも簡単です。
ログイン成功後のリダイレクト先や、ログアウト後の遷移先も自由に変更できます。
初心者にとって重要なのは、「なぜ自分の画面にアクセスできないのか?」と悩んだとき、まずSecurityFilterChainの設定を確認する習慣をつけることです。
これが理解できれば、Spring Security アクセス制御の基本をかなり把握できたことになります。
次回は、ユーザー認証の仕組みや、ユーザーデータの保存場所、カスタム認証の作り方など、より実践的な内容に進んでいきましょう。
6. アクセス制御でよくあるエラーと対処法(403 Forbiddenなど)
Spring Security 本番運用で初心者が最もつまずきやすいのが、403 Forbidden エラーです。
このエラーは、ユーザーがログイン済みであってもアクセス権限がないページにアクセスしようとした場合に表示されます。
たとえば以下のように、特定のロール(権限)を持つユーザーだけにアクセスを許可したい場合の設定です。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
この状態で「ADMINロール」を持っていないユーザーが/adminにアクセスすると、403 Forbiddenが返されます。
「ログインは成功しているのに画面が表示されない!」という初心者の悩みの多くは、この認可設定の不一致が原因です。
対処法としては、まずユーザーにどのロールが割り当てられているかを確認し、それに合ったアクセス制御ルールになっているかをチェックしましょう。
また、カスタムエラーページを設定することで、ユーザーに優しい表示に切り替えることもできます。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.exceptionHandling(e -> e
.accessDeniedPage("/access-denied")
);
return http.build();
}
この設定により、403エラー時は/access-deniedという画面にリダイレクトされるようになります。
このような対応をしておくことで、開発者自身のトラブルシュートがしやすくなるだけでなく、利用者にとっても親切な設計になります。
7. デフォルト設定のカスタマイズポイント(実務での応用例)
Spring Securityのデフォルト設定は非常に強力ですが、実務では要件に応じたカスタマイズが必要になります。
たとえば次のような応用例があります。
- 特定の画面はログインなしで公開
- 認証後はロールごとに異なる画面に遷移
- ログイン失敗時のエラーメッセージをカスタマイズ
- APIリクエストに対するCSRF無効化
以下のコードでは、ログイン後にユーザーのロールに応じて異なる画面へリダイレクトする処理を設定しています。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.formLogin(form -> form
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/login?error")
)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.logout(logout -> logout
.logoutSuccessUrl("/login?logout")
);
return http.build();
}
このように、Spring Security 本番運用においては、ルールを具体的に定めておくことがとても大切です。
たとえば、認証後の遷移先を設定しておかないと、ログイン後に意図しない画面に戻されることがあります。
また、ログイン画面やエラー画面を独自に用意することで、ユーザーにとっても分かりやすい画面構成になります。
実務では、見た目よりもまずセキュリティの要件を優先して設計することが推奨されます。
8. 本番環境におけるアクセス制御設計のポイント
最後に、Spring Security 本番運用において注意すべきアクセス制御の設計ポイントを整理しましょう。
■ 最小権限の原則を守る
すべてのユーザーに同じ権限を与えるのは危険です。ロールや権限は細かく分け、必要な機能だけを許可する設計にしましょう。
■ URLのパス設計に意味を持たせる
たとえば/admin/**は管理者、/user/**は一般ユーザーというように、パスに意味を持たせることで、アクセス制御の設定が明確になります。
■ ロール名の統一とドキュメント化
ROLE_ADMINやROLE_USERなど、ロールの名称は一貫して使用し、誰がどの権限を持つのかを文書化しておきましょう。
■ セキュリティ設定のコード管理
設定クラスは環境ごとに切り替えられるよう、プロファイルやプロパティファイルを使って分けておくと便利です。
■ エラー処理のログ出力
403 Forbidden エラーや401 Unauthorized エラーが発生した場合、ログに記録しておくことで、問題の特定が早くなります。
これらのポイントを意識することで、より安全で運用しやすいセキュリティ設計が実現できます。
初心者でも、これらの基本を押さえておけば、Spring Securityで安全なWebアプリケーションを構築することが可能です。
セキュリティは「一度作って終わり」ではなく、継続的に見直していくべき重要な分野です。
今後は、ユーザー認証情報の保存方法や、カスタム認証フィルターなど、より実践的な実装例についても学習を進めていきましょう。
まとめ
Spring Securityのデフォルトアクセス制御を振り返る
ここまで、Spring Securityのデフォルト設定を中心に、アクセス制御の仕組みや考え方を丁寧に確認してきました。 Spring Securityは、JavaやSpring Bootを使ったWebアプリケーション開発において、認証や認可といった セキュリティ対策を標準で提供してくれる非常に心強いフレームワークです。 特に初心者にとって重要なのは、「何も設定していなくても安全側に倒れている」という点です。 依存関係を追加した瞬間から、すべてのURLがログイン必須になるため、 意図せずセキュリティホールが生まれるリスクを大きく減らすことができます。
本記事では、認証と認可の違いをはじめ、SecurityFilterChainによるアクセス制御、 ログインやログアウトのデフォルトの動き、403 Forbiddenエラーが発生する理由など、 実務でも必ず直面するポイントを一つひとつ整理しました。 Spring Securityのアクセス制御は一見すると難しそうに感じますが、 基本となる考え方は「リクエストが来たら、まず認証状態と権限を確認する」というシンプルな流れです。 この流れを理解できれば、設定クラスのコードも自然と読み解けるようになります。
デフォルト設定を理解することの重要性
Spring Securityの設定を学ぶうえで、いきなり細かいカスタマイズから入ってしまうと、 「なぜこの設定が必要なのか」が分からなくなりがちです。 だからこそ、まずはデフォルトのアクセス制御がどのように動いているのかを理解することが大切です。 デフォルトでは、未認証ユーザーはログイン画面へリダイレクトされ、 認証済みであっても権限が足りなければ403エラーが返されます。 この挙動を知っていれば、画面が表示されないときにも冷静に原因を切り分けられるようになります。
また、SecurityFilterChainを使った設定は、URLごとのアクセス制御を明確に記述できる点が特徴です。 「どのパスは誰でもアクセス可能か」「どのパスはログインが必要か」 「管理者だけが使える機能はどこか」といったルールをコードとして表現できるため、 後から見返したときにも意図が分かりやすくなります。 これはチーム開発や長期運用において、非常に大きなメリットになります。
サンプルプログラムで確認するアクセス制御の基本
以下は、本記事で学んだ内容を踏まえた、基本的なアクセス制御設定の一例です。 デフォルトの考え方を活かしつつ、公開ページと認証必須ページを分けています。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
)
.logout(logout -> logout
.logoutSuccessUrl("/login?logout")
);
return http.build();
}
}
このように設定しておくことで、公開ページと保護されたページが明確になり、 Spring Securityのアクセス制御の流れを実感しやすくなります。 実務では、ここにロールごとの制御やエラーページの設定を追加していくことで、 より柔軟で安全な設計が可能になります。
生徒
「Spring Securityって、最初は難しそうだと思っていましたけど、 デフォルトのアクセス制御を理解すると、意外と筋が通っているんですね。」
先生
「そうだね。まずはデフォルトの動きを知ることが一番大切なんだ。 いきなり細かい設定を覚えるよりも、認証と認可の流れを頭に入れておくと応用がきくよ。」
生徒
「ログインしていないと画面が見られない理由や、 403 Forbiddenが出る理由も、SecurityFilterChainの役割を知ったら納得できました。」
先生
「それが理解できていれば十分なスタートだね。 あとは実際にコードを書きながら、どのURLを守るべきかを考えてみるといい。」
生徒
「まずはデフォルト設定をベースにして、 少しずつカスタマイズしていくようにしてみます!」
先生
「その姿勢が大事だよ。 Spring Securityのアクセス制御を理解できれば、 安全なWebアプリケーションを作る力がしっかり身についていくはずだ。」