春のセキュリティのパスワードハッシングの例

このチュートリアルでは、 `BCryptPasswordEncoder`を使用してパスワードをハッシュし、Spring Securityでログイン認証を実行する方法を説明します。

昔、通常、パスワードをエンコードするためにMD5の Md5PasswordEncoder`やSHAの ShaPasswordEncoder`ハッシュアルゴリズムを使用しました…​あなたはどんなエンコーダでも使用できますが、http://en.wikipediaを使用することをお勧めします.org/wiki/Bcrypt[BCrypt]`BCryptPasswordEncoder`は、ランダムに生成されたsaltを持つ強力なハッシングアルゴリズムです。

使用される技術:

  1. Spring 3.2.8.RELEASE

  2. 春のセキュリティ3.2.3.RELEASE

  3. Spring JDBC 3.2.3.RELEASE

  4. MySQLサーバ5.6

1. PasswordEncoderを見直す

使い慣れた古い認証の `PasswordEncoder`インターフェースは廃止されました…​

package org.springframework.security.authentication.encoding;
//Implementation : Md5PasswordEncoder and ShaPasswordEncoder
@Deprecated
public interface PasswordEncoder {

代わりに、この新しい暗号 "PasswordEncoder"インタフェースを使用する必要があります。

package org.springframework.security.crypto.password;
//Implementation : BCryptPasswordEncoder
public interface PasswordEncoder {

2. BCryptパスワードを生成する

まず、パスワードをハッシュしてデータベースに入れ、後でログイン認証を行います。この例では、 `` BCryptPasswordEncoder`を使用してパスワード "123456"をハッシュします。

PasswordEncoderGenerator.java

package com.mkyong.web.controller;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordEncoderGenerator {

  public static void main(String[]args) {

    int i = 0;
    while (i < 10) {
        String password = "123456";
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String hashedPassword = passwordEncoder.encode(password);

        System.out.println(hashedPassword);
        i++;
    }

  }
}

BCryptハッシュアルゴリズムでは、毎回長さ60の異なるハッシュ値が生成されます。

$2a$10$EblZqNptyYvcLm/VwDCVAuBjzZOI7khzdyGPBr08PpIi0na624b8.
$2a$10$trT3.R/Nfey62eczbKEnueTcIbJXW.u1ffAo/XfyLpofwNDbEB86O
$2a$10$teJrCEnsxNT49ZpXU7n22O27aCGbVYYe/RG6/XxdWPJbOLZubLIi2
$2a$10$BHG59UT6p7bgT6U2fQ/9wOyTIdejh4Rk1vWilvl4b6ysNPdhnViUS
$2a$10$W9oRWeFmOT0bByL5fmAceucetmEYFg2yzq3e50mcu.CO7rUDb/poG
$2a$10$HApapHvDStTEwjjneMCvxuqUKVyycXZRfXMwjU0rRmaWMsjWQp/Zu
$2a$10$GYCkBzp2NlpGS/qjp5f6NOWHeF56ENAlHNuSssSJpE1MMYJevHBWO
$2a$10$gwbTCaIR/qE1uYhvEY6GG.bNDQcZuYQX9tkVwaK/aD7ZLPptC.7QC
$2a$10$5uKS72xK2ArGDgb2CwjYnOzQcOmB7CPxK6fz2MGcDBM9vJ4rUql36
$2a$10$6TajU85/gVrGUm5fv5Z8beVF37rlENohyLk3BEpZJFi6Av9JNkw9O

塩がランダムに生成されるため、BCryptで値をハッシュするたびに異なる値を取得するのは正常です。このチュートリアルでは、最初の出力を取得してデータベースに挿入します。

3.データベース

テスト用にテーブルを作成し、ユーザ「mkyong」を挿入します。

CREATE  TABLE users (
  username VARCHAR(45) NOT NULL ,
  password VARCHAR(60) NOT NULL ,
  enabled TINYINT NOT NULL DEFAULT 1 ,
  PRIMARY KEY (username));

CREATE TABLE user__roles (
  user__role__id int(11) NOT NULL AUTO__INCREMENT,
  username varchar(45) NOT NULL,
  role varchar(45) NOT NULL,
  PRIMARY KEY (user__role__id),
  UNIQUE KEY uni__username__role (role,username),
  KEY fk__username__idx (username),
  CONSTRAINT fk__username FOREIGN KEY (username) REFERENCES users (username));

INSERT INTO users(username,password,enabled)
VALUES ('mkyong','$2a$10$EblZqNptyYvcLm/VwDCVAuBjzZOI7khzdyGPBr08PpIi0na624b8.', true);

INSERT INTO user__roles (username, role)
VALUES ('mkyong', 'ROLE__USER');
INSERT INTO user__roles (username, role)
VALUES ('mkyong', 'ROLE__ADMIN');

4.パスワードエンコーダを有効にする

XMLエンコーディングでパスワードエンコーダを有効にするには、いくつかの方法があります。

4.1デフォルトの BCryptPasswordEncoder の使用。

spring-security.xml

  <authentication-manager>
    <authentication-provider>
        <password-encoder hash="bcrypt"/>
    </authentication-provider>
  </authentication-manager>

4.2 "strength"パラメータを BCryptPasswordEncoder に渡す。

spring-security.xml

  <authentication-manager>
    <authentication-provider>
        <password-encoder ref="encoder"/>
    </authentication-provider>
  </authentication-manager>

  <beans:bean id="encoder"
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="11"/>
  </beans:bean>

4.3エンコーダを DaoAuthenticationProvider に渡す。

spring-security.xml

  <bean id="authProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="customUserService"/>
    <property name="passwordEncoder" ref="encoder"/>
  </bean>

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

4.4注釈の例。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth)
        throws Exception {

        auth.jdbcAuthentication().dataSource(dataSource)
            .passwordEncoder(passwordEncoder())
            .usersByUsernameQuery("sql...")
            .authoritiesByUsernameQuery("sql...");
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

5.プロジェクトデモ

パスワードで保護されたページにアクセスする:

localhost:8080/spring-security-password-hashing/admin 、ログインページが表示されます。パスワード "123456"を入力すると、Spring Securityはパスワードをハッシュし、データベースのハッシュパスワードと比較します。

spring-security-password-encoder、width = 527、height = 480

データベース内のユーザーとパスワード。

spring-security-password-encoder-database、width = 640、height = 311

ソースコードをダウンロードする

ダウンロード: spring-security-password-hashing.zip (18 KB)