[Spring Security] Spring Security, Oauth2, JWT 1. 개념

최진민·2021년 6월 27일
0
post-thumbnail

Spring Security 핵심 요소

  • 인증(Authentication), 권한 (Authorization)

  • 💕구조

    • 1) User가 로그인 정보와 함께 인증 요청 (HttpRequest)
    • 2) UsernamePasswordAuthenticationToken(이하 UPAT) 객체 생성 (= 사용자가 입력한 데이터 기반의 미검증 상태 객체)
    • 3) AuthenticationManager의 구현체인 ProviderManager에게 UPAT 전달
    • 4) AuthenticationProvider에게 토큰 전달
    • 💋5) 실제 DB로 부터 사용자 인증 정보를 가져오는 UserDetailsService에 사용자 정보를 넘겨준다.
    • 💋6) 정보를 통해 DB에서 찾은 UserDetails객체 생성
    • 7) AuthenticationProvider는 6)의 객체를 받아서 사용자 정보를 비교
    • 8) 인증에 성공하면, 사용자 정보를 담은 Authentication 객체 반환
    • 9 - 10) 반환된 Authentication 객체를 AuthenticationFilter에서 반환하여 SecurityContext에 저장
    • ✨주의깊게 살펴야할 부분
      • UserDetailsService
      • UesrDetatils
      • ⇒ 사용자의 입력 데이터 (email, pw 등)와 UserDetailsService의 메서드가 반환하는 UserDetails 객체를 비교하면서 동작한다.
  • Spring Security에서 동작하는 기본 필터들의 목록 & 순서

    • ❗If, OAuth2 로그인을 이용하면 UserPasswordAuthenticationFilter 대신 OAuth2LoginAuthenticationFilter가 호출

      • 이 두 필터는 AbstractAuthenticationProcessingFilter가 감싸고 있다.
    • 구체적인 시큐리티 필터 형태


OAuth 2.0

  • 기본 개념
    • OAuth(OpenID Authentication) : 타 사이트에 대한 접근 권한을 얻고 개발이 가능하도록 도와주는 프레임워크
    • 구글, 카카오, 네이버 등 로그인 → 직접 구현한 사이트에서도 로그인 인증
    • 개발한 웹 사이트에 구글 계정을 그대로 전달하면 안되므로 Access Token을 발급 받아 해당 토큰을 기반으로 원하는 기능을 구현해야한다.
    • 🧨따지면, Access Token을 발급 받기 위한 일련의 과정을 인터페이스로 정의한 것이 바로 OAuth!
  • 주요 용어
    • Resource Owner : 개인 정보 소유자 (U)
    • Client : 제 3의 서비스로부터 인증 받고자 하는 서버 (직접 개발 웹 사이트 X)
    • Resource Server : 개인 정보를 저장한 서버 (구글 등 (G))
    • Client ID : Resource Servcer에서 발급해주는 ID (XG가 할당한 ID를 알려준다.)
    • Client Sercret : Resource Servcer에서 발급해주는 PW (XG가 할당한 PW를 알려준다.)
    • Authorized Redirect URI : Client 측에서 등록하는 URL (IF, 해당 경로로 인증을 요구하는 것이 아니라면 Resource Server는 요청 무시)
  • 예시 동작 설명
    • XG에 등록이 완료되면, Access Token 발급 가능
    • 예를 들어, https://accounts.google.com/?client_id=123&scope=profile,email&redirect_uri=http://localhost 의 쿼리 스트링
    • 1) 유저가 구글 로그인을 정상적으로 했을 때 구글은 이전에 등록된 client_id=123인 서버의 redirect_uri와 동일한지 확인
    • 2) 일치 → 유저에게 scope=profile,email 기능을 넘겨줄 것인지에 대한 승인 여부를 물어보고 승인하면 authorization_code라는 임시 PW 발급
    • 3) 이후 http://localhost/?authorization_code=2로 리다이렉트되고 X에서 해당 코드를 갖고 구글 Access Token에 요청 → 유저의 인증이 필요할때마다 토큰으로 접근

