LoginSignup
4
3

More than 1 year has passed since last update.

Spring Security でデータベースを参照して認証を行う(できるだけ少ない手数で)

Posted at

概要

手順

  1. ビルドスクリプトに Spring Security と JPA を追加

    build.gradle
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    
  2. 以下のconfigクラスを新規作成

    package com.example.demo.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.SecurityFilterChain;
    
    @EnableWebSecurity
    public class SecurityConfig2 {
    
    	@Bean
    	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    		http.authorizeRequests()
    				.anyRequest().authenticated()
    				.and()
    				.formLogin()
    				.defaultSuccessUrl("/success");
    		return http.build();
    	}
    
    	@Bean
    	public PasswordEncoder passwordEncoder() {
    		return new BCryptPasswordEncoder();
    	}
    }
    
  3. 認証情報を持つテーブルに対応したエンティティクラスを用意

    @Entity
    @Table(name = "account")
    public class Account {
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	@Column(name = "id")
    	private int id;
    
    	@Column(name = "user_name")
    	private String userName;
    
    	@Column(name = "password")
    	private String password;
    
        // setter, getter 省略
    }
    
    1. を取得する Repository クラスを定義
    @Repository
    public interface AccountRepository extends JpaRepository<Account, Integer> {
    
    	Account findByUserName(String userName);
    }
    
  4. 認証に使うユーザ情報を取得するサービスを定義

    package com.example.demo.security;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    
    import java.util.Collections;
    
    @Service
    public class AccountUserDetailsService implements UserDetailsService {
    
    	private final AccountRepository accountRepository;
    
    	@Autowired
    	public AccountUserDetailsService(AccountRepository accountRepository) {
    		this.accountRepository = accountRepository;
    	}
    
    	@Override
    	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    		Account account = accountRepository.findByUserName(userName);
    		return new User(account.getUserName(), account.getPassword(), Collections.emptyList());
    	}
    }
    
  5. テストクラスなどでハッシュ化したパスワードを取得

    @SpringBootTest
    public class PasswordTest {
    
    	@Autowired
    	private PasswordEncoder encoder;
    
    	@Test
    	public void encode() {
    		System.out.println(encoder.encode("pass"));
    		System.out.println(encoder.encode("password"));
    	}
    }
    
    実行結果例
    $2a$10$T7dckfpU4EC0nKxEKKYukeTa1ZXGBtKc5ZrEFfVNZ/CGoYmUDRE3e
    $2a$10$hCZ9AJeq20LpMk.wRHJf0eUdHABHatUp2Tnb8uqe8J3/ZuJ4njun.
    
  6. ハッシュ化したパスワードを使ってデータベースに登録

  • H2 を使った例
    schema.sql
    CREATE TABLE IF NOT EXISTS account (
      id        INTEGER         NOT NULL AUTO_INCREMENT,
      user_name VARCHAR(128)    NOT NULL,
      password   VARCHAR(512)    NOT NULL,
      PRIMARY KEY (id)
    );
    
    data.sql
    INSERT INTO account (user_name, password) VALUES('user1', '$2a$10$T7dckfpU4EC0nKxEKKYukeTa1ZXGBtKc5ZrEFfVNZ/CGoYmUDRE3e');
    INSERT INTO account (user_name, password) VALUES('user2', '$2a$10$hCZ9AJeq20LpMk.wRHJf0eUdHABHatUp2Tnb8uqe8J3/ZuJ4njun.');
    
  1. アプリケーションを起動して、適当なページにアクセスする
  2. ログインページが表示されるので、user1 pass などで認証する
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3