spring security를 알아보자 - 6
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에서 검색해보면 새로만든 계정이 잘 생성되있는걸 볼 수 있다.