2016-12-10 9 views
0

新しいユーザーの登録後、認証されるために入力されたユーザー入力のパスワードと一致しません。生のパスワードは同じですが、ハッシュされたバージョンは異なります。私はどのようにこれらの2つが適切な認証のためにお互いに一致するようになるのだろうか?私は、セキュリティのためにSpring 4.3.2.RELEASEと4.2.0.RELEASEを使用しています。春のセキュリティ - BCryptでユーザー認証がハッシュされたパスワード(不正な資格情報エラー)

また、私は警告を持っている:

WARN SpringSecurityCoreVersion:78 - **** You are advised to use Spring 4.3.4.RELEASE or later with this version. You are running: 4.3.0.RELEASE 

は多分これは、いくつかの方法で問題を引き起こしています。

のconfig.xml:

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> 

<security:authentication-manager> 
    <security:authentication-provider user-service-ref="userService"> 
     <security:password-encoder ref="encoder"/> 
    </security:authentication-provider> 
</security:authentication-manager> 

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
    <property name="userDetailsService" ref="userService" /> 
    <property name="hideUserNotFoundExceptions" value="false" /> 
    <property name="passwordEncoder" ref="encoder" /> 
</bean> 

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager"> 
    <constructor-arg> 
     <ref bean="daoAuthenticationProvider" /> 
    </constructor-arg> 
</bean> 

UserEntity.java:

public void setPassword(String password) { 
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
    this.password = passwordEncoder.encode(password); 
} 

UserAuthenticationProviderService.java:

public boolean processUserAuthentication(UserEntity user) { 

    try { 
     Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword()); 
     Authentication result = authenticationManager.authenticate(request); 
     SecurityContextHolder.getContext().setAuthentication(result); 

     return true; 
    } catch(AuthenticationException e) { 
     FacesContext.getCurrentInstance().addMessage(null, 
       new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Catched Error!")); 

     return false; 
    } 
} 

EDIT:解決しました。

Shaunはエンティティクラスでエンコードが問題であると述べています。エンコーディングをユーザー作成プロセスの場所にのみ表示するため、エンコーディングをユーザー作成場所に移動した後、すべてうまく機能します。ありがとう!

+0

あなたは認証マネージャの名前空間の構成と単純なJava Beanの両方を使用しています。どちらか一方を選択する必要があります。また、あなたの質問はあまり明確ではありません。 「ハッシュバージョンは異なる」とはどういう意味ですか - あなたはどのように知っていますか?あなたは何を比較していますか?データベースの値はbcryptハッシュとして認識できますか?例を掲載し、実際の(テスト)データを使って説明してください。 –

+0

パスワード: "superman"で登録した直後に、パスワードは "$ 2a $ 10 $ lwRt // HRsibkzHQzECHxi.E2hacnQve3JTZkxlrwlvVZ1S0w1DKO6"のようにデータベースに保存されます。しかしその直後に、アプリケーションが自動ログインしようとすると、データベースのパスワードが「$ 2a $ 10 $ 19Z.a2KhDELFMJ55VhxQtOvaZsO0n8q2VLXUqBpxsmHfj3j3NkQjq」に変更され、そのままになります。それは、同じ実行で間違ったパスワードで正しいパスワードを更新するように見えますが、今は原因を知りません。 –

+0

更新:それはそのままではありません。あなたがログインした後に更新しようとしました(まだ更新されていません) –

答えて

0

はい、BCryptEncoderで同じ文字列を2回エンコードした直後に、異なる文字列が表示されることにお気づきでしょう。しかし、Spring Securityでは、equalsに対するマッチングは使用されません。エンコーダを登録すると、SPring SecurityはPasswordEncoderのboolean matches(CharSequence rawPassword, String encodedPassword)を使用します(BCryptEncoderはこのインターフェイスを実装します)。

あなたは詳細についての興味深いしている場合、あなたはその非常に単純bcryptの、の実装を表示することができます

static boolean equalsNoEarlyReturn(String a, String b) { 
     char[] caa = a.toCharArray(); 
     char[] cab = b.toCharArray(); 

     if (caa.length != cab.length) { 
      return false; 
     } 

     byte ret = 0; 
     for (int i = 0; i < caa.length; i++) { 
      ret |= caa[i]^cab[i]; 
     } 
     return ret == 0; 
    } 
+0

答えをありがとう、しかし私はまだ春のセキュリティが一致()関数を使用してこれらのパスワードと一致しない理由を理解できませんエンコーダがsecrypt設定ファイルでBCryptとして定義されている間。 authenticationManager.authenticate()がパスワードにBCryptハッシュが認識されず、それらを生のものとして比較する可能性はありますか? –

+0

@rchtp auth.userDetailsS​​ervice(userDetailsS​​ervice)で明示的に言ったとき、BCryptとして認識します。passwordEncoder(新しいBCryptPasswordEncoder()); BCryptに切り替えたときに何も変更する必要はありませんでした。 – Srikanth

関連する問題