1
0

More than 3 years have passed since last update.

Sprint Security で login URL と login 画面の両方を変更する

Posted at

概要

Spring Boot + Spring Security を用いたユーザーアカウント管理システムにおいて,独自の login 画面を作成し,login ページの URL を /login ではなく /signin とするのに少しだけ手間取った.

最初に結論を示し,続けて参考のために過程を伴う詳細を記す.

前提

  • Spring Security の機能を利用して,ユーザーアカウントの作成,ログイン,ログアウトの最低限の処理を実装したことがある.

  • 独自の login 画面を用いたログイン処理を実装したことがない方は,先に詳細を参照されたい.

環境

  • Spring Boot 2.4.4
  • Spring Security
  • Java 11
  • Thymeleaf

結論

Config,Controller,テンプレートファイルの login 画面表示 URL および login 処理実行 URL に,利用したい値 (ここでは /signin) を指定することで解決する.

WebSecurityConfiguration.java
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
  /* 中略 */
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http./* 中略 */
        .formLogin()
        .loginPage("/signin") // 追記または変更; デフォルト login 画面表示 URL
  }
}
AccountController.java
@GetMapping("/signin") // 変更
public ModelAndView login(ModelAndView modelAndView) {
  modelAndView.setViewName("login");
  return modelAndView;
}
login.html
<form th:method="post" th:action="@{/signin}"> <!-- 変更 -->
  <input type="text" name="username"></td>
  <input type="password" name="password"></td>
  <input type="submit" value="Sign in"/></td>
</form>

詳細

デフォルトの login ページ URL は /login なので,login 画面用のテンプレートファイル login.html (ファイル名はこれに限らない) を作成し,login 用の form に th:action="@{/login}" を追加すれば, login 画面を独自のテンプレートファイルに差し替えることができる.

login.html
<form th:method="post" th:action="@{/login}">
  <input type="text" name="username"></td>
  <input type="password" name="password"></td>
  <input type="submit" value="Sign in"/></td>
</form>

ここで,login 画面を表示する URL を /signin に変更したいとする.

Controller のマッピング URL を変更し,それ以外はデフォルト (/login) とした場合,/signin にアクセスをすれば login 処理は実行できる.

AccountController.java
@GetMapping("/signin")
public ModelAndView login(ModelAndView modelAndView) {
}

ただし,Spring Security で「認証済みでない場合に,許可されていないページにアクセスをするとログインページにリダイレクトされる」機能を利用していると,デフォルトのリダイレクト先が /login であるため独自の login ページが表示されない.

次に,デフォルトの login 画面表示 URL を /signin に変更するために Config に次の記述を追加する.これに伴い,認証なしで /signin にアクセスできるよう設定する.

WebSecurityConfiguration.java
    http.authorizeRequests()
          .mvcMatchers("/", "/signin").permitAll() // 認証なしで /signin にアクセス可能
        .and
        .formLogin()
          .loginPage("/signin") // デフォルト login 画面表示 URL の変更

このとき,login 処理をするための POST リクエストの URL まで変更される模様.リダイレクトされても独自の login ページが表示されるが,今度は submit をしても login 処理ができなくなる.

テンプレートファイルの form の遷移先も同様に変更することでこの問題は解決する.

login.html
<form th:method="post" th:action="@{/signin}">

login 画面を表示する GET リクエスト URL と login 処理を実行する POST リクエスト URL に別の値を指定する

次のように URL を指定する場合の記述を示す.

機能 URL HTTP メソッド
login 画面表示 /signin/form GET
login 処理実行 /signin/execute POST
WebSecurityConfiguration.java
    http.authorizeRequests()
          .mvcMatchers("/", "/signin/**").permitAll() // 変更: /signin -> /signin/**
        .and
        .formLogin()
          .loginPage("/signin/form") // 変更: /signin -> /signin/form
          .loginProcessingUrl("/signin/execute") // 追加
AccountController.java
@GetMapping("/signin/form") // 変更: /signin -> /signin/form
public ModelAndView login(ModelAndView modelAndView) {
  modelAndView.setViewName("login");
  return modelAndView;
}
login.html
<form th:method="post" th:action="@{/signin/execute}"> <!-- 変更 -->
  <input type="text" name="username"></td>
  <input type="password" name="password"></td>
  <input type="submit" value="Sign in"/></td>
</form>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0