前提・実現したいこと
Spring Boot、Spring Securityを使って、ログイン機能を実装しようとしています。
認証方法としてはDB認証です。
ログイン画面からDBに登録済みのユーザ情報を入力してログインボタンを押下すると、
「type=Method Not Allowed, status=405」となりました。
POSTであるために怒られているようなのですが、下記のようなキーワードで検索してみても、解決の糸口が見えません。
「Spring Boot HttpRequestMethodNotSupportedException 405」
「Spring Security HttpRequestMethodNotSupportedException Post」
何が原因なのか、わかりますでしょうか?
発生している問題・エラーメッセージ
2022-01-28 22:54:54.381 WARN 22220 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
該当のソースコード
html
1myLogin.html 2 3<!DOCTYPE html> 4<html lang="ja" xmlns:th="http://www.thymeleaf.org"> 5 <head> 6 <meta charset="UTF-8"> 7 <meta name="viewport" content="width=device-width"> 8 <title>ログイン</title> 9<!-- <link rel="stylesheet" href="css/style.css"> --> 10 <link th:href="@{/css/style.css}" rel="stylesheet"> 11 <script type="text/javascript" src="js/site.js"></script> 12 </head> 13 <body> 14 <div class="content"> 15 <h1>ログイン</h1> 16 <p>ログインするには、ユーザ名とパスワードを入力してください。</p> 17 <form method="post" th:action="@{/sign_in}"> 18 <div class="control"> 19 <label for="mymail">ユーザ名</label> 20 <input type="text" name="userName" th:value="*{userName}" required="required"> 21 </div> 22 23 <div class="control"> 24 <label for="passcode">パスワード</label> 25 <input type="password" name="password" th:value="*{password}" required="required"> 26 </div> 27 28 <div> 29 <button class="button_login" type="submit">ログインする</button> 30 </div> 31 </form> 32 </div> 33 </body> 34</html>
java
1//WebSecurityConfig.java 2 3package com.example.demo.controller; 4 5import java.io.IOException; 6 7import javax.servlet.ServletException; 8import javax.servlet.http.HttpServletRequest; 9import javax.servlet.http.HttpServletResponse; 10 11import org.springframework.beans.factory.annotation.Autowired; 12import org.springframework.context.annotation.Bean; 13import org.springframework.context.annotation.Configuration; 14import org.springframework.security.authentication.BadCredentialsException; 15import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 16import org.springframework.security.config.annotation.web.builders.HttpSecurity; 17import org.springframework.security.config.annotation.web.builders.WebSecurity; 18import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 19import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 20import org.springframework.security.core.AuthenticationException; 21import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 22import org.springframework.security.crypto.password.PasswordEncoder; 23import org.springframework.security.web.authentication.AuthenticationFailureHandler; 24 25import com.example.demo.dao.ScheduleUserDaoImpl; 26 27/* 28 * 認証・認可についての設定を記述したクラス 29 * Spring BootでSpring Securityを使うには、WebSecurityConfigurerAdapterクラスを継承して定義を行います。 30 */ 31@Configuration 32@EnableWebSecurity 33public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ 34 35 @Autowired 36 private ScheduleUserService scheduleUserService; 37 38 @Autowired 39 ScheduleUserDaoImpl dao; 40 41 //認証用パスワードはハッシュ化して扱うためPasswordをハッシュ化する際に必要なBCryptPasswordEncoder()を返すメソッドを作成しておく。 42 @Bean 43 public PasswordEncoder passwordEncoder() { 44 BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); 45 return bCryptPasswordEncoder; 46 } 47 48 /** 49 * 認可設定を無視するリクエストを設定 50 * 静的リソース(image,javascript,css)を認可処理の対象から除外する 51 * 主に全体に対するセキュリティ設定を行う 52 */ 53 @Override 54 public void configure(WebSecurity web) throws Exception { 55 web.ignoring().antMatchers("/css/**", "/js/**"); 56// web.ignoring().antMatchers("/**"); 57 } 58 59 /** 60 * 認証・認可の情報を設定する 61 * SpringSecurityのconfigureメソッドをオーバーライドしています。 62 * 主にURLごとに異なるセキュリティ設定を行う 63 */ 64 @Override 65 protected void configure(HttpSecurity http) throws Exception { 66 http 67 .authorizeRequests() 68 // ログイン画面は直リンクOK 69 .antMatchers("/myLogin").permitAll() 70 // 405エラー対策としてこれを追加してみる。 71// .antMatchers("/sign_in").permitAll() 72 // それ以外は直リンク禁止 73 .anyRequest().authenticated() 74 .and() 75 .formLogin() 76 // これを設定しておかないと、デフォルトのログインページが表示される。 77 .loginPage("/myLogin") 78 .loginProcessingUrl("/sign_in") //フォームのSubmitURL、このURLへリクエストが送られると認証処理が実行される 79 .usernameParameter("userName") //リクエストパラメータのname属性を明示 80 .passwordParameter("password") 81 .successForwardUrl("/list") 82// .successForwardUrl("redirect:list") 83 .failureUrl("/myLogin"); 84// .and() 85// .httpBasic(); 86 87 http 88 .logout() 89// .logoutRequestMatcher(new AntPathRequestMacher("/logout")) 90 .logoutUrl("/logout") 91 // ログアウト時の遷移先URL 92 .logoutSuccessUrl("/Mylogin"); 93 94 } 95 96 /*// (4) 主に認証方法の実装の設定を行う 97 * (非 Javadoc) 98 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder) 99 * ここでは、認証にuserDetailsServiceを用いることを指定し、 100 * 更に引数に先ほど作成した実装クラスを渡してあげると、 101 * DaoAuthenticationProviderというクラスが呼ばれ、 102 * 認証の中で実装したloadUserByUsernameメソッドを呼んでくれるようになります。 103 * passwordEncoderにはDBのものと同じ暗号化方式を指定し、フォームの入力値とDBのパスワードを比較し認証処理を行うために利用します。 104 * https://qiita.com/a-pompom/items/80b3f4bb6414e8678829 105 */ 106 @Override 107 public void configure(AuthenticationManagerBuilder auth) throws Exception{ 108 System.out.println("scheduleUserService実行する!"); 109 auth.userDetailsService(scheduleUserService).passwordEncoder(passwordEncoder()); 110// dao.getUserId("userName").passwordEncoder(passwordEncoder()); 111 } 112 113 /* 114 * (非 Javadoc) 115 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#userDetailsService() 116 * UserDetailsService を Bean として登録する。 117 * このインターフェースはユーザーの詳細な情報(UserDetails)を取得してくる機能を提供する。 118 */ 119 120 /* 121 * 未ログインの状態ではログイン画面に飛ぶようにしてみます。 122 * その場合、WebSecurityConfigurerAdapterのサブクラスを作って認証処理の設定を作り込むようです。 123 */ 124 public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler{ 125 126 @Override 127 public void onAuthenticationFailure( 128 HttpServletRequest request, 129 HttpServletResponse response, 130 AuthenticationException exception) throws IOException, ServletException { 131 132 String errorId = "ERR_001"; 133 if(exception instanceof BadCredentialsException){ 134 errorId = "LOGIN_001"; 135 } 136 137 // ログイン画面にリダイレクトする 138 response.sendRedirect("/myLogin?error=" + errorId); 139 } 140 } 141
ScheduleUserService.java
→長すぎて文字数制限を超過してしまったため、下記リンクに書きました。
https://docs.google.com/document/d/1hJYfZRWbqgfCHDJFCduNU2Se2ztz-ilQzylkiD03BV4/edit
LoginController.java
→長すぎて文字数制限を超過してしまったため、下記リンクに書きました。
https://docs.google.com/document/d/1EGWBNfjSk0BmkrTYtCde06TDwJZCu5xcWzhnGfE_pTk/edit
list.html
→長すぎて文字数制限を超過してしまったため、下記リンクに書きました。
https://docs.google.com/document/d/1-LUwwRxVwIS_dwkjaccngUYm-YpV_h4iIahi2smYpfM/edit
ScheduleController.java
→長すぎて文字数制限を超過してしまったため、下記リンクに書きました。
https://docs.google.com/document/d/1MmKavkcYDWuxJ_ezkV292OzIKvpO1PoKuVbTnoN2p08/edit
実行結果
Springアプリケーション起動し、ログイン画面に行って、
DBのテーブルに登録済みのユーザーIDとパスワードを入力しログインボタンを押下すると、
コンソールには下記が表示されます。
ログイン! ログイン! ScheduleUserServiceの38行目 sample1 2022-01-28 23:20:21.768 DEBUG 6836 --- [nio-8080-exec-7] org.hibernate.SQL : select scheduleus0_.user_id as user_id1_1_, scheduleus0_.password as password2_1_, scheduleus0_.user_name as user_nam3_1_ from schedule_user scheduleus0_ where scheduleus0_.user_name=? 2022-01-28 23:20:21.772 TRACE 6836 --- [nio-8080-exec-7] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [sample1] 50行目:entityの中身 3 sample1 $2a$10$17RU1NGRZqCrOvBS63WquusZuWKBZeoC7SHYZjRlDvLpctsjtyPJy 2022-01-28 23:20:21.864 WARN 6836 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
試したこと
①application.propertiesに下記を追加しましたが、エラーメッセージは変わりませんでした。
(https://www.ninton.co.jp/archives/8215 を参考にしました)
spring.mvc.hiddenmethod.filter.enabled=true spring.webflux.hiddenmethod.filter.enabled=true
②ダメ元で、WebSecurityConfig.javaの
protected void configure(HttpSecurity http)
の中に、
.antMatchers("/sign_in").permitAll()
を追加してみましたが変わりませんでした。
③よくわかっていないのですが、とりあえず
LoginControllerのgetLoginメソッドをすべてコメントアウトしてみましたが、変わりありませんでした。
補足情報(FW/ツールのバージョンなど)
Spring Boot
Java1.8
Eclipse
Maven
よろしくお願い致します。
回答1件
あなたの回答
tips
プレビュー