質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Spring Security

Spring Securityは、Springのサブプロジェクトの一つでWebアプリケーションに必要な機能を追加します。正規ユーザーであるかを確認するための「認証機能」と、ユーザーのアクセスを制御する「認可機能」を簡単に追加することが可能です。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

1872閲覧

SpringBootの独自ログイン認証が成功しない。loadUserByUsernameでインスタンスを取得も認証失敗するのは何故でしょうか。

spring_boot

総合スコア12

Spring Security

Spring Securityは、Springのサブプロジェクトの一つでWebアプリケーションに必要な機能を追加します。正規ユーザーであるかを確認するための「認証機能」と、ユーザーのアクセスを制御する「認可機能」を簡単に追加することが可能です。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2018/09/28 04:08

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もそのままリターンしてよいのか。様々な記事やドキュメントを読みましたが該当記事が見当たりませんでした。
もし、解決のヒントでもありましたらご教授いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こちら自己解決いたしました。

パスワードをハッシュ化させる前は、SpringSecurityの仕様でパスワードの値に「{noop}」とつける必要があること。DaoAuthenticationProviderをBeanとして登録しておくだけでパスワードに対してハッシュ化されているかの判定がかかり認証が通過しなくなること。以上二点でした。二つ目はおそらくなので定かではないですが、事前に登録していたBeanをひとまずコメントアウトしたところ動作が成功したので影響を受けていたことは確かです。

投稿2018/09/28 08:25

spring_boot

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問