1편과 2편은 같이 봐야하니 1편을 보지 않았다면 아래 링크로 가서 보시길 바랍니다.
Entity
- User에 대한 Entity 클래스를 생성 해주어야 함.
- @Data 는 Getter와 Setter를 한번에 생성 시켜주는 어노테이션이다.
- @CreationTimestamp는 생성될 때의 시간을 저장시켜주는 어노테이션이다.
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String email;
private String role;
@CreationTimestamp
private Timestamp createDate;
}
authorize
- Security가 /login 주소 요청이 오면 낚아채서 로그인을 진행시킨
- 로그인 진행이 완교가 되면 Security Session을 만들어줌 (Security ContextHolder)
- 오브젝트 타입은 Authentication 타입의 객체임.
- Authentication 안에 user 정보가 있어야 함.
- User 오브젝트 타입은 UserDetails 타입의 객체임.
- 결론적으로는 Secrity session 값으로 Authentication 타입의 객체를 받고, Authentication값은 UserDetails 타입의 객체를 받음.
UserDetails(PrincipalDetails)
- UserDetails 인터페이스가 가지고 있는 메소드를 구현하는 클래스로 session에 값을 주기 위해 타입 변환 및 User의 상태 권한을 설정 하는 클래스이다.
- Collection<? extends GrantedAuthority> getAuthorities()
- 계정이 가지고 있는 권한을 리턴하는 메소드이다.
public class PrincipalDetails implements UserDetails {
private User user;
public PrincipalDetails(User user) {
this.user =user;
}
// 해당 유저의 권한을 리턴하는 곳
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collect = new ArrayDeque<>();
collect.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return user.getRole();
}
});
return collect;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
// 계정의 사용가능 기간이 만료가 안 되었는지?
@Override
public boolean isAccountNonExpired() {
return true;
}
// 계정이 안 잠겨져 있는지?
@Override
public boolean isAccountNonLocked() {
return true;
}
// 비밀번호 사용가능 기간이 만료가 안 되었는지?
@Override
public boolean isCredentialsNonExpired() {
return true;
}
// 사용이 가능한 계정인지?
@Override
public boolean isEnabled() {
return true;
}
}
UserDetailsService(PrincipalDetailsService)
- Security 설정에서 loginprocessingUrl("login")으로 /login 요청이 오면 자동으로 UserDetailsService 타입으로 IoC되어 있는 loadUserByUsername 메소드가 실행됨.
@Service
public class PrincipalDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
// 매개변수 받는 값이름을 username으로 고정해야 함. 기본값임.
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if(user != null)
return new PrincipalDetails(user);
return null;
}
}
UserReposiroty
- findBy*는 하나의 형식으로 By 이후에 있는 문자를 가진 컬럼에서 해당 내용을 찾아줌.
- username 컬럼에서 매개변수 값을 찾음.
public interface UserRepository extends JpaRepository<User, Integer> {
User findByUsername(String username);
}