Spring security + Jwt 를 공부하면서 이해안가는 부분이 많았습니다. 따라서확실하게 JWT에 대해서 이해하고 적용을 하고 싶어 많은 자료를 찾아보고 그것을 이 글에 정리하고자 합니다.
먼저 Spring Security에 대해서 알아보겠습니다.
Web, Mobile 등 대부분의 어플리케이션에서 로그인 기능은 기본적으로 사용되고 있습니다.
Spring Security는 스프링 기반 어플리케이션의 보안(인증,권한,인가)을 담당하는 스프링 하위 프레임워크 입니다.
개발자에게 보안 관련 많은 옵션을 제공해 주기 때문에 편하게 로직을 작성할 수 있도록 해줍니다.
인증(Authentication) -> 인증성공 -> 인가(Authorization)
Spring Security에서는 기본적으로 인증 절차를 거쳐 인증이 성공되면 인가 절차를 진행합니다. 그 뒤에 인가과정에서 접근 권한을 확인합니다.
이러한 인증,인가를 위해 Principal을 ID로, Credentail을 PWD로 사용하는 인증방식을 사용합니다.
기본적으로 인증 정보는 최종적으로 SecurityContextHolder에 세션-쿠키 방식으로 저장됩니다.
다음은 Security Security의 전체적인 동작 과정입니다.
첫번째로 Http Request를 받습니다.
Security에는 일련의 Filter Chain이 있는데, Client로 부터 Request가 오면 인증 및 권한 부여 목적으로 이러한 필터를 거치게 됩니다.
ID,PWD 기반의 인증일 경우 가장 먼저 Application Filters를 거치게 됩니다. 그 중에서 Authentication Filters라는 필터에 도착하고, username/password를 사용하는 form 기반 인증 처리 필터인 UsernamePasswordAuthenticationFilter에 도착하는 것입니다.
UsernamePasswordAuthenticationFilter에 요청이 도착하면 클래스의
attempAuthentication(request,response) 메서드가 동작합니다.
이곳에서는 request로 부터 username,password를 가지고 와서 사용자 자격 증명을 기반으로 한 UsernamePasswordAuthenticationToken(Authentication)을 생성합니다.
UsernamePasswordAuthenticationToken 은 Authentication 인터페이스의 구현체
모든 접근 주체는 Authentication을 생성하고 이것은 최종적으로 SecurityContext에 보관되고 사용
그 뒤 생성된 토큰을 이용하여 AuthenticationManager에게 인증을 진행하도록 위임합니다.
AuthenticationManager는 Interface로, Authentication 객체를 받아 인증을 진행합니다. 인증이 되었다면 인증된 객체를 돌려주는 authenticate() 메서드를 구현하도록 합니다.
ProviderManger는 이러한 AuthenticationManager의 구현체입니다.
실제로 직접 인증 과정을 거치지 않으며 AuthenticationProvider에게 인증을 위임하고 ProviderManager는 인증이 되었다고 알려주는 역할입니다.
AuthenticationProvider에서는 authenticate() 메서드를 통해 인증 과정이 진행됩니다.
UserDetailsService는 DB에서 사용자 인증 정보를 가져오는 역할을 합니다. UserDetilas 객체를 전달 받은 후 실제 사용자의 입력정보와 UserDetails 객체를 가지고 인증을 시도합니다.
인증이 완료되면 사용자 정보를 가진 Authentication 객체를 SecurityContextHolder에 담은 이후 AuthenticationSuccessHandle을 실행합니다.
JWT는 토큰 기반 인증 시스템의 대표적인 구현체입니다.
다음과 같이 .을 기준으로 Header,Payload,Signature로 이루어져 있습니다.
여태까지는 Spring Security 에서의 인증 및 권한 부여에 대해서 알아보았습니다. 기존에 인증 체계는 Cookie, Session으로 이뤄졌습니다.
=> Browser에 저장되어서 사용하는 작은 텍스트 파일로써 접속자 장치를 인식하거나 일부 데이터를 저장하는 역할
쿠키는 사용자의 로그인 정보와 같은 민감한 정보를 포함하고 있어 보안에 좋지 않고, 조작의 가능성, 다른 브라우저간 공유 불가능, 4KB라는 적은 사이즈로 충분한 데이터를 담을 수없다는 단점이 있습니다.
세션은 stateful하기 때문에 Http의 장점을 발휘하지 못한 다는점과, Session 저장소에 문제가 발생하면 인증 체계가 무너지는 점,
사용자가 많아지면 메모리를 많이 차지하고 매번 요청마다 세션 저장소를 조회해야 한다는 단점이 있습니다.
요즘은 웹이 아닌 모바일에서도 사용가능한 장점과 Stateless 한 서버 구현, 안정성을 가진다는 장점으로 JWT를 많이 사용하고 있습니다.
쓰다보니 글이 길어져서 구현부터는 다음 챕터에서 하도록 하겠습니다 :)