[Spring Security] 10. JWT 이해2

개발자·2022년 7월 25일
0

Spring Security

목록 보기
10/11
post-thumbnail

Spring security + Jwt 를 공부하면서 이해안가는 부분이 많았습니다. 따라서확실하게 JWT에 대해서 이해하고 적용을 하고 싶어 많은 자료를 찾아보고 그것을 이 글에 정리하고자 합니다.

📌 Spring Security

먼저 Spring Security에 대해서 알아보겠습니다.
Web, Mobile 등 대부분의 어플리케이션에서 로그인 기능은 기본적으로 사용되고 있습니다.
Spring Security는 스프링 기반 어플리케이션의 보안(인증,권한,인가)을 담당하는 스프링 하위 프레임워크 입니다.
개발자에게 보안 관련 많은 옵션을 제공해 주기 때문에 편하게 로직을 작성할 수 있도록 해줍니다.

Spring Security 용어

  • 인증 Authentication : 해당 사용자가 본인이 맞는지 확인한다.
  • 인가 Authorization : 인증된 사용자가 요청한 자원에 접근이 가능한지 확인하는 절차이다.
  • 접근주체 Principal : 보호받는 Resource에 접근하는 대상이다.
  • 비밀번호 Credential : Resource에 접근하는 대상의 비밀번호이다.
  • 권한 : 인증된 주체가 어플리케이션의 동작을 수행할 수 있도록 허락되어 있는지를 결정한다.

절차 및 동작 과정

인증(Authentication) -> 인증성공 -> 인가(Authorization)

Spring Security에서는 기본적으로 인증 절차를 거쳐 인증이 성공되면 인가 절차를 진행합니다. 그 뒤에 인가과정에서 접근 권한을 확인합니다.
이러한 인증,인가를 위해 Principal을 ID로, Credentail을 PWD로 사용하는 인증방식을 사용합니다.

기본적으로 인증 정보는 최종적으로 SecurityContextHolder에 세션-쿠키 방식으로 저장됩니다.

다음은 Security Security의 전체적인 동작 과정입니다.

HTTP 요청 수신

첫번째로 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, AuthenticationProvicer(s), ProviderManager

AuthenticationManager는 Interface로, Authentication 객체를 받아 인증을 진행합니다. 인증이 되었다면 인증된 객체를 돌려주는 authenticate() 메서드를 구현하도록 합니다.

ProviderManger는 이러한 AuthenticationManager의 구현체입니다.
실제로 직접 인증 과정을 거치지 않으며 AuthenticationProvider에게 인증을 위임하고 ProviderManager는 인증이 되었다고 알려주는 역할입니다.

AuthenticationProvider에서는 authenticate() 메서드를 통해 인증 과정이 진행됩니다.

UserDetailsService, UserDetails, User

UserDetailsService는 DB에서 사용자 인증 정보를 가져오는 역할을 합니다. UserDetilas 객체를 전달 받은 후 실제 사용자의 입력정보와 UserDetails 객체를 가지고 인증을 시도합니다.

인증이 완료되면 사용자 정보를 가진 Authentication 객체를 SecurityContextHolder에 담은 이후 AuthenticationSuccessHandle을 실행합니다.

📌 JWT

JWT는 토큰 기반 인증 시스템의 대표적인 구현체입니다.

다음과 같이 .을 기준으로 Header,Payload,Signature로 이루어져 있습니다.

JWT의 사용 이유

여태까지는 Spring Security 에서의 인증 및 권한 부여에 대해서 알아보았습니다. 기존에 인증 체계는 Cookie, Session으로 이뤄졌습니다.

  • Client가 Web Site에 접속할 때 그 사이트가 사용하게 되는 일련의 작은 기록 파일
  • Server가 Client에 정보를 전달할 때 저장하고자하는 정보를 응답헤더(cookie)에 저장하여 전달
  • Key Value 형식의 문자열 형태

=> Browser에 저장되어서 사용하는 작은 텍스트 파일로써 접속자 장치를 인식하거나 일부 데이터를 저장하는 역할

Session

  • Cookie의 단점을 보완하고자 나온 것
  • 일정 시간동안 같은 사용자로 부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술
  • 방문자의 요청에 따른 정보를 웹 서버가 세션 아이디 파일을 만들어 서비스가 돌아가는 서버에 저장한다.

Cookie/Session이 아닌 JWT??

쿠키는 사용자의 로그인 정보와 같은 민감한 정보를 포함하고 있어 보안에 좋지 않고, 조작의 가능성, 다른 브라우저간 공유 불가능, 4KB라는 적은 사이즈로 충분한 데이터를 담을 수없다는 단점이 있습니다.

세션은 stateful하기 때문에 Http의 장점을 발휘하지 못한 다는점과, Session 저장소에 문제가 발생하면 인증 체계가 무너지는 점,
사용자가 많아지면 메모리를 많이 차지하고 매번 요청마다 세션 저장소를 조회해야 한다는 단점이 있습니다.

요즘은 웹이 아닌 모바일에서도 사용가능한 장점과 Stateless 한 서버 구현, 안정성을 가진다는 장점으로 JWT를 많이 사용하고 있습니다.

기본 동작 원리

  1. Clinet 사용자가 아이디,패스워드를 통해 웹 서비스 인증
  2. Server에서 서명된 JWT를 생성하여 Client에 응답으로 돌려주기
  3. Client가 서버에 데이터를 추가적으로 요구할 때 JWT를 HTTP Header에 첨부
  4. Server에서 Client로 부터 온 JWT 를 검증

쓰다보니 글이 길어져서 구현부터는 다음 챕터에서 하도록 하겠습니다 :)

0개의 댓글