JWT 도입

  • 서버 기반 인증 방식

    • 핵심 : 서버 측에 사용자 정보를 저장하는 것.
    • Spring Security에서는 별도의 설정이 없다면 Session 이용
      • 즉, 사용자가 로그인을 하면 서버는 사용자의 세션을 만들어 서버의 메모리와 DB에 저장
      • If, 마이크로 서비스 개발 또는 서버 확장 : 모든 서버에게 세션의 정보를 공유해야하므로 별도의 중앙 세션관리 서버를 두기도 한다.
  • Access Token / Resfresh Token

    • Access Token
      • 리소스(사용자 정보)에 접근할 수 있도록 해주는 정보
      • 짧은 만료 기간, 세션 관리
      • Access Token만 이용하여 사용자 인증을 관리할 때
        • 1) Access Token의 만료기간을 짧게 하여 사용자가 자주 로그인
        • 2) Access Token의 만료기간을 길게 하여 사용자 로그인 빈도를 줄인다. But, 토큰 탈취가능성(위험 노출도 상승)
    • Refresh Token
      • 새로운 Access Token을 발급받기 위한 정보
      • 클라이언트가 Access Token이 없거나 만료됐다면 Refresh Token을 통해 Auth Server에 요청하여 새로운 Access Token을 발급
      • 외부 노출 X → DB관리
    • 보안과 편의의 Trade Off가 존재하지만 각 토큰의 장점을 잘 이용해야한다.
  • OAuth 2.0

    • Resorce Server에서 발급받은 Access Token을 이용해 직접 개발한 서버의 API 서비스를 이용 및 호출. 이때, 마이크로 서비스나 서버간 통신이 잦은 경우에는 Access Token을 자주 주고 받아야 한다.
    • 또한, 전달받은 Access Token이 유효한지 매번 DB에서 조회하고 갱신시 업데이트 해야한다. ⇒ (문제점) 클라이언트 상태를 관리 및 공유할 추가적인 저장 공간이 필요하고 매 요청마다 Access Token의 유효성을 검증하고 업데이트를 위한 DB 호출이 발생 ⇒ (해결) JWT 기반 인증
  • JWT

    • JWT : Claim(사용자에 대한 속성 값) 기반의 JSon Web Token

    • Auth Server에 검증 요청 생략(Why? 의미있는 토큰) ⇒ 비용 절감 & Stateless 아키텍처 구성

      • 1) 사용자 Auth Server 로그인
      • 2) Auth Server에서 인증 완료한 사용자는 JWT 토큰 발행 받음
      • 3) 사용자는 특정 애플리케이션 서버에 리소스 요청시, JWT 토큰을 Authorization Header에 넣어 전달
      • 4) 애플리케이션 서버는 전달 받은 JWT 토큰의 유효성을 직접 검사하여 사용자 인증 가능
    • JWT는 확장성에 큰 강점이 있다.

      • 세션 사용
        • 서버를 확장할 때마다 각 서버에 세션 정보 저장
        • 특정 서버에서 로그인 인증을 받을 때 다른 서버에서는 로그인을 했는지 알 수 없다.
      • JWT 사용
        • 서버의 수와 상관없이 토큰을 인증하는 방식을 알고 있다면 인증 과정 문제 없음.
        • 웹과 앱 간 쿠키 세션 처리에도 유용
    • JWT의 단점

      • 사용자 인증 정보가 필요한 요청을 보낼 때 헤더에 JWT 토큰 값을 실어 보내야 하기때문에 데이터가 증가해 네트워크 부하가 늘어날 수 있음
      • 토큰 자체에 사용자 정보를 담고 있기에 JWT가 만료되기 전에 탈취당하면 서버에서 처리 가능한 작업이 없다. JWT는 한 번 만들어 클라이언트에게 전달하면 제어가 불가능하기 때문에 만료 시간을 필수로 기입해야한다.
profile
열심히 해보자9999

0개의 댓글