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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Spring Boot

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

Q&A

解決済

1回答

3559閲覧

パスワードのハッシュ化の方法がわからない

jampack

総合スコア10

Spring Security

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Spring Boot

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

0グッド

1クリップ

投稿2019/06/02 02:44

編集2019/06/03 01:30

目的:BCryptPasswordEncorderを使用してパスワードをハッシュ化したい
ログイン画面の動作確認のためDBに保存しているアカウントでログインしたいのですがDBにはハッシュ化されたパスワードをいれなければならないので困っています。
本の通りに進めているのですが本ではINSERT文でハッシュ化されたパスワードを直接いれててどうやってハッシュ化したものを確認したのかわからないといった状況です。

追記 ハッシュ化したパスワードを確認しようとアプリケーションのmainメソッドを以下のように変更したところアプリケーションを起動するたび表示されるハッシュ値がかわってしまいました。何が原因なんでしょうか
追記2 どうやらbcryptを使うと同じパスワードでもハッシュ値が毎回変わるようです。どうしたらパスワードをハッシュ化したものを表示しINSERTでDBにいれることができるのでしょうか?
追記3 アプリケーション起動→ハッシュ値確認→アプリケーション終了→DBにかくにんしたハッシュ値を登録→mainメソッドからハッシュ値生成に関係するメソッドを除去→アプリケーション起動でもなぜかエラーが発生してしまいました。

Spring Security
PostgreSQL

WebSecurityConfig.java

package mrs; import org.springframework.beans.factory.annotation.Autowired; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import mrs.domain.service.user.ReservationUserDetailsService; @Configuration //Spring Securityのweb連携機能を有効にする @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired ReservationUserDetailsService userDetailsService; @Bean PasswordEncoder passwordEncoder() { //パスワードのエンコードアルゴリズムとしてBCryptを使用したBCryptPasswordEncoderを有効にする return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http)throws Exception{ http.authorizeRequests() //js以下と/css以下へのアクセスは常に許可 .antMatchers("/js/**","/css/**").permitAll() //それ以外のアクセスは認証を要求(authenticated)する .antMatchers("/**").authenticated() .and() .formLogin() //ログインフォームのパス .loginPage("/loginForm") //認証処理のパス .loginProcessingUrl("/login") .usernameParameter("username") .passwordParameter("password") //認証成功時の飛び先 .defaultSuccessUrl("/rooms",true) //失敗時の遷移先へのアクセス許可 .failureUrl("/loginForm?error=true").permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } }

data.sql

一部抜粋 INSERT INTO usr (user_id,first_name,last_name,password,role_name) VALUES ('aaaa','Aaa','Aaa','/*ここにハッシュ化したパスワードをいれたい*/','USER');

MrsApplication.java

package mrs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @SpringBootApplication public class MrsApplication{ public static void main(String[] args) { SpringApplication.run(MrsApplication.class, args); BCryptPasswordEncoder a =new BCryptPasswordEncoder(); String p = "demo"; String d = a.encode(p); System.out.println(d); } }

###loginForm.html(ログイン画面)

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title></title> </head> <body> <h3>ログインフォーム</h3> <p th:if="${param.error}"> Error! </p> <form th:action="@{/login}" method="POST"> <table> <tr> <td><label for="username">User:</label></td> <td><input type="text" id="username" name="username" value="aaaa"/></td> </tr> <tr> <td><label for="password">Password:</label></td> <td><input type="password" id="password" name ="password" value="demo"/></td> <tr> <td>&nbsp;</td> <td><button type="submit">ログイン</button></td> </tr> </table> </form> </body> </html>

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

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

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

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

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

guest

回答1

0

ベストアンサー

目的:BCryptPasswordEncorderを使用してパスワードをハッシュ化したい

回答者はSpringFrameworkは全く触ったことが無く、Javaもほんの触りしか触ったことが無いのでふわっとした回答になっています。

端的に言うと、
BCryptPasswordEncoder.encode()
を使用してください。
参考

