Java/spring

spring security를 알아보자 - 6

티코딩 2024. 3. 25. 15:02

Jpa를 사용해보자.

  Customer 엔티티와, CustomerRepository를 만들어주자.

CustomerRepository는 CrudRepository를 extends한다.

@Repository
public interface CustomerRepository extends CrudRepository<Customer, Long> {

}

<Customer, Long> 에서 Customer는 어느테이블에 속하는 리포지토리인지, Long은 PrimaryKey의 타입을 적어준것이다.

 

그리고 레포지토리나 엔티티가 메인 애플리케이션 밖에 존재한다면 @EnableJpaRepositories, @EntityScan를 붙혀준다.

하지만 나는 안에 존재하기때문에 알아서 적용된다.

 

 이제 loadUserByUsername을 사용하기위해 UserDetailsService를 implements하는 BankUserDetails를 만들어보자.

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String userName, password;
        List<GrantedAuthority> authorities;
        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);
    }

로직은 이렇게 만들었다.

 

이클래스는 비지니스로직이 있어 service layer로서 기능을하므로 클래스위에 @Service 를 붙혀줬다.

Spring security는 인증을 진핼할때마다 인증요청을 DaoAuthenticationProvider에게 전달하고 우리가 구현한 UserDetailsService를 찾을것이다. 우리가 만든건 위의 BankUserDetails 와 SecurityConfig의 userDetailsService 이다.

@Bean
    public UserDetailsService userDetailsService(DataSource dataSource) {
        return new JdbcUserDetailsManager(dataSource);
    }

UserDetailsService를 구현이 두개나있어서 충돌이 발생한다. 위의 userDetailsService를 주석처리해주자.

 

이전까지 SQL 스크립트를 사용해 데이터베이스에 직접 입력했다. 이것은 일반적이지않고 추천하지않음. 유저가 자격정보를 직접 입력해서 등록해야 한다. 어떻게할까?

 

방법 1

UserDetailsService가 아닌 UserDetailsManager를 구현한다.

 

 

 

방법2

LoginController를 만든다.

@RestController
public class LoginController {

    @Autowired
    private 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 ex) {
            response = ResponseEntity
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("An exception occured due to " + ex.getMessage());
        }
        return response;
    }

}

 

포스트맨에서 /register를 테스트해보면 잘 등록되었고, db에서 검색해보면 새로만든 계정이 잘 생성되있는걸 볼 수 있다.