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

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

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

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

Spring

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Spring Boot

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

Q&A

解決済

1回答

4225閲覧

SpringSecurityの認証が通らない

退会済みユーザー

退会済みユーザー

総合スコア0

Spring Security

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

Spring

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Spring Boot

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

0グッド

0クリップ

投稿2020/09/25 01:28

編集2020/09/25 05:08

環境

Springを勉強し始めた者です。
現在SpringBoot2 入門: 基礎から実演までの8-3章、【DBのユーザでログインする】のプログラム(Spring-Security3)を動かしています。
フォルダ構成や開発環境、依存関係は全て書に準拠して作成しています。

依存関係
・SpringWeb ・Lombok ・SpringBootDevTool ・Thymeleaf ・SpringDataJPA ・検証 ・SpringSecurity ・H2DB

現在のエラー

【DBのユーザでログインする】のプログラムを動かしてみているのですが、ユーザの登録までは動くのですがログインができず、画面上にerror.htmlで設定したエラー警告を出されてしまいます。
何度もコードを見直したのですが、原因がわかりません。
コンソール上にエラーは表示されていません。

試したこと

ユーザの登録にH2DBを利用しており、登録が実はできていないことが原因と考えH2コンソールでユーザ情報を確認しようともしたのですが、SpringSecurityが働いてしまいコンソールが開かず、真偽不明な状態です。

エラー警告が呼び出されてしまう原因として下記コード内のuserの値がnullであることが原因と考えています。

UserDetailsServiceImplから一部記載

