Spring Security + JWT

dev_yuni·2023년 11월 5일
5

Spring

목록 보기
1/1
post-custom-banner

Spring Security

스프링 시큐리티란 ?

스프링 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크이다.

인증(Authentication)

해당 사용자가 본인이 맞는지를 확인하는 절차이다. 즉, 사용자가 아이디와 비밀번호를 입력하고 로그인하는 과정을 말한다.

인가(Authorization)

인증된 사용자가 요청한 자원에 접근 가능한지를 결정하는 절차이다.

Spring Security는 기본적으로 인증 절차를 거친 후에 인가 절차를 진행하게 되며, 인가 과정에서 해당 리소스에 대한 접근 권한이 있는지 확인을 하게 된다.
Spring Security에서는 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.

  • Principal(접근 주체): 보호받는 Resource에 접근하는 대상
  • Credential(비밀번호): Resource에 접근하는 대상의 비밀번호

정리

스프링 기반 애플리케이션의 보안을 담당하는 스프링 하위 프레임워크이다.
보안과 관련하여 체계적으로 많은 옵션을 제공하여 편리하게 사용할 수 있고, Filter 기반으로 동작하여 MVC와 분리하여 관리 및 동작하면서 어노테이션을 통한 간단하게 설정할 수 있다. Spring Security는 기본적으로 세션 & 쿠키 방식으로 인증을 제공한다.

스프링 시큐리티 인증 처리 과정

  1. 사용자가 폼에 아이디와 비밀번호를 입력하면 HTTPServletRequest에 아이디, 비밀번호 정보가 전달된다.
    이때 AuthenticationFilter가 넘어온 아이디와 비밀번호의 유효성 검사를 실시한다.

  2. 유효성 검사 후 실제 구현체인 UsernamePasswordAuthenticationToken을 만들어 넘겨준다.

  3. 인증용 객체인 UsernamePasswordAuthenticationToken을 AuthenticationManager에게 전달한다.

  4. UsernamePasswordAuthenticationToken을 AuthenicationProvider에게 전달한다.

  5. 사용자 아이디를 UserDetailsService로 보낸다. UserDetailsService는 사용자 아이디로 찾은 사용자의 정보를 UserDetails 객체로 만들어서 AuthenticationProvider에게 전달한다.

  6. DB에 있는 사용자의 정보를 가지고 온다.

  7. 입력 정보와 UserDetails의 정보를 비교해 실제 인증 처리를 진행한다.

  8. ~10. 까지 인증이 완료되면 SecurityContextHolder에 Authentication을 저장한다. 인증 성공 여부에 따라 성공 시 AuthenticationSuccessHandler, 실패 시 AuthenticationFailureHandler 핸들러를 실행한다.

스프링 시큐리티 필터

  • SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 저장하는 역할을 한다.

  • LogoutFilter : 설정된 로그아웃 URL로 오는 요청을 감시하며, 해당 유저를 로그아웃 처리한다.

  • (UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리한다.

  • DefaultLoginPageGeneratingFilter : 인증을 위한 로그인폼 URL을 감시한다.

  • BasicAuthenticationFilter : HTTP 기본 인증 헤더를 감시하여 처리한다.

  • RequestCacheAwareFilter : 로그인 성공 후, 원래 요청 정보를 재구성하기 위해 사용된다.

  • SecurityContextHolderAwareRequestFilter : HttpServletRequestWrapper를 상속한
    SecurityContextHolderAwareRequestWapper 클래스로 HttpServletRequest 정보를 감싼다.
    SecurityContextHolderAwareRequestWrapper 클래스는 필터 체인상의 다음 필터들에게 부가정보를 제공한다.

  • AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 인증토큰에 사용자가 익명 사용자로 나타난다.

  • SessionManagementFilter : 이 필터는 인증된 사용자와 관련된 모든 세션을 추적한다.

  • ExceptionTranslationFilter : 이 필터는 보호된 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달하는 역할을 한다.

  • FilterSecurityInterceptor : 이 필터는 AccessDecisionManager 로 권한부여 처리를 위임함으로써 접근 제어 결정을 쉽게해준다.

저걸 어떻게 다 외워요.
필터는 굳이 다 외우지 말고 이런게 있구나~ 하고 알고 있으면 됩니다!
필터는 custom해서 쓰는 경우도 있으니까요 :)


JWT (Json Web Token)

쿠키와 세션에 대한 자세한 내용은 스스로 알아보기.

  • cookie & Session은 서버의 어떤 저장소에 해당 값과 매칭되는 value를 가지고 있어야 한다. -> 서버 자원이 많이 사용됨.

  • JWT는 토큰 자체에 유저 정보를 담아서 암호화한 토큰이다. 암호화된 내용은 디코딩 과정으로 해석이 가능하다. -> 자원 문제 해결.

JWT 구조

JWT 는 . 을 구분자로 3가지의 문자열로 되어있다.

  • Header : 토큰의 타입이나, 서명 생성에 어떤 알고리즘이 사용되었는지 저장한다.

  • Payload :토큰에 담을 정보가 들어있다. 여기에 담는 정보의 한 ‘조각’ 을 클레임(claim) 이라고 부르고, 이는 key - value 의 한 쌍으로 이뤄져있다. 토큰에는 여러개의 클레임 들을 넣을 수 있다. 일반적으로 user의 id, 유효기간이 포함되어있다.
    단, payload에는 민감한 정보는 담지 않아야한다.( 디코딩되어 있을 뿐 특별한 암호화가 걸려있지 않아서 jwt를 가지고 디코딩하면 header나 payload에 담긴 값을 알 수 있다.)

  • Signature : Base64 방식으로 헤더(header)와 정보(payload)를 합친후 주어진 비밀키로 해쉬를 하여 생성한다.

https://jwt.io/ <- 이 사이트는 JWT.IO 는 브라우저 상에서 JWT 토큰을 검증하고 생성 할 수 있게 해주는 디버거 서비스를 제공

JWT를 통한 인증 절차

  1. 사용자가 로그인 한다.

  2. 서버에서는 계정의 정보를 읽어서 사용자를 확인 한 후, 사용자의 고유 ID 값을 부여하고 다른 정보와 함께 Payload에 넣는다.

  3. JWT 토큰의 유효기간을 설정한다.

  4. 암호화할 Secret key를 이용해서 Access Token을 발급한다.

  5. 사용자는 Access Token을 받아 저장 후, 인증이 필요할 때마다 토큰을 헤더에 실어서 보낸다.

  6. 서버에서는 해당 토큰의 Verify Signature(서명)를 Secret key로 복호화한 후, 조작 여부, 유효 기간을 확인한다.

  7. 검증이 완료되었을 경우에는 Payload를 디코딩해서 사용자의 ID에 맞는 데이터를 가져온다.

JWT에도 단점이 존재하는데...❗️
1. base64 인코딩을 통한 정보 전달이 이루어져 전달량이 많아 네트워크 전달 시 많은 데이터 양으로 부하가 생길 수 있다.
2. Payload에는 암호화가 되어 있지 않기 때문에 민감 정보 저장이 불가하다.
3. 토큰이 탈취당하면 만료될 때까지 대처 불가능하다.

⭐️ 3번 단점을 해결하기 위한 방법은 exp, Expiration Time (만료 시간) 을 짧게 가져가기!

어? 그러면 유효시간이 짧으면 시간이 지날때마다 ID, PW를 또 입력하는 불편함이 생기지 않나?
그걸 보완하는 방법은 Refresh Token❗️ (다음 시간에 계속...)


참고 사이트

profile
꾸준히 성장하는 백엔드 개발자
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 11월 13일

최고!

답글 달기