前提・実現したいこと
Spring Securityでemailとpasswordを用いてログイン認証を行う。
###問題
すでに実装済みのアカウント登録機能で登録したemailをJpaUserDetailsServiceImplのfindByAccountEmailメソッドでDBから引っ張ってこれているにも関わらずhttp://localhost:8080/login/?errorに遷移しログインができない。
該当のソースコード
Account
1 2package com.example.demo.entity; 3import org.springframework.security.core.GrantedAuthority; 4import org.springframework.security.core.userdetails.UserDetails; 5import javax.persistence.*; 6import java.sql.Timestamp; 7import java.util.Collection; 8import java.util.Date; 9 10@Entity 11@Table(name = "accounts") 12public class Account implements UserDetails { 13 @Id 14 @GeneratedValue(strategy = GenerationType.IDENTITY) 15 @Column(name = "account_id") 16 private int accountId; 17 18 19 @Column(name = "account_email", nullable = false) 20 private String accountEmail; 21 22 @Column(name = "account_password", nullable = false) 23 private String accountPassword; 24 25 @Column(name = "account_delete_flag", nullable = false) 26 private int accountDeleteFlag; 27 28 29 public int getAccountId() { 30 return accountId; 31 } 32 33 public String getAccountEmail() { 34 return accountEmail; 35 } 36 37 public String getAccountPassword() { 38 return accountPassword; 39 } 40 41 42 public Timestamp getAccountRegisterDate() { 43 return accountRegisterDate; 44 } 45 46 public int getAccountDeleteFlag() { 47 return accountDeleteFlag; 48 } 49 50 public void setAccountId(int accountId) { 51 this.accountId = accountId; 52 } 53 54 55 public void setAccountEmail(String accountEmail) { 56 this.accountEmail = accountEmail; 57 } 58 59 public void setAccountPassword(String accountPassword) { 60 this.accountPassword = accountPassword; 61 } 62 63 public void setAccountDeleteFlag(int accountDeleteFlag) { 64 this.accountDeleteFlag = accountDeleteFlag; 65 } 66 67 @Override 68 public Collection<? extends GrantedAuthority> getAuthorities() { 69 return null; 70 } 71 72 @Override 73 public String getUsername() { 74 return this.accountEmail; 75 } 76 77 @Override 78 public String getPassword() { 79 return this.accountPassword; 80 } 81 82 @Override 83 public boolean isAccountNonExpired() { 84 return false; 85 } 86 87 @Override 88 public boolean isAccountNonLocked() { 89 return false; 90 } 91 92 @Override 93 public boolean isCredentialsNonExpired() { 94 return false; 95 } 96 97 @Override 98 public boolean isEnabled() { 99 return false; 100 } 101} 102
AccountRepository
1package com.example.demo.entity; 2 3import org.springframework.data.jpa.repository.JpaRepository; 4import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 5import org.springframework.data.jpa.repository.Query; 6import org.springframework.data.repository.query.Param; 7 8import java.util.List; 9public interface AccountRepository extends JpaRepository<Account, Integer>, JpaSpecificationExecutor<Account> { 10 11 @Query(value = "SELECT * FROM accounts WHERE account_email = :account_email AND account_delete_flag = 0", nativeQuery = true) 12 Account findByAccountEmail(@Param("account_email") String accountEmail); 13 14 /** 15 * Emailに紐づくアカウントの件数を取得する。 16 * 17 * @param account_email Email 18 * @return 件数 19 */ 20 21 @Query(value = "SELECT COUNT(*) FROM accounts WHERE account_email = :account_email AND account_delete_flag = 0", nativeQuery = true) 22 int countByAccountEmail(@Param("account_email") String accountEmail); 23 24 /** 25 * 全アカウントを検索する。 26 * 27 * @return 全アカウントのリスト 28 */ 29 @Query(value = "SELECT * FROM accounts WHERE account_delete_flag = 0", nativeQuery = true) 30 List<Account> findAllAccount(); 31} 32
WebSecurityConfig
1package com.example.demo.config; 2 3import com.example.demo.service.JpaUserDetailsServiceImpl; 4import org.springframework.beans.factory.annotation.Autowired; 5import org.springframework.context.annotation.Bean; 6import org.springframework.context.annotation.Configuration; 7import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 8import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter; 9import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10import org.springframework.security.config.annotation.web.builders.WebSecurity; 11import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 14import org.springframework.security.crypto.password.PasswordEncoder; 15 16@Configuration 17@EnableWebSecurity 18public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 19 20 @Override 21 public void configure(WebSecurity web) { 22 // 認証状態によらず許可するパス 23 web.ignoring().antMatchers("/favicon.ico", "/css/**", "/js/**", "/bootstrap/css/**", "/bootstrap/js/**", "/jquery/**", "/img/**", "/fonts/**"); 24 } 25 26 @Override 27 protected void configure(HttpSecurity http) throws Exception { 28 29 // SessionFixation対策 30 http.sessionManagement().sessionFixation().newSession(); 31 32 http.authorizeRequests() 33 // 認証状態によらず許可するURL 34 .antMatchers("/").permitAll() 35 .antMatchers("/login").permitAll() 36 .antMatchers("/account/register/**").permitAll() 37 .antMatchers("/resources/**").permitAll() 38 .anyRequest().authenticated(); 39 40 http.formLogin() 41 .loginPage("/login") // ログインページのパス 42 .loginProcessingUrl("/login") // 認証処理を起動させるパス 43 .failureUrl("/login/?error") // ログイン処理失敗時の遷移先 44 .successForwardUrl("/top/loginSuccess") // ログイン成功時の繊維先 45 .usernameParameter("login_id")// ユーザid 46 .passwordParameter("login_password").permitAll(); // パスワード 47 48 http.logout() 49 .logoutUrl("/logout") // ログアウト処理を起動させるパス 50 .logoutSuccessUrl("/login") // ログアウト完了時のパス 51 .deleteCookies("JSESSIONID", "SESSION") 52 .invalidateHttpSession(true).permitAll(); 53 54 } 55 56 @Configuration 57 protected static class AuthenticationConfiguration 58 extends GlobalAuthenticationConfigurerAdapter { 59 60 final JpaUserDetailsServiceImpl userDetailsService; 61 62 @Autowired 63 public AuthenticationConfiguration(JpaUserDetailsServiceImpl userDetailsService) { 64 this.userDetailsService = userDetailsService; 65 } 66 67 @Override 68 public void init(AuthenticationManagerBuilder auth) throws Exception { 69 // 認証するユーザーを設定する 70 auth.userDetailsService(userDetailsService) 71 // 入力値をbcryptでハッシュ化した値でパスワード認証を行う 72 .passwordEncoder(new BCryptPasswordEncoder()); 73 } 74 } 75 76 @Bean 77 public PasswordEncoder passwordEncoder() { 78 return new BCryptPasswordEncoder(); 79 } 80}
JpaUserDetailsServiceImpl
1package com.example.demo.service; 2import com.example.demo.entity.Account; 3import com.example.demo.entity.AccountRepository; 4import org.springframework.beans.factory.annotation.Autowired; 5import org.springframework.security.core.userdetails.UserDetails; 6import org.springframework.security.core.userdetails.UserDetailsService; 7import org.springframework.security.core.userdetails.UsernameNotFoundException; 8import org.springframework.stereotype.Component; 9import org.springframework.transaction.annotation.Transactional; 10import java.util.Objects; 11@Component 12@Transactional 13public class JpaUserDetailsServiceImpl implements UserDetailsService { 14 15 /** アカウントリポジトリ */ 16 private final AccountRepository accountRepository; 17 18 @Autowired 19 public JpaUserDetailsServiceImpl(AccountRepository accountRepository) { 20 this.accountRepository = accountRepository; 21 } 22 23 @Override 24 public UserDetails loadUserByUsername(String accountEmail) throws UsernameNotFoundException { 25 Account account = accountRepository.findByAccountEmail(accountEmail); 26 if (Objects.isNull(account)) { 27 return new Account(); 28 } 29 return account; 30 } 31} 32
試したこと
- WebSecurityConfigのfailureUrlをコメントアウト
→依然ログイン失敗、URLに/login?errorが表示される
2. Spring Security関連のブログやQiita等を散見
→解決せず
補足情報(FW/ツールのバージョンなど)
もともとuserIdとpasswordでログイン認証を行なっていたアプリのソースコードを元にemailでログインできるよう編集中
上記の問題でかなり長いこと詰まっているため解決方法ご教示いただけると幸いです。
回答1件
あなたの回答
tips
プレビュー