1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Spring SecurityでDB認証&BCryptでハッシュ化

Last updated at Posted at 2020-03-15

概要

  • Spring Securityで必要最低限のログイン機能を実装する。(権限周りは触れません。)
  • ログインフォームなどはSpring Securityで用意されているものを使う。
  • 仕組みはあまり理解できていないので、また別でまとめます。
  • この投稿はとりあえず、動くようになったというところまで!

開発環境

  • OS:Windows10
  • IDE:eclipse 2019-12
  • Java:13
  • Spring boot:2.2.5(Gradle)
  • DB:Oracle 12c

Spring Securityの導入

依存関係で下記の4つを選択

  • Spring Security
  • Spring Web
  • Spring Data JPA
  • Oracle Driver ←使用するDBのDriverを選択してください
    2020-03-15-14-06-34.png

DB接続情報をプロパティファイルに記述

  • それぞれのDBに合った内容にしてください。
application.properties
spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/[データベース名]
spring.datasource.username=[DBユーザー名]
spring.datasource.password=[パスワード]
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver

ユーザー情報のテーブルを作成

create table USER_TABLE (
    USER_ID VARCHAR2(30 char)
  , FAMILY_NAME VARCHAR2(10 char) not null
  , FIRST_NAME VARCHAR2(10 char) not null
  , PASSWORD VARCHAR2(255) not null
  , constraint USER_TABLE_PKC primary key (USER_ID)
) ;

データ登録

下記のパスワードは「pass」をハッシュ化したものです。
この記事を参考にしました。

INSERT INTO
    USER_TABLE
VALUES(
    '0001'
   ,'テスト'
   ,'太郎'
   ,'$2a$10$w0C4tFU.SLFATC1Y6Y4uy.vMYsLXhlfvgnFP4dLbRjEa6/Ag1csKS'
   );

Entityクラスを作成

UserTable.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "USER_TABLE")
public class UserTable {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "USER_ID")
	private String userId;

	@Column(name = "FAMILY_NAME")
	private String familyName;

	@Column(name = "FIRST_NAME")
	private String firstName;

	@Column(name = "PASSWORD")
	private String password;

// Getter,Setterは省略


リポジトリを作成

UserTableRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.azkz.entity.UserTable;

@Repository
public interface UserTableRepository extends JpaRepository<UserTable, String> {

	public UserTable findByUserId(String userId);

}

SecurityConfigを作成

DemoSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
@EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter {

	//アクセス可能なURLの制限とログイン成功時の遷移先の指定をするメソッド
	@Override
	protected void configure(HttpSecurity httpSecurity) throws Exception {
		httpSecurity.authorizeRequests()
				.mvcMatchers("/").permitAll() // 「/」は誰でもアクセスできる
				.anyRequest().authenticated() // それ以外はログインが必要
				.and()
				.formLogin()
				.defaultSuccessUrl("/success"); // ログイン成功時には「/success」にGetリクエストをする
	}

	//入力されたパスワードをBCrypt方式でハッシュ化するメソッド
	@Bean
	protected PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
}

UserDetailsServiceを作成

  • DBからユーザ情報を取得し、DemoUserDetailsをインスタンス化する。
DemoUserDetailsService.java
import org.springframework.beans.factory.annotation.Autowired;
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 com.azkz.entity.UserTable;
import com.azkz.repository.UserTableRepository;

@Service
public class DemoUserDetailsService implements UserDetailsService {

	@Autowired
	UserTableRepository userTableRepository;

	@Override
	public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {

		//入力されたUserIDを条件にDBからデータを取得する
		UserTable userTable = userTableRepository.findByUserId(userId);

		// 入力値(ユーザーID、パスワード)とインスタンス化したDemoUserDetailsクラスを
		// SpringSecurityの内部で比較することで、ログインチェックを行っている。
		return new DemoUserDetails(userTable);

	}

}

UserDetailsを作成

  • このクラスが入力情報(ユーザID、パスワード)と比較されることになる(?)
  • ログイン後のセッション情報もこれ
DemoUserDetails.java
import java.util.Collections;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;

import com.azkz.entity.UserTable;

public class DemoUserDetails extends User {

	@Autowired
	UserTable userTable;

	public DemoUserDetails(UserTable userTable) {
		// 「Collections.emptySet()」は本来は権限名のコレクションとなる。今回は空。
		super(userTable.getUserId(), userTable.getPassword(),Collections.emptySet());
		this.userTable = userTable;
	}

	// セッション情報から独自の項目を取得するためのGetter

	public String getFirstName() {
		return this.userTable.getFirstName();
	}

	public String getFamilyName() {
		return this.userTable.getFamilyName();
	}

}

Controllerを作成

  • 成功時にログインユーザの情報を表示する
DemoController.java
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.azkz.security.DemoUserDetails;

@RestController
public class DemoController {

	@GetMapping("/success")
	public DemoUserDetails loginSuccess() {
		// ログイン中のユーザ情報を取得
		DemoUserDetails demoUserDetails =
				(DemoUserDetails) SecurityContextHolder
									.getContext().getAuthentication().getPrincipal();

		return demoUserDetails;
	}
}

画面確認

http://localhost:8080/login にアクセス

2020-03-15-19-24-53.png


ログイン成功

2020-03-15-19-26-25.png


ログイン失敗

2020-03-15-19-28-26.png


終わりに

  • 表面的なことしか書いておりませんが、間違い・不足点等がございましたら、ぜひご教示いただきたく存じます。何卒!
1
6
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
1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?