カテゴリ: Spring 更新日: 2025/11/15

【Springセキュリティ】権限(ROLE_USER, ROLE_ADMIN)で制御する基本

【Springセキュリティ】権限(ROLE_USER, ROLE_ADMIN)で制御する基本
【Springセキュリティ】権限(ROLE_USER, ROLE_ADMIN)で制御する基本

新人と先輩の会話形式で理解しよう

新人

「先輩、Spring SecurityでROLE_USERとかROLE_ADMINってよく見かけるんですが、あれって何なんですか?」

先輩

「それは『権限(ロール)』のことだよ。アクセスできるページや操作を制限するために使うんだ。」

新人

「つまり、ログインするだけじゃなくて、その人がどの操作をしていいかも決められるってことですか?」

先輩

「そういうこと!今回は、Spring Security 権限の基本である ROLE_USER と ROLE_ADMIN の違いと使い方を学んでいこうか。」

1. 権限(ROLE_USER, ROLE_ADMIN)とは?

1. 権限(ROLE_USER, ROLE_ADMIN)とは?
1. 権限(ROLE_USER, ROLE_ADMIN)とは?

Spring Security 権限(ロール)とは、ログインしたユーザーに対して「どこまで操作できるか」を決める仕組みです。たとえば、一般ユーザーには閲覧だけ許可し、管理者には編集や削除を許可するなど、操作の範囲を制限するのが権限の役割です。

よく使われる権限には、以下のようなものがあります:

  • ROLE_USER:一般ユーザー向けの権限
  • ROLE_ADMIN:管理者用の権限。通常はより多くの操作が可能

Spring Securityでは、これらの権限をユーザーに割り当てておくことで、ページや機能ごとにアクセスをコントロールできます。

たとえば、以下のような制御が可能です。

  • /user → ROLE_USER と ROLE_ADMIN がアクセス可能
  • /admin → ROLE_ADMIN のみアクセス可能

このように、Spring Securityの権限を使えば、誰がどのページを見られるか、操作できるかを簡単に管理できます。

2. Spring Securityにおけるロールの考え方とアクセス制御の必要性

2. Spring Securityにおけるロールの考え方とアクセス制御の必要性
2. Spring Securityにおけるロールの考え方とアクセス制御の必要性

Spring Securityでは、ロール(ROLE_USER、ROLE_ADMINなど)は文字列としてユーザーに紐づけられます。ログイン時に認証情報と一緒にこのロール情報もシステムに渡され、アクセス制御に使われる仕組みになっています。

アクセス制御をしないと、誰でも管理者画面にアクセスできてしまう危険があります。たとえば、ユーザーの一覧やデータ削除といった重要な操作が誰にでも許されてしまうと、情報漏洩や改ざんのリスクが高まります。

そこで、Spring SecurityのauthorizeHttpRequestsメソッドを使うことで、URLごとにアクセスを許可するロールを設定できます。

以下は、ROLE_ADMINのみが/admin以下にアクセスできるようにする例です。


.authorizeHttpRequests(auth -> auth
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
    .anyRequest().authenticated()
)

hasRole("ADMIN")はROLE_ADMINだけを許可し、hasAnyRole("USER", "ADMIN")は両方のロールを許可する指定です。

このように、ROLE_USER と ROLE_ADMIN を使い分けることで、アプリケーションのセキュリティを強化できます。

ちなみに、Spring Securityではロール名の前に「ROLE_」という接頭辞が自動的に付与されます。そのため、コード上では「hasRole("ADMIN")」と書けば、実際には「ROLE_ADMIN」として扱われます。

3. Spring Securityの依存関係の追加方法(pleiades上での操作手順)

3. Spring Securityの依存関係の追加方法(pleiades上での操作手順)
3. Spring Securityの依存関係の追加方法(pleiades上での操作手順)

Spring Securityを使って「ROLE_USER 設定」や「URLごとのアクセス制限」を行うには、まずSpring Securityのライブラリをプロジェクトに追加する必要があります。pleiades環境では、Gradleの build.gradle を直接編集するのではなく、GUIから依存関係を追加する方法が便利です。

以下はpleiades上での操作手順です:

// 【手順】Spring Securityの依存関係をpleiadesから追加する方法
1. プロジェクトを右クリック →「プロパティ」を開く
2. 左側のメニューから「Gradle」→「Dependencies」を選択
3. 画面右側の「追加」ボタンをクリック
4. 「Group Id」には「org.springframework.boot」と入力
5. 「Artifact Id」には「spring-boot-starter-security」と入力
6. バージョンは空欄でOK(Spring Bootに合わせて自動で選ばれる)
7. 入力後、「OK」→「適用」→「OK」で反映
8. 自動でGradleの同期(同期に失敗した場合はプロジェクトを右クリック→Gradle→Refresh Gradle Project)