エスパーですが使われている書籍は
[Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
By 株式会社NTTデータ](https://books.google.co.jp/books?id=7TesDAAAQBAJ&pg=PA683&lpg=PA683&dq=//%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%81%97%E3%81%A6BCrypt%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9FBCryptPasswordEncoder%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B&source=bl&ots=_WuxGYlYah&sig=ACfU3U2WgYwiIXqmxk8O65mshjbvbalB0w&hl=en&sa=X&ved=2ahUKEwiOpbv0lsriAhW0L6YKHUp0AMwQ6AEwAXoECAkQAQ#v=onepage&q=PasswordEncoder.encode(&f=false)

だと思うので、今読んでいるページより前のページで
passwordEncoder.encode(rawPassword)`を実行しているところ、使い方を説明しているところがあるはずなのでその辺りを読むと使い方がわかると思います。

以下、質問編集前の回答

同じアルゴリズムと同じパスワードで作ったハッシュ値をSELECT文のWHERE句の条件として指定して、想定するレコードが取得出来ればハッシュ値が正しく(少なくとも指定したアルゴリズムで)格納されていることが確認できます。

本の通りに進めているのですが本ではINSERT文でハッシュ化されたパスワードを直接いれててどうやってハッシュ化したものを確認したのかわからないといった状況です。

確認する について、どのような形をイメージされているのかがわかりませんが、
おそらくデータベースの中身を直接参照して確認するような事をイメージされているのかなと想像します。

ハッシュ値は不可逆なのでその様なアプローチは難しいです。

参考にされている書籍でもログインのあたりで扱っていると思われるので、確認してみてください。

投稿2019/06/02 03:25

編集2019/06/02 06:55
tanat

総合スコア18713

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

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

jampack

2019/06/02 04:12

回答ありがとうございます。おそらく自分はもっと根本的なことがわかっていないんです。ハッシュ化の仕方がわからないのです。 demoというパスワードのハッシュ値が1234だとしたら本当に1234なの?ではなくその1234ってどうやって知ったの?という感じです
gentaro

2019/06/02 05:29

ハッシュ化の方法がわからない、という意味ですか? であれば、質問内容をそのように変更された方が良いと思います。 「ハッシュ化したものを確認」という表現は、「すでにハッシュ化ができている」と受け取られます。
jampack

2019/06/02 06:02 編集

たしかに誤解を与える書き方でしたので修正しました。
jampack

2019/06/02 10:20 編集

本はそれであってますw ハッシュ化の方法を理解したのでそれを利用しハッシュ値を表示させようとしたら毎回表示が変わってしまうようになりました。 Javaはあまり詳しくないとのことでしたので自分で解決しようとしたのですが結局解決できず返信がおくれてしまいました。すいません。また、本内でpasswordEncoder.encode(rawPassword)を実行しているページは見つけられなかった(見落としてるかもしれません)ので具体的な表示方法は知ることができませんでした。
退会済みユーザー

退会済みユーザー

2019/06/02 10:46

その本「入門書」じゃなく「活用書」なんで初歩的な技術はそれなりに省いてるよ
jampack

2019/06/02 11:03

ですよね。買ってしまったのでとりあえずアプリケーション開発の部分だけ進めています。あとすこしで終わるのでここであきらめたくはないです。
tanat

2019/06/02 11:06

> asahina1979さん あー、なるほど。 補足ありがとうございます
tanat

2019/06/02 11:22

> 本はそれであってますw 活用書ということであれば、レファレンス(回答の最初のリンク)は読めるくらいの読者を想定している気がしますね。 > ハッシュ化の方法を理解したのでそれを利用しハッシュ値を表示させようとしたら毎回表示が変わってしまうようになりました。 どの様に実行したのかのコードを質問に追記してもらえれば、 そのものズバリな回答が得られるかと思いますよ。 同じ引数を与えているつもりが、実はそうなってないとか、第二引数まで与える形になってるとか? まずは固定値をrawpasswordとして与えてみて動きを確認してみてはいかがでしょうか。 https://qiita.com/NagaokaKenichi/items/2742749a93df15b55d24 でやっているような形で固定値での動作を確認出来るかと思います。 > 本内でpasswordEncoder.encode(rawPassword)を実行しているページは見つけられなかった 回答のリンクで検索結果を示していますが、P13,28,43,44,45あたりに出ていませんか?
退会済みユーザー

退会済みユーザー

2019/06/02 11:35

まあ作者もこういってるからなww 槙:初心者が最初から読み進めるとむしろ理解しにくいと思うので(笑)、「Chapter13 Spring Boot」や「Chapter14 チュートリアル」から始めて、動くものを味わってから、そのあと中身を知るために最初から読んでみるのがいいと思います。 https://codezine.jp/article/detail/9552
jampack

2019/06/02 11:45

あ、すいません本のリンクは見てませんでした。確認してみます
jampack

2019/06/02 12:28

NoOpPasswordEncoderを試してみた結果→使用すべきでないと斜線がでる→無視して続行ログインファーム送信後エラー(結果変わらず) リンク先のページを読みましたが表示という感じでなく直接DBに入れる感じで、まぁできるんだろうなといった感じです。本来のINSERT文でのダミーユーザー生成での動作確認とは違うなという風に思いました。
退会済みユーザー

退会済みユーザー

2019/06/02 13:09

NoOpPasswordEncoder 平文用のだったかな。 パスワードを暗号化せずに保存すべき観点から非推奨になってたはずだけどね
tanat

2019/06/02 14:45

色々検証しようとしているのに、質問には反映出来ていないため勿体無いというか追加の回答を非常にしずらい状態になっています。 ハッシュ値の出力の仕方自体は把握出来ている様に思います。 後はその値を出力するかDBに格納するかの違いであって、 >リンク先のページを読みましたが表示という感じでなく直接DBに入れる感じで、 という感想は何か勘違いしているか、わからない箇所が増えているかだと思います。 > BCryptPasswordEncorderを使用してパスワードをハッシュ化したい というのはどこからどこまでが範囲だと想像されていますか? 質問内容そのままであれば、 質問に追記されたコードで解決しているように思います。 コードでは固定値をハッシュ化していますが、stringな変数を渡してやれば変数でも使用可能なコードになります。 現状は 1. 「固定値をハッシュ化することは出来るが、[コードでは固定値をハッシュ化していますが、stringな変数を渡してやれば変数でも使用可能なコードになります]という意味ががわからない」(Javaの文法やSpringのオブジェクトの扱いの問題) 2. 「フォームから入力されたパスワードをハッシュ化したい(固定値や変数をハッシュ化することは出来るがフォームからの入力値の受け取り方がわからない)」 3. 「フォームから入力されたパスワードをハッシュ化してDBに登録したい(フォーうから入力されたパスワードをハッシュ化することは出来るがDBに登録することが出来ない)」 4. 「フォームから入力されたパスワードをハッシュ化してDBに登録した後、認証に使用してログインさせたい(DBに登録するところまでは出来ている)」 のうちどこがわからないのか質問文からは読み取れない状態です。 1以外であれば質問内容が当初から変わってしまっている(様に見える)ので、 teratailのルール上&回答者が回答しやすい様にこの質問はクローズしたうえで、 > 追記3 アプリケーション起動→ハッシュ値確認→アプリケーション終了→DBにかくにんしたハッシュ値を登録→mainメソッドからハッシュ値生成に関係するメソッドを除去→アプリケーション起動でもなぜかエラーが発生してしまいました。 について、それぞれのフェーズで何をどう確認しようとしてどの様なコードを書いたか、どの様なエラーが出たのか(エラー文の原文)を全て書く形で新しく質問を作る方が良いかと思いますよ。
jampack

2019/06/03 00:45 編集

追記したコードでハッシュ化をし、コンソール画面でdemoのハッシュ値を目でみえるようにしました。そのハッシュ値をコピーしdata.sqlのINSERT文のコメント部にそのハッシュ値をいれました。これでログイン画面に行きdemoというパスワードでログインしようとすると結果変わらずエラーという状況です。エラーというのはログイン画面上でのエラーということです。コンソール画面にはエラー文はありませんでした。
jampack

2019/06/03 01:17

追記3ではログイン画面でエラーをもらったのはまだmainメソッドにハッシュ値生成のメソッドを残していたのでdemoのハッシュ値が上書きされてしまったのかと考えてもう一度data.sqlのINSERTに新たに表示されたハッシュ値を入れてmainメソッドからハッシュ値生成のメソッドに関係するものをすべて消してログインの処理ができるかどうか確かめたかったのです。(結果は変わらずログイン画面でエラーでした)
jampack

2019/06/03 03:20

もしかしたらハッシュ化ができていないという問題ではないのかもしれないので別で質問をしました。そちらで問題が見つかるようでしたらこちらの質問も解決済みとします。
jampack

2019/06/03 06:14

その値を出力するかDBに格納するかの違いというところがわからなくて出力(コンソールに目で見える形でハッシュ値を表示)はできるようになりました。ですが実際にそのハッシュ値をINSERT文にいれてログイン処理をするとコンソール画面にempty encoded password というのが表示されログイン処理の結果がパスワードが間違っている時と同じ結果になってしまいます。 リンク先のページを読みましたが表示という感じでなく直接DBに入れる感じというのはユーザーの登録処理を通してDBにユーザーを直接登録するやり方が検索に引っかかっていたのでそうではなく、ユーザーの登録処理を経由しないでハッシュ値を表示させ、INSERT文でハッシュ化されたパスワードいれたいということを伝えようとしてました。 現状 demoのハッシュ値は見えるようになったがINSERT文にそのハッシュ値をいれてもログイン処理ができない ハッシュ値さえわかればINSERT文でハッシュ化されたパスワードをいれることができ、ログイン処理ができるようになると思っていたのですが実際はハッシュ値がわかってもログイン処理ができないので題とは少しずれたことになってしまっています。ですのでもしこの問題の解決方法がわからないようでしたら題とはずれてしまっているので解決済みとします。
gentaro

2019/06/03 06:28

INSERT文にハッシュ値を入れる、というのは、そのパスワード(のハッシュ)を登録するということですよね。 パスワード(のハッシュ)はDBにちゃんと登録できているけど、ログインの処理ができない、ということであれば、フレームワークの使い方の問題のような気がしますが。 フレームワーク関係なく、DBからそのハッシュをSELECTして、平文パスワードを再度ハッシュ化したものと比較するとちゃんと一致しますよね?
jampack

2019/06/03 06:51 編集

すいません。DBからそのハッシュをSELECTして、平文パスワードを再度ハッシュ化したものと比較するやり方がわかりません。ハッシュ化されたパスワードと生パスワードを比較する方法はリンクで教えていただいたので旧ハッシュ化パスワードと生パスワードを比較したところ一致しました。 >INSERT文にハッシュ値を入れる、というのは、そのパスワード(のハッシュ)を登録するということですよね。 その通りです。 本ではハッシュ化されたパスワードをそのまま登録していたのでハッシュ値をいれればログイン処理ができると思ってました。唯一本と違うのはfindOne()が使えなくなったのでfindById().orElse(null)に変えたということです。コードについては私の別の質問を見ていただけるとわかります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問