@RequiredArgsConstructor @Service public class UserDetailsServiceImpl implements UserDetailsService{ private final SiteUserRepository userRepository; //ユーザ特定の為のインタフェース //メソッドの戻り値()で見つかったユーザを返す。見つからなかった場合はSecurityのUsename...をthrowする @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{ //現在userの値はNull SiteUser user = userRepository.findByUsername(username); if(user == null) { throw new UsernameNotFoundException(username + "not found"); } return createUserDetails(user); }

ここでusernameの内容を表示するとregisterで登録したユーザ名が表示されます。
このusernameはログインフォームで入力した値がそのまま入っているだけであり、H2DBの中からfindByUsernameでユーザ情報が見かったわけではない。
原因はおそらくregisterの処理にある。

しかしfindByUsernameを用いて取得したusernameはnullとなっており、結果userの値もnullになっており、UsernameNotFoundExceptionに投げられてエラー警告を出されているようです。
ここのリポジトリとエンティティを交えた処理を自分でもうまく理解できておらず原因の修正まで至らない状態です。
usernameの値をuserにコピーできれば動くのではと考えていますがうまくいっていません。

以下参考にリポジトリとエンティティを記載

リポジトリ
SiteUserRepository

package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.example.demo.model.SiteUser; public interface SiteUserRepository extends JpaRepository<SiteUser, Long>{ SiteUser findByUsername(String username); boolean existsByUsername(String username); }

エンティティ
SiteUser

package com.example.demo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import lombok.Getter; import lombok.Setter; @Getter @Setter @Entity public class SiteUser { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Size(min = 2,max = 20) private String username; @Size(min = 4,max = 255) private String password; @NotBlank @Email private String email; private int gender; private boolean admin; private String role; private boolean active = true; }

何卒よろしくお願いします。

追記

プロパティの内容を追記します。

application.properties

spring.datasource.url=jdbc:h2:./testdb spring.jpa.hibernate.ddl-auto=update

SecurityConfig

package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.example.demo.util.Role; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Configuration @EnableWebSecurity public class SeculityConfig extends WebSecurityConfigurerAdapter{ private final UserDetailsService userDetailsService; @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override public void configure(WebSecurity web) throws Exception{ //セキュリティ設定を無視(ignoring)するパスを指定する //通常、CSSやJS、INGなどの静的なリソースを指定する web.ignoring().antMatchers("/js/**","/css/**","/webjars/**"); } @Override protected void configure(HttpSecurity http)throws Exception{ http.authorizeRequests() //「/login」をアクセス可能にする //[/registerを追加] .antMatchers("/login","/register").permitAll() //[/admin]にはAdminユーザのみアクセス可能とする .antMatchers("/admin/**").hasRole(Role.ADMIN.name()) .anyRequest().authenticated() .and() .formLogin() //ログイン時のURLを指定 .loginPage("/login") //認証後にリダイレクトする場所を指定 .defaultSuccessUrl("/") .and() //ログアウトの設定 .logout() //ログアウト時のURLを指定 .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .and() //Remember-Meの認証を許可する。これを指定するとログイン状態の保存ができる .rememberMe(); } @Override protected void configure(AuthenticationManagerBuilder auth)throws Exception{ //userDetailsServiceを利用してDBからユーザを参照できるようにする auth.userDetailsService(userDetailsService) //auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } }

Role

package com.example.demo.util; public enum Role { ADMIN, USER }

Pom.xml内にSTS以外から導入した依存関係の追記部分

<!-- SB Admin2を手動追加(STにパッケージが無いので) --> <dependency> <groupId>org.webjars</groupId> <artifactId>startbootstrap-sb-admin-2</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> <version>0.40</version> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>datatables-buttons</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>datatables-plugins</artifactId> <version>1.10.20</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jszip</artifactId> <version>3.1.0</version> </dependency>

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

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

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

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

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

A-pZ

2020/09/25 01:42

SpringBootの設定(application.propertiesないしはyml)で、特にdataSourceの設定も追記してくださると原因がわかるかもしれません。
退会済みユーザー

退会済みユーザー

2020/09/25 01:55

返信ありがとうございます。 application.propertiesの内容を追加しました。内容は参考本と同様のものです。
A-pZ

2020/09/25 02:07

ありがとうございます。残念ながら私の方では書籍が手元にありませんので、他にもいくつか情報が必要になります。SpringSecurityの設定、ならびにSpringBootの設定でSpringSecurityで追加したものも追記していただけますでしょうか。
退会済みユーザー

退会済みユーザー

2020/09/25 03:07

再度返信ありがとうございます。 Config、Roleの内容と依存関係の記載(STS内に無かったものは直接pom.xmlの内容を記述)を追加しました。 自分の理解が浅く、追記した内容で情報が足りているか判断ができませんので、他追記の必要があればお願いします。
guest

回答1

0

ベストアンサー

起動中のH2 DatabaseへのSpringSecurity保護の解除は /h2-console 以下を含めれば参照できますので、ログインユーザーデータが格納されているかを確認してください。

java

1ignoring().antMatchers("/js/**","/css/**","/webjars/**", "/h2-console/**");

なお、パスワードのフィールドは、同じくSecurityConfig内にて

java

1 @Bean 2 public BCryptPasswordEncoder passwordEncoder() { 3 return new BCryptPasswordEncoder(); 4 } 5 6 @Override 7 protected void configure(AuthenticationManagerBuilder auth) throws Exception{ 8 auth.userDetailsService(userDetailsService) 9 .passwordEncoder(passwordEncoder()); 10 }

と、BCryptPasswordEncoderでencodeした値が保存されます。

パスワードの値は、BCryptPasswordEncoder#encode された内容が格納されていますでしょうか。

記載していただいたコードを参考に私の方で動作確認に必要なクラスを追加+formログイン画面から動作確認したところ、

java

1SiteUser user = userRepository.findByUsername(username);

でSiteUserが取得できるところまでは確認済みです。

投稿2020/09/25 06:51

A-pZ

総合スコア12011

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

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

退会済みユーザー

退会済みユーザー

2020/09/25 07:57

回答ありがとうございます。 SpringSecurity保護の解除の記述は知りませんでした...非常に助かります。 早速H2コンソールを確認したところ接続先のtestdbが存在せず、おそらくそもそもDBの作成ができていない状態のようでした。そのため修正箇所はユーザ登録の記述である可能性が高いです。 原因の特定、原因の箇所が大きく変わるためベストアンサーとさせて頂きます。 また、BCryptPasswordEncoderの内容はパスワードと別の値が格納されていました。
A-pZ

2020/09/25 08:28

もし初期投入用のSQL(schema.sqlやdata.sql)を利用されている場合は、spring.jpa.hibernate.ddl-auto=noneなどをお使いください。updateを指定されているので、Entityに定義しているテーブルがない場合に自動作成されます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問