補足として、ネットワーク環境によっては依存関係の取得に時間がかかることがあります。反応がないように見えても、数分待ってみるのがポイントです。

4. ユーザーに権限(ロール)を割り当てる方法

4. ユーザーに権限(ロール)を割り当てる方法
4. ユーザーに権限(ロール)を割り当てる方法

Spring Security 権限設定では、ログインユーザーに対して ROLE_USERROLE_ADMIN などのロールを割り当てる必要があります。これは認証処理の中で行います。ここでは簡単なメモリ内ユーザー(インメモリユーザー)を使って設定してみましょう。


// SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests(auth -> auth
        .requestMatchers("/admin/**").hasRole("ADMIN") // ROLE_ADMINのみ許可
        .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") // USERとADMINを許可
        .anyRequest().authenticated()
      )
      .formLogin(); // ログインフォームを有効化
    return http.build();
  }

  @Bean
  public UserDetailsService userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
      .username("user")
      .password("userpass")
      .roles("USER") // ROLE_USERが付与される
      .build();

    UserDetails admin = User.withDefaultPasswordEncoder()
      .username("admin")
      .password("adminpass")
      .roles("ADMIN") // ROLE_ADMINが付与される
      .build();

    return new InMemoryUserDetailsManager(user, admin);
  }
}

roles("USER")と記述するだけで、内部的には「ROLE_USER」として扱われます。この命名規則を覚えておくと混乱しません。

注意点:withDefaultPasswordEncoder()はテスト用です。本番では必ずパスワードエンコーダーを別で定義してください。

5. コントローラで権限によって表示を制限する方法(@PreAuthorizeなし)

5. コントローラで権限によって表示を制限する方法(@PreAuthorizeなし)
5. コントローラで権限によって表示を制限する方法(@PreAuthorizeなし)

今回は@PreAuthorizeなどのアノテーションを使わず、HttpSecurityの設定だけでURLごとのアクセス制限を実現します。これはauthorizeHttpRequests()の中でルールを記述することで実現できます。


// 再掲:SecurityConfigのauthorize設定
http
  .authorizeHttpRequests(auth -> auth
    .requestMatchers("/admin/**").hasRole("ADMIN") // 管理者のみ
    .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") // 一般ユーザーまたは管理者
    .anyRequest().authenticated()
  )

このようにURLのパターンごとにアクセス権限を設定することで、管理者だけが管理画面にアクセスできるように制限できます。

コントローラ側は特別なことをする必要はありません。たとえば以下のような構成にします:


// UserController.java
@Controller
public class UserController {

  @GetMapping("/user/home")
  public String userHome() {
    return "user-home"; // user-home.html などのテンプレートを返す
  }

  @GetMapping("/admin/home")
  public String adminHome() {
    return "admin-home"; // admin-home.html などのテンプレートを返す
  }
}

ポイント:コントローラ側ではアクセス制限のロジックを一切書かず、セキュリティ設定ファイルだけで制御する構成になっています。これにより、ロジックとセキュリティを分離でき、保守性が高まります。

注意点:URLパターンとロール設定の対応が正しくないと、予期せずアクセスできてしまう可能性があります。requestMatchers()の設定ミスには注意しましょう。

6. 複数の権限を使ったアクセス制御の実例(ROLE_USERとROLE_ADMINでアクセス制限を分ける)

6. 複数の権限を使ったアクセス制御の実例(ROLE_USERとROLE_ADMINでアクセス制限を分ける)
6. 複数の権限を使ったアクセス制御の実例(ROLE_USERとROLE_ADMINでアクセス制限を分ける)

ここでは「ROLE_USER」と「ROLE_ADMIN」を使って、ページごとにアクセスできるユーザーを分ける実例を紹介します。たとえば、「/user/home」は一般ユーザーと管理者が両方アクセスできる一方で、「/admin/home」は管理者だけがアクセスできるように制御します。


// SecurityConfig.java の設定例(再確認)
http
  .authorizeHttpRequests(auth -> auth
    .requestMatchers("/admin/**").hasRole("ADMIN") // 管理者のみアクセス可
    .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") // 両方アクセス可
    .anyRequest().authenticated()
  )
  .formLogin();

