ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 클래스가 시큐리티 필터에 잘 등록되었음을 알 수 있다.


     

    GitHub - qlsdud0604/spring-security-basic: 스프링 시큐리티의 기초를 학습하는 공간

    스프링 시큐리티의 기초를 학습하는 공간. Contribute to qlsdud0604/spring-security-basic development by creating an account on GitHub.

    github.com

     

    728x90

    댓글

Designed by Tistory.