Spring Bootで認証と認可を徹底解説!初心者でもわかる基本概念
新人
「Spring Bootでユーザーのログイン機能を作りたいんですけど、認証と認可の違いがわかりません。」
先輩
「それは重要なポイントだね!認証はユーザーが誰なのか確認することで、認可はそのユーザーが何をできるかを決めることだよ。」
新人
「具体的にはどうやって実装するんですか?」
先輩
「じゃあ、認証と認可の基本から説明していくよ!」
1. 認証とは?
認証(Authentication)は、ユーザーが誰であるかを確認するプロセスです。例えば、ユーザーがログイン画面でユーザー名とパスワードを入力し、正しい情報であることを確認するのが認証です。Spring Bootでは、Spring Securityを使用して簡単に認証を実装できます。
開発環境としては、pleiadesを使用し、プロジェクト作成や依存関係の追加もpleiades内で行います。ビルドツールはGradleを使用します。
Spring Bootでの認証実装例
以下のコードは、簡単なログインフォームを提供する認証の実装例です。
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
上記のコードでは、inMemoryAuthenticationを使用してメモリ内で認証ユーザーを設定しています。formLogin()で簡単にログイン画面が表示されます。
2. 認可とは?
認可(Authorization)は、認証されたユーザーがどのリソースにアクセスできるかを決定するプロセスです。例えば、一般ユーザーは管理画面にアクセスできないように制御するのが認可です。
Spring Bootでは、HttpSecurityの設定を変更することで認可を実装します。
認可の実装例
次のコードでは、/adminパスにはADMINロールを持つユーザーだけがアクセスできるように設定しています。
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password("{noop}adminpass")
.roles("ADMIN")
.and()
.withUser("user")
.password("{noop}userpass")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
この設定により、/adminエンドポイントにアクセスできるのはADMINロールのユーザーのみで、/userにはUSERかADMINロールを持つユーザーがアクセスできます。
認証と認可の違い
認証は「あなたは誰ですか?」を確認するプロセスであり、認可は「あなたは何ができますか?」を決定するものです。この違いを理解することは、セキュアなアプリケーションを構築する上で非常に重要です。
例えば、銀行のATMでカードを挿入して暗証番号を入力するのが認証であり、その後に口座から引き出しや残高照会ができるかどうかを決めるのが認可です。
3. 認証の仕組みと実装方法
認証の仕組みは、ユーザーが自分の身元を証明するプロセスです。Spring Bootでは、Spring Securityを利用することで簡単に認証機能を実装できます。ここでは、pleiadesを使ったプロジェクト作成から、認証実装までの流れを解説します。
3.1 プロジェクト作成と依存関係の追加
まず、pleiadesでSpring Bootプロジェクトを作成します。以下の手順で行ってください。
- Pleiadesを起動し、「新規プロジェクトの作成」を選択。
- 「Spring Starter Project」を選び、
Gradleをビルドツールに指定。 - プロジェクト名とパッケージ名を入力し、WebとSpring Securityを依存関係に追加。
- 完了をクリックしてプロジェクトを作成。
3.2 認証のコード実装
次に、ユーザーがログインできるように認証の設定を行います。
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll();
}
}
この設定では、メモリ内にuserというユーザーを作成し、/loginでログイン画面を表示します。{noop}はパスワードのエンコーディングを無効にするための指定です。
4. 認可の仕組みと実装方法
認可は、認証後にユーザーがアクセスできるリソースを制御する仕組みです。ユーザーの役割に応じてアクセス制限を設けることが可能です。
4.1 認可設定の追加
以下のコードは、ADMINロールを持つユーザーのみが/adminパスにアクセスできるようにする例です。
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password("{noop}adminpass")
.roles("ADMIN")
.and()
.withUser("user")
.password("{noop}userpass")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
この設定により、/adminにアクセスできるのはADMINロールのユーザーのみです。/userはUSERまたはADMINがアクセス可能です。
5. 認証と認可の違いを実際のコードで比較
ここでは、認証と認可の違いを理解するために、2つの異なるコントローラを用意します。
5.1 ユーザー向けコントローラ
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@GetMapping("/user")
@ResponseBody
public String userPage() {
return "ユーザーページにアクセスしました。";
}
}
5.2 管理者向けコントローラ
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class AdminController {
@GetMapping("/admin")
@ResponseBody
public String adminPage() {
return "管理者ページにアクセスしました。";
}
}
実行結果
/user にアクセス → ユーザーページにアクセスしました。
/admin にアクセス(ADMIN以外のユーザー) → アクセスが拒否されました。
/admin にアクセス(ADMINユーザー) → 管理者ページにアクセスしました。
上記のコードと実行結果を見ると、認証はユーザーが正しくログインしているかを確認するもので、認可はログイン後にどのページにアクセスできるかを制御するものだとわかります。
6. 認証と認可を組み合わせた実際のアプリケーション例(pleiadesでの起動方法)
ここでは、認証と認可を組み合わせた実際のアプリケーションを作成し、pleiadesでの実行方法について説明します。
6.1 プロジェクト構成
以下のような構成でプロジェクトを作成してください。
src/main/java/com/example/demo/
├─ config/SecurityConfig.java
├─ controller/UserController.java
├─ controller/AdminController.java
└─ DemoApplication.java
src/main/resources/
└─ application.properties
6.2 pleiadesでの起動方法
- pleiadesを起動し、作成済みのプロジェクトを開きます。
- パッケージエクスプローラーで
DemoApplication.javaを右クリック。 - 「実行」→「Spring Boot アプリケーション」を選択して起動。
- コンソールに「Started DemoApplication」が表示されれば正常に起動しています。
6.3 コントローラコード例
ユーザー用と管理者用のページを表示するために、以下のようにコントローラを作成します。
6.3.1 ユーザーコントローラ
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@GetMapping("/user")
@ResponseBody
public String userPage() {
return "ユーザーページにアクセスしました。";
}
}
6.3.2 管理者コントローラ
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class AdminController {
@GetMapping("/admin")
@ResponseBody
public String adminPage() {
return "管理者ページにアクセスしました。";
}
}
6.4 実行結果
/user にアクセス → ユーザーページにアクセスしました。
/admin にアクセス(ADMIN以外のユーザー) → アクセスが拒否されました。
/admin にアクセス(ADMINユーザー) → 管理者ページにアクセスしました。
7. よくあるエラーとトラブルシューティング
Spring Securityを使用する際、初心者がつまずきやすいエラーとその解決方法を紹介します。
7.1 エラー:ログイン画面が表示されない
原因: セキュリティ設定の不備やコントローラのマッピングミス。
解決方法: formLogin().loginPage("/login") の設定が正しいか確認し、/loginを処理するコントローラを作成してください。
@GetMapping("/login")
public String loginPage() {
return "login"; // resources/templates/login.htmlが必要
}
7.2 エラー:パスワードが無効
原因: パスワードのエンコーディング指定ミス。
解決方法: {noop}を忘れずに指定してください。
.withUser("user")
.password("{noop}password")
.roles("USER");
7.3 エラー:アクセスが拒否されました
原因: ロール設定の誤りやマッピングミス。
解決方法: hasRole("ADMIN") のスペルや権限付与を再確認してください。
8. 認証と認可を用いた開発での注意点と今後の学習のすすめ
認証と認可を実装する際は、以下の点に注意してください。
- パスワード管理: 本番環境では
BCryptPasswordEncoderを使用。 - セッション管理: 適切なセッションタイムアウト設定を。
- アクセス制御: 必要なページにのみ認可を設定。
8.1 次の学習ステップ
さらに理解を深めるため、以下を学習してください。
- Spring Securityの詳細設定: カスタムログインページやエラーハンドリング。
- OAuth2による外部認証: GoogleやGitHubとの連携。
- JWT認証: トークンベースの認証でAPIセキュリティを強化。
以上で、Spring Bootを使った認証と認可の基本から応用までの解説を終わります。学んだ知識を使って安全なアプリケーション開発を目指しましょう!