Spring Security, JWT

wjd15sheep·2024년 9월 4일
3

Spring Boot

목록 보기
11/19

프로젝트 진행 중 로그인과 세션 관리를 위해 여러 방법을 찾아본 결과, Spring Security와 JWT(Json Web Token)를 활용하기로 결정했습니다. 그러나 관련 자료를 조사해보니, 현재 버전에 맞지 않은 정보가 대부분이었습니다. 이로 인해 적용해보고 삭제하는 과정을 반복하며 많은 시간을 소모했습니다.

그러던 중 유튜브 채널 '개발자 유미'를 발견했습니다. 해당 채널에서는 현재 버전에 맞는 Spring Security와 JWT 사용법을 자세히 설명해주며, 따라 하기 쉽게 자료를 제공합니다. 그래서 많은 분들에게 추천하고 싶습니다.

이제 제가 이해한 내용과 개발자 유미님의 설명을 바탕으로 정리해보겠습니다.


로그인 기능 개발 고려해야할 것

  1. 인증과 인가
  • 인증 Authentication
    • 사용자 자격 증명(Credentials)을 통해 신원을 확인하는 과정, 예를 들어, 아이디와 비밀번호를 통한 단순 로그인 방식
  • 인가 Authorization
    • 사용자의 권한(Authorities) 및 보안 레벨을 확인하는 과정, 인증된 사용자가 어떤 자원에 접근할 수 있는지를 결정
  1. 로그인 인증 확인 및 권한 인가 + 로그인 세션 유지
  • 로그인 인증 확인 및 권한 인가
    사용자 자격 증명을 통해 로그인을 수행하고, 로그인된 사용자 정보를 가져오는 방법
    • 인증(Authentication) SSO : Credential을 통해 사용자 로그인 인증 완료
    • 인가(Authorization) OAuth : Credential을 통해 유저 로그인 인증 후 선택적 유저 정보 취득
  • 로그인 세션 유지
    로그인 인증 완료 및 로그인 된 유저 정보를 어떻게 저장할 것인지에 대한 전략
    • Cookie (Browser Side) : Stateful
    • Session (Server Side) : Stateful
    • JWT (Client Side Storage, Web 이라면 cookie / App 이라면 자체 저장소에 저장) : Stateless

그럼 본격적으로 Secrity란 무엇인지 포스팅하겠습니다.

Spring Security란 무엇인가?

Spring 기본적으로 로그인, 세션에 관련된 모튤 및 설정을 손쉽게 사용가능하도록 제공합니다.
spring security가 FilterChain 형식으로 제공 및 커스텀하여 기능을 사용하게 합니다.
이러한 방식의 장점으로는 1. 요청 URL에 따라 다른 인증처리가 가능, 2. 모든 요청에 따로 개발한 인증 모튤을 적용 가능하게 됩니다.

Filter(Servlet) 그리고 Interceptor(Spring) 차이

갑자기 필터와 인터셉터가 나왔다고 '뭐지?' 하시는 분이 계실겁니다. 그러나 필터와 인터셉터는 Spring Security을 이해하는데 아주 중요합니다.
이제 그 이유를 설명하겠습니다.
Spring Security에서 모든 보안처리는 Filter의 집합(SecurityFilterChain)을 통해 동작됩니다.
아래 이미지를 보면

외부로부터 오는 요청을 Filter에서 한번 거르고 Intercepter에서 두번 거르고 나서 Spring controller에 도달을 한다. 위 이미지가 Spring Security의 원리이다.

관리주체

  • Fiilter : Tomcat (Servlet Container) 서 관리
  • Interceptor : Spring (Spring Contaniner)서 관리

