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

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

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

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

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

解決済

【Spring Security】emailとpasswordでログイン認証を行う

hotoke6
hotoke6

総合スコア0

Spring Security

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

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

1回答

0評価

0クリップ

18閲覧

投稿2019/07/28 09:37

編集2022/01/12 10:58

前提・実現したいこと

Spring Securityでemailとpasswordを用いてログイン認証を行う。

###問題
すでに実装済みのアカウント登録機能で登録したemailをJpaUserDetailsServiceImplのfindByAccountEmailメソッドでDBから引っ張ってこれているにも関わらずhttp://localhost:8080/login/?errorに遷移しログインができない。

該当のソースコード

Account

AccountRepository

public interface AccountRepository extends JpaRepository<Account, Integer>, JpaSpecificationExecutor<Account> { @Query(value = "SELECT * FROM accounts WHERE account_email = :account_email AND account_delete_flag = 0", nativeQuery = true) Account findByAccountEmail(@Param("account_email") String accountEmail); /** * Emailに紐づくアカウントの件数を取得する。 * * @param account_email Email * @return 件数 */ @Query(value = "SELECT COUNT(*) FROM accounts WHERE account_email = :account_email AND account_delete_flag = 0", nativeQuery = true) int countByAccountEmail(@Param("account_email") String accountEmail); /** * 全アカウントを検索する。 * * @return 全アカウントのリスト */ @Query(value = "SELECT * FROM accounts WHERE account_delete_flag = 0", nativeQuery = true) List<Account> findAllAccount(); }

WebSecurityConfig