この設定では、/user/homeには「ROLE_USER」と「ROLE_ADMIN」のどちらを持っていてもアクセス可能ですが、/admin/homeは「ROLE_ADMIN」だけがアクセスできます。

このようにすることで、機能ごとに細かく制御することができ、セキュリティを高めることができます。

7. 権限エラー(403 Forbidden)発生時の画面表示と対処法

7. 権限エラー(403 Forbidden)発生時の画面表示と対処法
7. 権限エラー(403 Forbidden)発生時の画面表示と対処法

Spring Securityでは、ユーザーがアクセス権限のないページへアクセスしようとすると、403 Forbiddenというエラー画面が表示されます。

たとえば、一般ユーザーが「/admin/home」にアクセスすると、ブラウザ上には以下のようなメッセージが表示されることがあります:

HTTP Status 403 – Forbidden
The server understood the request but refuses to authorize it.

これはSpring Securityが正常に機能している証拠ですが、初心者ユーザーにとってはわかりづらい表示でもあります。

そこで、独自の403エラーページを用意することで、より分かりやすいメッセージを表示することができます。以下のようにテンプレートファイルを配置しましょう。


// src/main/resources/templates/error/403.html
<html>
<head><title>アクセス拒否</title></head>
<body>
  <h2>403 - アクセスが拒否されました</h2>
  <p>このページにアクセスする権限がありません。ログイン中のアカウントに管理者権限があるか確認してください。</p>
</body>
</html>

さらに、403エラー専用のハンドラを設定すれば、テンプレートと連動して表示を制御できます。


// SecurityConfig にアクセス拒否時の設定を追加
http
  .exceptionHandling(exception -> exception
    .accessDeniedPage("/error/403") // アクセス拒否時は /error/403 にリダイレクト
  );

これにより、「Spring Security 403 エラー」が発生した場合も、ユーザーに優しい表示で案内することができます。

8. 確認手順:ログイン後に権限によってアクセスできるページを検証する方法

8. 確認手順:ログイン後に権限によってアクセスできるページを検証する方法
8. 確認手順:ログイン後に権限によってアクセスできるページを検証する方法

最後に、「ROLE_ADMIN ログイン後の挙動」や「権限ごとのページ制御」が正しく動作しているかどうかを確認するための手順を紹介します。以下のようにユーザーと管理者の両方で動作確認を行いましょう。

// 【確認手順】ROLE_USER の場合
1. http://localhost:8080/login にアクセス
2. ユーザー名「user」、パスワード「userpass」でログイン
3. /user/home にアクセス → 成功(表示される)
4. /admin/home にアクセス → 403 Forbidden エラー画面が表示される(アクセス不可)

// 【確認手順】ROLE_ADMIN の場合
1. http://localhost:8080/login にアクセス
2. ユーザー名「admin」、パスワード「adminpass」でログイン
3. /user/home にアクセス → 成功(表示される)
4. /admin/home にアクセス → 成功(表示される)

注意点:ログイン中のユーザー情報はセッションに保持されているため、ユーザーを切り替えるときは一度ログアウトしてから再ログインするようにしましょう。

また、ログイン後の画面遷移先を指定したい場合は、.formLogin().defaultSuccessUrl("/user/home")などで制御できます。


// SecurityConfig のログイン設定に遷移先を指定
.formLogin(form -> form
  .defaultSuccessUrl("/user/home", true) // ログイン成功後に自動遷移
)

このようにして、ユーザー体験を向上させながら、権限ごとの動作確認をしっかり行うことができます。

コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

関連記事:
カテゴリの一覧へ
新着記事
オブジェクト指向とは?初心者向けにやさしく解説【Java入門】
Java の複数の引数を扱う方法を完全ガイド!カンマで区切る基本を初心者向けに解説
Java の void メソッドとは?戻り値がない場合の使い方を初心者向けに徹底解説
Javaのメソッドのメリットを完全解説!処理の整理と再利用で初心者でも読みやすいコードに
人気記事
No.1
Java&Spring記事人気No1
SQLのINSERT文を完全ガイド!初心者でもわかるデータの追加方法
No.2
Java&Spring記事人気No2
SQLのサブクエリを完全ガイド!入れ子クエリの使い方を初心者向け解説
No.3
Java&Spring記事人気No3
HTMLのセレクトボックス(プルダウン)の使い方を完全ガイド!selectとoptionの基本を覚えよう
No.4
Java&Spring記事人気No4
Modelとは?メソッド引数のModelの使い方を初心者向けに解説!