호출시기 차이

  • Filter : Front Controller 앞단 : DispatcherServlet 앞쪽에 위치
    doFilter()

    • 요청이 DispatcherServlet.service()에 진입히가 직전(init() 후)에 호출 : Req
    • 결과를 DispatcherServlet.service()가 반환하는 직후(destory() 전)에 호출 : Res
  • Interceptor : Front Controller 뒷단, Controller(Handler) 앞쪽에 위치

    • preHandle() : 요청이 Controller에 진입하기 직전에 호출
    • postHandle() : 결과를 Controller가 반환하는 직후에 호출
    • afterCompletion() : Controller 성공/실패 결과에 따라 View를 생성한 직후에 호출
  • 커버리지 차이

    • Filter : Tomcat은. WAS이니 정적리소스 반환 등의 WS 처리도 수행, Filter는 여기가지 적용
    • Interceptor : Spring Controller (Handler) 요청, 반환에 대해서만 Interceptor 적용

위 설명의 이미지

현재 버전은 Spring 빈으로 Filter를 등록을한다.
Filter는 Spring Bean 로 등록 가능하며, 내부에서 Spring Bean 활용도 가능하게 변경되었다.


위 이미지를 보면 DelegatingFilterProxy 설정으로 Tomcat이 관리하는 FilterChain의 중간 필터를 spring이 이항받아 SecurityFilterChain을 실행하는 방식으로 구현이 되어있다.

JWT란?

JWT 방식은 웹 서비스에서 쓴다면 사실상 Cookie와 같다.

  • 앱과 같이 HTTP Cooke를 가진 웹이 아닌 것이라면 자체 저장소 사용
  • 왜 Stateless인가?
    • JWT이 웹 서비스에서 사용되면 Cookie에 Domain + Path 기반 Stateful
    • 앱 서비스에서 사용되면 자체 저장소에 저장하기에 Stateless
    • 결론 : JWT는 상황에 따라 달리 해석될 케이스는 존재하나 Stateless이다. => JWT가 탈취되면 사용자가 누군지에 상관 없이 원하는 결과를 얻을 수 있기 때문
  • Header, Payload가 BASE64로 인코딩 되어있어 누구든지 바로 읽어낼 수 있다.
  • 데이터 위변조가 가능하지만, Signature를 통해 위변조 여부를 판단할 수 있다.
  • 영구 탈취에 대한 우려는 Refresh Token을 통해 보완(탈취되어도 일정 시점 이후에는 무력화 됨)

JWT 토큰의 구성 이미지

  • Header : 아래 Signature가 어떤 알고리즘으로 암호화되었나 확인이 가능하다.
  • Payload : 서버가 실제로 사용할 데이터가 적재
  • Signature : 해시가 단방향 암호화라 복호화가 아닌 Header, Payload 변조 여부만 판단

JWT 단점 : 실시간성 보장 불가

로그인 세션 데이터를 브라우저가 갖고 있기 때문에 실시간성을 보장할 순 없다.

  • 방금전 A에서 B으로 개명해도 JWT 내 유저 정보 상에 A이라는 이름
  • JWT 가 탈취가 되었을 시, JWT를 통해 인증이 필요한 작업을 타인이 수행가능한 문제

이를 보완하기 위해 Refresh Token을 통해 Access Token의 만료

  • Access Token의 만료기간을 10분으로 설정
  • Access Token이 탈취된다해도, 10분이 지나면 Refresh Token로 갱신 필요
    • 탈취된 Access Token는 10분만 지나면 활용할 수 없게됨
    • 이 주기를 짧게하면 Refresh 비용이 증가하고, 길게하면 탈취 대응이 힘듬

현업에서는 로그인 세션 유지 및 저장에 어떤 방식을 많이 사용하는가?

  • JWT : 세션 비용을 마련하기 부담스럽거나, 빠른 고객 검증이 필요한 스타트업
  • Session (Server Side) : 대기업

[참고]

  • 개발자 유미님 유튜브
  • ASAC-[웹 풀스택] 강사 Aaron
profile
성장 위해 노력하는 웹 개발자 주니어

0개의 댓글