@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) { // 認証状態によらず許可するパス web.ignoring().antMatchers("/favicon.ico", "/css/**", "/js/**", "/bootstrap/css/**", "/bootstrap/js/**", "/jquery/**", "/img/**", "/fonts/**"); } @Override protected void configure(HttpSecurity http) throws Exception { // SessionFixation対策 http.sessionManagement().sessionFixation().newSession(); http.authorizeRequests() // 認証状態によらず許可するURL .antMatchers("/").permitAll() .antMatchers("/login").permitAll() .antMatchers("/account/register/**").permitAll() .antMatchers("/resources/**").permitAll() .anyRequest().authenticated(); http.formLogin() .loginPage("/login") // ログインページのパス .loginProcessingUrl("/login") // 認証処理を起動させるパス .failureUrl("/login/?error") // ログイン処理失敗時の遷移先 .successForwardUrl("/top/loginSuccess") // ログイン成功時の繊維先 .usernameParameter("login_id")// ユーザid .passwordParameter("login_password").permitAll(); // パスワード http.logout() .logoutUrl("/logout") // ログアウト処理を起動させるパス .logoutSuccessUrl("/login") // ログアウト完了時のパス .deleteCookies("JSESSIONID", "SESSION") .invalidateHttpSession(true).permitAll(); } @Configuration protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { final JpaUserDetailsServiceImpl userDetailsService; @Autowired public AuthenticationConfiguration(JpaUserDetailsServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } @Override public void init(AuthenticationManagerBuilder auth) throws Exception { // 認証するユーザーを設定する auth.userDetailsService(userDetailsService) // 入力値をbcryptでハッシュ化した値でパスワード認証を行う .passwordEncoder(new BCryptPasswordEncoder()); } } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }

JpaUserDetailsServiceImpl

@Component @Transactional public class JpaUserDetailsServiceImpl implements UserDetailsService { /** アカウントリポジトリ */ private final AccountRepository accountRepository; @Autowired public JpaUserDetailsServiceImpl(AccountRepository accountRepository) { this.accountRepository = accountRepository; } @Override public UserDetails loadUserByUsername(String accountEmail) throws UsernameNotFoundException { Account account = accountRepository.findByAccountEmail(accountEmail); if (Objects.isNull(account)) { return new Account(); } return account; } }

TopController

@Controller @RequestMapping("/top") public class TopController { /**トップサービス*/ private final TopService service; /** HTTPセッション */ private final HttpSession session; /** セッションキー(ログインユーザのアカウント) */ private static final String SESSION_FORM_ID = "account"; /** コード値 */ @Autowired public TopController(TopService topService, HttpSession session) { this.service = topService; this.session = session; } /** * ログイン成功時処理。 * * @return Path */ @RequestMapping(value = "loginSuccess") public String loginSuccess() { return "redirect:/top"; } /** * トップ画面表示。 * * @param account 認証されたアカウント * @param model モデル * @return Path */ @RequestMapping(value = "") public String init(@AuthenticationPrincipal Account account, Model model) { // 初回のアクセスなら、アカウントを検索してセッションに格納する if (Objects.isNull(session.getAttribute(SESSION_FORM_ID))) { Account sessionAccount = service.getAccountById(account.getAccountId()); session.setAttribute(SESSION_FORM_ID, sessionAccount); } return "top"; } }

login

試したこと

  1. WebSecurityConfigのfailureUrlをコメントアウト

→依然ログイン失敗、URLに/login?errorが表示される
2. Spring Security関連のブログやQiita等を散見
→解決せず

補足情報(FW/ツールのバージョンなど)

もともとuserIdとpasswordでログイン認証を行なっていたアプリのソースコードを元にemailでログインできるよう編集中

上記の問題でかなり長いこと詰まっているため解決方法ご教示いただけると幸いです。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

asahina1979
asahina1979

2019/07/28 09:49

で?エラーログ確認してない人に回答がつくことはないと思うが
hotoke6
hotoke6

2019/07/28 10:02

ご意見いただきありがとうございます。 プログラミング初心者なため至らない点どうかご容赦ください。 コメントの件ですが、ここでのエラーログとはスタックトレースのことでしょうか? 今回はログイン成功先に遷移せず、ログイン失敗先に遷移しているためプログラム上のエラーがありません。 そのためスタックトレース上にもエラーが表示されないためどこが問題かわからない状態です。 私の「エラーログ」に関する受け取り方が間違っていればその点ご指摘ください。 よろしくお願いいたします。
asahina1979
asahina1979

2019/07/28 10:29

おそらく認証で「BadCredentialsException」か「IllegalArgumentException\("Bad strength"\)」が投げられてるきがするんだが
asahina1979
asahina1979

2019/07/28 10:42

ちなみに一応確認しておこう(w SELECT \* FROM accounts WHERE account_email = :account_email AND account_delete_flag = 0 AND account_password = :account_password :account_email は あなたが画面で入力したメールアドレス :account_password は あなたが画面で入力したパスワード で1件の返却があるならログインできません。
hotoke6
hotoke6

2019/07/28 11:44

回答ありがとうございます。 1\. BadCredentialsException等のエラーメッセージは見受けられませんでした。 2\. JpaUserDetailsServiceImplの中でオーバーライドしているUserDetailsのloadUserByUsernameはemailの値をキーにしてアカウント情報の存在を確認するだけという認識でしたので、記載いただいた「AND account_password = :account_password」を含むクエリ文は書いていません。 その上で「1件の返却があるならログインできない」という件について詳細お聞きすることは可能でしょうか? お手数おかけしますがよろしくお願いいたします。
rubytomato
rubytomato

2019/07/28 22:48

accountsテーブルに登録したデータは動作検証用だと思うのですが、データはinsert文を直接実行して登録されたのでしょうか\? それともアカウント登録画面も実装済みで画面から登録されたのでしょうか\?
hotoke6
hotoke6

2019/07/28 22:51

コメントありがとうございます。 こちらアカウント登録画面が実装済で画面上から登録いたしました。 なおパスワードはBCryptPasswordEncoderを使用しハッシュ化した状態で登録しております。
rubytomato
rubytomato

2019/07/28 23:00

ご確認ありがとうございます。 それではフレームワークのバージョンと、差し支えなければpom\.xmlとjavaソースコードについてはimport文も質問に記載をお願いできますでしょうか。
hotoke6
hotoke6

2019/07/29 00:32

文字数制限のため下記リンクにpom\.xml追記とTopコントローラーとlogin\.htmlの移動を行いました。 見にくくて申し訳ありませんがよろしくお願いいたします。 https://teratail\.com/questions/203137にpom\.xml

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Spring Security

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

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