SpringBoot2で日本語記事を参考にログイン認証機能を作っています。
SpringSecuityyでは基本的にはUserというデータベースを用意し、「username」「password」という名前のカラムで
ログイン認証機能が自動で働くようになっています。
しかし、基本的には「email」カラムと「password」でログインをするだろうということで
独自認証機能を作っていますが、どの記事を見ても方法はさまざまでなかなかゴールにたどり着けません。
現在Spring bootでweb セキュリティ(ログイン認証)編
を見ながらコードを作ってみたのですがこの通りではうまくいきません。
設定は以下のようになっています。inMemoryAuthenticationやjdbcAuthenticationなど基本的な認証は成功しています。今回は
java
1auth.userDetailsService(userInfoService);
以上の設定でUserDetailsServiceを実装したUserInfoServiceを認証に使用しています。以下全コードです。
DemoSecurityConfig.java
java
1package com.example.demo.config; 2 3import javax.sql.DataSource; 4 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.context.annotation.Bean; 7import org.springframework.context.annotation.Configuration; 8import org.springframework.security.authentication.AuthenticationProvider; 9import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 10import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 11import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 13import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 14import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 15 16import com.example.demo.service.UserInfoService; 17 18@Configuration 19@EnableWebSecurity 20public class DemoSecurityConfig extends WebSecurityConfigurerAdapter { 21 22 @Autowired 23 private DataSource securityDataSource; 24 25 @Autowired 26 private UserInfoService userInfoService; 27 28 @Override 29 protected void configure(AuthenticationManagerBuilder auth) throws Exception { 30// auth.inMemoryAuthentication().withUser("john").password("{noop}test123").roles("EMPLOYEE"); 31// auth.inMemoryAuthentication().withUser("mary").password("{noop}test123").roles("MANAGER"); 32// auth.inMemoryAuthentication().withUser("susan").password("{noop}test123").roles("ADMIN"); 33// auth.jdbcAuthentication().dataSource(securityDataSource); 34 35 auth.userDetailsService(userInfoService); 36 37 38 } 39 40 41 @Override 42 protected void configure(HttpSecurity http) throws Exception { 43 44 http.authorizeRequests() 45 .antMatchers("/register/**").permitAll()//**はそれより下の階層全て 46 .anyRequest().authenticated() 47 .and() 48 .formLogin() 49 .loginPage("/showMyLoginPage") 50 .loginProcessingUrl("/authenticateTheUser") 51 .permitAll() 52 .and() 53 .logout().permitAll() 54 .and() 55 .exceptionHandling().accessDeniedPage("/access-denied"); 56 } 57 58}
UserInfoのエンティティとUserInfoServiceは以下のようになっています。
UserInfo.java
java
1package com.example.demo.entity; 2 3import java.util.ArrayList; 4import java.util.Collection; 5import java.util.List; 6 7import javax.persistence.Column; 8import javax.persistence.Entity; 9import javax.persistence.GeneratedValue; 10import javax.persistence.Id; 11import javax.persistence.Table; 12 13import org.springframework.security.core.GrantedAuthority; 14import org.springframework.security.core.authority.SimpleGrantedAuthority; 15import org.springframework.security.core.userdetails.UserDetails; 16 17import lombok.AllArgsConstructor; 18import lombok.Data; 19import lombok.NoArgsConstructor; 20 21@Data 22@NoArgsConstructor 23@AllArgsConstructor 24@Entity 25@Table(name="user_info") 26public class UserInfo implements UserDetails{//ログイン認証用のテーブルはUserDetailsのimplementsが必要 27 28 /** 29 * 30 */ 31 private static final long serialVersionUID = 1L; 32 33 @Id 34 @GeneratedValue 35 private String username; 36 37 @Column(nullable = false) 38 private String email; 39 40 @Column(nullable = false) 41 private String password; 42 43 @Column(nullable = false) 44 private Boolean enabled; 45 46 @Column(nullable = false) 47 private String authority; 48 49 50 51 @Override 52 public Collection<? extends GrantedAuthority> getAuthorities() { 53 // TODO Auto-generated method stub 54 List<GrantedAuthority> authorities = new ArrayList<>(); 55 authorities.add(new SimpleGrantedAuthority(authority)); 56 System.out.println(authorities); 57 return authorities; 58 } 59 60 @Override 61 public boolean isAccountNonExpired() { 62 // TODO Auto-generated method stub 63 return false; 64 } 65 66 @Override 67 public boolean isAccountNonLocked() { 68 // TODO Auto-generated method stub 69 return false; 70 } 71 72 @Override 73 public boolean isCredentialsNonExpired() { 74 // TODO Auto-generated method stub 75 return false; 76 } 77 78 @Override 79 public boolean isEnabled() { 80 // TODO Auto-generated method stub 81 return false; 82 } 83 84 85 86}
UserInfoRepository.java
java
1package com.example.demo.repositories; 2 3import org.springframework.data.jpa.repository.JpaRepository; 4 5import com.example.demo.entity.UserInfo; 6 7public interface UserInfoRepository extends JpaRepository<UserInfo, String> { 8 9 public UserInfo findByEmail(String email); 10 11} 12
UserInfoService.java
java
1package com.example.demo.service; 2 3import javax.transaction.Transactional; 4 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.security.core.userdetails.UserDetails; 7import org.springframework.security.core.userdetails.UserDetailsService; 8import org.springframework.security.core.userdetails.UsernameNotFoundException; 9import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10import org.springframework.stereotype.Service; 11 12import com.example.demo.entity.UserInfo; 13import com.example.demo.repositories.UserInfoRepository; 14 15@Service 16public class UserInfoService implements UserDetailsService { 17 18 @Autowired 19 UserInfoRepository repository; 20 21 @Autowired 22 private BCryptPasswordEncoder passwordEncoder; 23 24 @Override 25 public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { 26 // TODO Auto-generated method stub 27 System.out.println(email);//user@test到着 28 if(email == null || "".equals(email)) { 29 throw new UsernameNotFoundException("Username is empty"); 30 } 31 32 UserInfo userInfo = repository.findByEmail(email); 33 System.out.println(userInfo); 34 //UserInfo(username=test_user, email=test@user, password=test, 35 //enabled=true, authority=ROLE_USER)取得 36 if(userInfo == null) { 37 throw new UsernameNotFoundException("User not found for email:" + email); 38 } 39 40 return userInfo; 41 } 42 43 44} 45
ここで一番詰んでいるのが
java
1UserInfo userInfo = repository.findByEmail(email);
上記コードでUserInfo(username=test_user, email=test@user, password=test, enabled=true, authority=ROLE_USER)
というオブジェクトを取得できているにもかかわらず認証に成功しないことです。
フォームはnameがusernameとpasswordのインプットがあり、「test@user」「test」と入力しています。
Spring bootでweb セキュリティ(ログイン認証)編の記事で気になるのは、認証をemailに切り替えたことを伝えるコードが入っていないことです。実際に判定しているのはDaoAuthenticationProviderでしょうか。emailカラムの内容と入力値が一致していることを伝えるコードを入れなければいけない気がしてなりません。そしてuserInfoもそのままリターンしてよいのか。様々な記事やドキュメントを読みましたが該当記事が見当たりませんでした。
もし、解決のヒントでもありましたらご教授いただけると幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。