MENU

【SpringBoot】Spring Securityを使って、メールアドレスでログイン処理を行う。

こんにちは、くまごろーです。
資格の勉強もひと段落ついたので、年内はポートフォリオの作成に集中することにしました。

Spring Securityを使ってログイン機能を実装しているんですが、Spring Securityはデフォルトでは"username"でログイン処理を行うようになっているんですよね。それをメールアドレスでの認証に変更したかったんですが中々うまくいかず・・・
正解にたどり着けず苦戦したのでここでまとめておきます。
 
 
 
1 Configクラス
 
【このクラスでやること】
(1)ログインフォームで入力された「メールアドレス」「パスワード」を、SecurityConfigを通して受け取るよう設定する
(2)UserDetailsServiceクラスで、DBからユーザーを参照できるようにする
 
<SecurityConfig.java

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests().antMatchers("/login", "/register").permitAll().anyRequest().authenticated()
      .and()
      .formLogin().loginPage("/login").defaultSuccessUrl("/")
      .usernameParameter("email")  //usernameの値を"email"から取得するよう設定する
      .passwordParameter("password")
      .and()
      .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
      .and()
      .rememberMe();
  }
	
@Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    auth  //ユーザの設定
      //userDetailsServiceで、DBからユーザーを参照できるようにする
      .userDetailsService(userDetailsService)    
      .passwordEncoder(passwordEncoder());
  }

 
※  usernameParameter(), passwordParameter()で指定する文字列は、htmlのname属性の名前と同名になる。
 
  
 
2 Repositoryクラス

 このクラスでは、"email"でユーザーを検索するメソッドを実装する。

<UserRepository.java

public interface SiteUserRepository extends JpaRepository<SiteUser, Long> {
  //Emailでユーザーを検索
  public SiteUser findByEmail(String email);
}


※ Repositoryインターフェースでは、規則に従ってメソッド名を宣言することで、自動実装が利用可能になる。(詳細については以下のページでわかりやすく説明されています。)

以下の3つの要素を規則に従って組み合わせたメソッド名をRepositoryインターフェースに宣言することで、自動実装が利用可能になります。

プレフィックス(find...By read...By query...By count...By get...By)
キーワード
フィールド名

【Spring Data JPA】自動実装されるメソッドの命名ルール - Qiita

 
 
3 UserDetailsServiceクラス
 
【ここでやること】
(1)RepositoryクラスのメソッドでDBからユーザーを検索する
(2)見つかったユーザー情報をSiteUserクラスに格納
(3)ユーザーに応じて権限を設定
(4)User(Details)オブジェクト生成し、認証処理へ
 
<UserDetailsServiceImpl.java

@Override
  public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException{
    SiteUser user =  userRepository.findByEmail(email);
    if(user == null) {
      //ユーザーが見つからなければ、SpringSecurityの以下の例外をthrowする。
      throw new UsernameNotFoundException(email + " not found");
    }
    return createUserDetails(user);
  }
	
  public User createUserDetails(SiteUser user) {
    Set<GrantedAuthority> grantedAuthories = new HashSet<>();
    grantedAuthories.add(new SimpleGrantedAuthority("ROLE_" + user.getRole()));

    return new User(user.getUsername(), user.getPassword(), grantedAuthories);
  }

 
 
  
4 参考
spring Security ログインフォームの項目とSecurytyConfig、値の受け渡し - Qiita
Spring-Bootでログイン機能を実装してみる - Qiita
【Spring Data JPA】自動実装されるメソッドの命名ルール - Qiita