How to Use custom tables for Authentication

김가빈·2023년 7월 28일
0

springsecurity

목록 보기
6/23

problem

  • in JdbcUserDetailsManager have their one quries for authentication, so we need to make table match to this form
  • BUT sometimes you want to add other column in your table(for example, email) or you want to your own column name for table.
  • so, we will make our custom tables for authentication

create table

CREATE TABLE `customer` (
  `id` int NOT NULL AUTO_INCREMENT,
  `email` varchar(45) NOT NULL,
  `pwd` varchar(200) NOT NULL,
  `role` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
  
 INSERT INTO `customer` (`email`, `pwd`, `role`)
 VALUES ('johndoe@example.com', '54321', 'admin')

create entity class

  • create new package com.eazybytes.model
  • create entity class match to table
package com.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;


@Entity
public class Customer {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	private String email;
	private String pwd;
	private String role;
	
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
	
}

create repository

  • create new package com.eazybytes.repository
  • and make interface match to entity

add annotation

  • mentioning @EnableJpaRepositories @EntityScan is optional

  • @EnableWebSecurity annotaion optional to Spring Boot BUT it esstential to Spring Project without boot for using spring security method


implements UserDetailsService

  • create class which implements UserDetailsService

package com.eazybytes.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 com.eazybytes.model.Customer;
import com.eazybytes.repository.CustomerRepository;

@Service
public class EazyBankUserDetails implements UserDetailsService {

	@Autowired
	CustomerRepository customerRepository;
	
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		String userName = null;
		String password = null;
		
		List<GrantedAuthority> authorities = null;
		List<Customer> customer = customerRepository.findByEmail(username);
		
		if(customer.size() == 0) {
			throw new UsernameNotFoundException("User details not found for the user : " + username);
		} else {
			userName = customer.get(0).getEmail();
			password = customer.get(0).getPwd();
			authorities = new ArrayList<>();
			authorities.add(new SimpleGrantedAuthority(customer.get(0).getRole()));
		}
		return new User(username, password, authorities);
	}

}

  • if you return user object spring security stored that authentication in the storage

remove JdbcUserDetailsManager

  • we need to remove JdbcUserDetailsManager because you make your own custom userdetailsService

login

  • try login in custom db and match to security db

  • you can sign in your own table rows data


why I use this logic

  • because I just want to override loadUserByUsername for authentication
  • I don't need to override other JPA crud quries
  • forexample, I still can use this crud quries

  • create login controller
package com.eazybytes.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.eazybytes.model.Customer;
import com.eazybytes.repository.CustomerRepository;

@RestController
public class LoginController {

	@Autowired
	CustomerRepository customerRepository;
	

	@PostMapping("/register")
	public ResponseEntity<String> registerUser(@RequestBody Customer customer) {
		Customer savedCustomer = null;
		ResponseEntity response = null;
		
		try {
			savedCustomer = customerRepository.save(customer);
			if(savedCustomer.getId() > 0) {
				response = ResponseEntity
								.status(HttpStatus.CREATED)
								.body("Given user details are successfully registered");
			}
		} catch (Exception e) {
			response = ResponseEntity
							.status(HttpStatus.INTERNAL_SERVER_ERROR)
							.body("An exception occured due to " + e.getMessage());
		}
		
		return response;
	}
}

Insert user in to custom table

  • you will need to

    • add content-type application/json

    • change entity annotation(because @GeneratedValue not match with table)

    • regist url into securityConfig

    • then you will meet 401 error because of csrf

    • temporary block csrf


  • then you can enter your own user in custom db

profile
신입 웹개발자입니다.

0개의 댓글