06.DB기반 로그인 검증
인증
- 시큐리티를 통해 인증을 진행하는 방법은
- 사용자가 로그인 페이지를 통해 아이디와 비밀번호를 POST로 요청
- 스프링 시큐리티가 DB에 저장된 회원정보를 조회 후 비밀번호를 검증하고 서버 세션 저장소에 해당 아이디에 대한 세션 저장
- UserRepository로 조회된 UserEntity를 UserDetails에 담아 시큐리티에게 전달한다
UserDetailsService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import com.example.testsecurity.dto.CustomUserDetails;
import com.example.testsecurity.entity.UserEntity;
import com.example.testsecurity.repository.UserRepository;
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;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity userData = userRepository.findByUsername(username);
if (userData != null) {
return new CustomUserDetails(userData);
}
return null;
}
}
- 시큐리티가 이용할 CustomUserDetailsService는 UserDetailsService 인터페이스를 구현한다.
- findByUsername() 역시 개발자의 커스텀 메소드이다.
- findByUsername()를 통해 사용자 정보를 불러와서 userData에 담는다.
- userData가 null 즉, 회원이라면 CustomUserDetails에 userData를 담아 생성하며 인증이 진행이 되고, 아니라면 null을 리턴한다.
UserRepository
1
2
3
4
5
6
7
8
9
import com.example.testsecurity.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<UserEntity, Integer> {
boolean existsByUsername(String username);
UserEntity findByUsername(String username);
}
- findByUsername() 커스텀 메소드
UserDetails
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import com.example.testsecurity.entity.UserEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private UserEntity userEntity;
public CustomUserDetails(UserEntity userEntity) {
this.userEntity = userEntity;
}
// 1번
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return userEntity.getRole();
}
});
return collection;
}
// 2번
@Override
public String getPassword() {
return userEntity.getPassword();
}
// 3번
@Override
public String getUsername() {
return userEntity.getUsername();
}
// 나머지 4번
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
- 1번은 DB에 담긴 사용자의 인가(권한)에 관한 정보를 불러와서 처리하는 메소드
- 2번, 3번은 비밀번호와 아이디를 반환오는 메소드
- 4번의 경우 계정만료, 계정잠금, 비밀번호만료, 사용가능과 같은 것들을 체크하는 메소드이다
- 디비에 만료, 잠금, 사용가능과 같은 정보들이 있다면 그것을 불러와 처리하면 된다.
- true일 경우는 모두 사용가능한 상태이고 false로 세팅하면 사용 불가능하다.
- 현재의 경우 DB에 관련된 컬럼들과 정보가 없기에 강제적으로 true로 세팅하였다.