Q&A
前提
Spring Securityを実装し、URL:http://localhost:8080/user/list への直リンクを禁止にしました。
直接上記のリンクを入力すると、下記のようなページに遷移するため、Spring Securityは正しく実装できていると思います。
しかし、エラー処理が発生した際に共通のエラー画面に遷移できるよう「error.html」を作成していましたが、その画面には遷移することができませんでした。どうすれば自ら作成した共通のエラー画面に遷移させることができるのでしょうか。
後悔しないためのSpring Boot 入門書:Spring 解体新書(第2版): Spring Bootが丸分かり Spring解体新書の
「11章 Spring セキュリティ」を実装中に問題が発生しました。
この本に書かれている内容(11章)は現在では非推奨になっており、本の内容とは違う書き方をしなければなりませんでした。
実現したいこと
ここに実現したいことを箇条書きで書いてください。
- 直リンク禁止ページのURLを入力した際に、共通のエラー画面を表示させたい
発生している問題
Spring Securityを実装し、URL:http://localhost:8080/user/list への直リンクを禁止にしました。
直接上記のリンクを入力すると、下記のようなページに遷移するため、Spring Securityは正しく実装できていると思います。
しかし、エラー処理が発生した際に共通のエラー画面に遷移できるよう「error.html」を作成していましたが、その画面には遷移することができませんでした。
ファイルツリー
(1枚目)
(2枚目)
該当のソースコード
インストールした内容
pom.xml
1 <!-- SpringSecurity --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-security</artifactId> 5 </dependency> 6 <!-- Thymeleaf拡張ライブラリ(セキュリティ) --> 7 <dependency> 8 <groupId>org.thymeleaf.extras</groupId> 9 <artifactId>thymeleaf-extras-springsecurity5</artifactId> 10 </dependency>
error.htmlに共通のエラー内容を表示させるためのファイル(GlobalControllAdvice.java)
GlobalControllAdvice.java
1 2package com.example.aspect; 3 4import org.springframework.dao.DataAccessException; 5import org.springframework.http.HttpStatus; 6import org.springframework.ui.Model; 7import org.springframework.web.bind.annotation.ControllerAdvice; 8import org.springframework.web.bind.annotation.ExceptionHandler; 9 10@ControllerAdvice 11public class GlobalControllAdvice { 12 13 /* データベース関連の例外処理 */ 14 @ExceptionHandler(DataAccessException.class) 15 public String dataAccessExceptionHandler(DataAccessException e, Model model) { 16 17 // 空文字をセット 18 model.addAttribute("error", ""); 19 20 // メッセージをModelに登録 21 model.addAttribute("message", "DataAccessExceptionで例外は発生しました"); 22 23 // HTTPのエラーコード(500)をModelに登録 24 model.addAttribute("status", HttpStatus.INTERNAL_SERVER_ERROR); 25 26 return "error"; 27 } 28 29 /* その他の例外処理 */ 30 @ExceptionHandler(Exception.class) 31 public String exeptionHandler(Exception e, Model model) { 32 33 // 空文字をセット 34 model.addAttribute("error", ""); 35 36 // メッセージをModelに登録 37 model.addAttribute("message", "Exception例外が発生しました"); 38 39 // HTTPのエラーコード(500)をModelに登録 40 model.addAttribute("status", HttpStatus.INTERNAL_SERVER_ERROR); 41 42 return "error"; 43 } 44}
共通エラーを出力するファイル(error.html)
error.html
1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org"> 3<head> 4<meta charset="UTF-8"> 5<title>Error</title> 6</head> 7<body> 8 <h1 th:text="${status} + ' ' + ${error}"></h1> 9 <p th:text="${message}"></p> 10 <p>ログイン画面に戻ってください</p> 11 <form method="post" th:action="@{/logout}"> 12 <button class="btn btn-link" type="submit">ログイン画面に戻る</button> 13 </form> 14</body> 15</html>
Spring Securityを実装したファ(SecurityConfig.java)
SecurityConfig.java
1package com.example.config; 2 3import org.springframework.boot.autoconfigure.security.servlet.PathRequest; 4import org.springframework.context.annotation.Bean; 5import org.springframework.context.annotation.Configuration; 6import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7import org.springframework.security.web.SecurityFilterChain; 8 9@Configuration 10public class SecurityConfig { 11 12 @Bean 13 public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 14 15 http.authorizeHttpRequests(authz -> authz // URL毎の認可設定記述開始 16 .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() 17 .mvcMatchers("/login").permitAll() // /loginはログイン無しでもアクセス可能 18 .mvcMatchers("/user/signup").permitAll() // /user/signupはログイン無しでもアクセス可能 19 .anyRequest().authenticated() // 他のURLはログインのみアクセス可能 20 ); 21 return http.build(); 22 } 23}
試したこと
元々はWebSecurityConfigurerAdapterを継承して行う方法が参考書には書かれていましたが、上記(SecurityConfig.java)に書かれている内容に変更しました。
補足情報(FW/ツールのバージョンなど)
- Spring Boot ver 2.7.5
- JRE ver 17
- Spring Security ver 2.7.5