-
Spring Security JWT - JWT를 위한 로그인 시도Framework & Library/Spring Security 2021. 10. 8. 17:34
Repository 생성
public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username); }
ㆍ repository 패키지를 만들고 위 코드와 같이 UserRepository 인터페이스를 생성한다.
ㆍ 사용자의 username을 통해 User 객체를 반환하는 findByUsername() 메서드를 작성해준다.
PrincipalDetails 클래스 생성
public class PrincipalDetails implements UserDetails { private User user; public PrincipalDetails(User user) { this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> authorities = new ArrayList<>(); user.getRoleList().forEach(role -> { authorities.add(() -> role); }); return authorities; } @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; } }
ㆍ config 패키지에 auth 패키지를 만들고 PrincipalDetails 클래스를 생성한다.
ㆍ PrincipalDetails 클래스는 UserDetails 인터페이스를 구현하는 형태여야 한다.
ㆍ PrincipalDetails 클래스는 로그인을 수행한 사용자에 대한 다양한 처리가 가능한 클래스이다.
PrincipalDetailsService 클래스 생성
@Service @RequiredArgsConstructor public class PrincipalDetailsService implements UserDetailsService { private final UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("PrincipalDetailsService 실행"); User userEntity = userRepository.findByUsername(username); return new PrincipalDetails(userEntity); } }
ㆍ auth 패키지 내에 PrincipalDetailsService 클래스를 생성한다.
ㆍ /login 요청 시 loadUserByUsername() 메서드가 자동으로 실행되며, PrincipalDetails 객체를 반환한다.
ㆍ 하지만 SecurityConfig 클래스에서 .formLogin().disable() 메서드를 통해 폼 로그인 미사용 설정을 했기 때문에 정상적으로 loadUserByUsername() 메서드가 실행되지 않는다.
ㆍ loadUserByUsername() 메서드가 정상적으로 실행되기 위해서는 별도의 설정이 필요하다.
JwtAuthenticationFilter 클래스 생성
@RequiredArgsConstructor public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; @Override /** /login 요청을 하면 로그인 시도를 위해서 실행되는 함수 */ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("JwtAuthenticationFilter 로그인 시도 중"); return super.attemptAuthentication(request, response); } }
ㆍ config 패키지에 jwt 패키지를 만들고 JwtAuthenticationFilter 클래스를 생성한다.
ㆍ JwtAuthenticationFilter 클래스는 앞서 말했던 loadUserByUsername() 메서드 호출의 문제점을 해결하기 위해 필요한 클래스이다.
ㆍ JwtAuthenticationFilter 클래스는 UsernamePasswordAuthenticationFilter 클래스를 상속받는 형태이며, attemptAuthentication() 메서드를 오버라이딩 하고 있는 형태이다.
ㆍ attemptAuthentication() 메서드는 /login 요청이 오면 로그인 시도를 위해 자동으로 실행되는 메서드이다.
시큐리티 필터 등록
ㆍ JwtAuthenticationFilter 클래스를 시큐리티 필터에 등록을 해야 정상적으로 작동이 가능하다.
ㆍ 따라서, 위 사진에 표시된 코드를 통하여 JwtAuthenticationFilter 클래스를 시큐리티 필터에 등록한다.
테스트
로그인 요청
ㆍ 테스트는 Postman을 통해서 진행하였다.
ㆍ body의 username의 값을 "qlsdud0604"로 password의 값을 "1234"로 지정한 후 "http://localhost:8080/login" url로 POST 방식의 요청을 보낸다.
콘솔 창 확인
ㆍ 콘솔 창에 "JwtAuthenticationFilter 로그인 시도 중"이라는 메시지가 출력되고 있음을 확인해 볼 때 JwtAuthenticationFilter 클래스가 시큐리티 필터에 잘 등록되었음을 알 수 있다.
728x90'Framework & Library > Spring Security' 카테고리의 다른 글
Spring Security JWT - 로그인 인증 (0) 2021.10.09 Spring Security JWT - 회원가입 (0) 2021.10.09 Spring Security JWT - 임시 토큰을 통한 테스트 (0) 2021.10.08 Spring Security JWT - Filter 등록 (0) 2021.10.08 Spring Security JWT - 시큐리티 설정 (0) 2021.10.07