관리 메뉴

너와 나의 스토리

Spring security - 용어 정리/작동 방식/JWT 본문

개발/Spring Boot

Spring security - 용어 정리/작동 방식/JWT

노는게제일좋아! 2020. 8. 22. 13:14
반응형

Spring security

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

  • 만약 스프링 시큐리티를 사용하지 않았다면? 
    • 자체적으로 세션을 체크하고 redirect 등을 해야할 것이다. 
  • Spring security는 filter 기반으로 동작하기 때문에 spring MVC와 분리되어 관리 및 동작한다.

 

보안 관련 용어

  • 접근 주체(Principal): 보호된 대상에 접근하는 유저
  • 인증(Authenticate): 현재 유저가 누구인지 확인 (ex. 로그인)
    • 애플리케이션의 작업을 수행할 수 있는 주체임을 증명
    • AuthenticationManager, AuthenticationProvider
  • 인가(Authorize): 현재 유저가 해당 리소스[어떤 서비스, 페이지]에 접근할 수 있는 권한이 있는지 검사
  • 권한: 인증된 주체가 애플리케이션의 동작을 수행할 수 있도록 허락되있는지를 판단
    • 권한 승인이 필요한 부분으로 접근하려면 인증 과정을 통해 주체가 증명되어야만 한다.
    • 권한 부여에도 두 가지 영역이 존재하는데 웹 요청 권한, 메소드 호출 및 도메인 인스턴스에 대한 접근 권한 부여

 

Authentication vs Authorization

  • Spring Security는 'Authentication' 부분과 'Authorization'에 대한 부분을 Filter 흐름에 따라 처리하고 있다.
  • Authentication(인증): 해당 사용자가 본인이 맞는지를 확인하는 절차
  • Authorization(인가): 인증된 사용자가 요청한 자원에 접근 가능한지를 결정하는 절차
  • 즉, 인증 절차 거친 후, 인가 절차 진행됨.
  • Spring security에서는 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.

 

JWT(JSON Web Token)

  • 보안(인증과 권한)에 많이 사용됨
  • JWT 토큰 형태로 사용됨

 

주요 인증 방식 

  • 로그인 기반 기반
    • Credential-based authentication
    • 토큰 기반 인증
  • 인증정보를 다른 어플리케이션으로 전달
    • 소셜 계정을 이용해 로그인하는 방식(제 3자가 인증)
    • OAuth2라고 한다.
  • 2단계 인증
    • 로그인한 후에 인증 단계를 한 번 더 거침(핸드폰 or 이메일 인증)
  • 하드웨어 인증

 

서버 기반 인증 시스템의 문제점

  • 작동 방식:
    • 클라이언트: 서버에게 로그인 요청
    • 서버: 세션 생성 및 유지 & 응답
  • 세션은 유저가 인증할 때 이 기록을 서버에 저장한다. 이 경우 유저의 수(동시 접속)가 많으면 서버나 DB에 부하가 큼
  • CORS(Cross-Origin Resource Sharing)
    • 쿠키를 여러 도메인에서 관리하는 것이 번거로움

 

토큰 기반 인증 시스템 

  • 위 서버 기반 인증 시스템의 문제를 완화한다.
  • 작동 원리
    • 유저가 아이디와 비밀번호로 로그인을 수행
    • 서버측에서 해당 정보 검증
    • 계정 정보가 정확하다면 서버측에서 유저에게 signed 토큰을 발급
    • 클라이언트에서는 토큰을 저장해두고 요청마다 토큰을 서버에 함께 전달
    • 서버에서 토큰을 검증하고 요청에 응답
  • 토큰은 HTTP 헤더에 포함시켜서 전달
  • 장점:
    • 무상태(stateless)
      • 확장성(Scalability)이 있음
    • 보안성
      • 쿠키를 사용하지 않음
    • 확장성(Extensibility)
      • 기능 확장 가능
      • token의 body에 내용을 담을 수 있다. -> 기능 확장
    • CORS 이슈를 해결할 수 있다.
      • 토큰만 유효하면 어디서나 요청이 정상적으로 처리되므로.
    • 웹 표준 기반
      • JWT <- 표준 토큰

 

JWT 구조

  • .을 구분자로 두고 3가지 문자열로 구성된다.
    • ->[헤더(header)].[내용(payload)].[서명(signature)]
  • Header
    • 두 가지 정보를 포함
      • typ: 토큰의 타입을 지정(JWT)
      • alg: 해싱 알고리즘 지정
  • Payload
    • 토큰에 담을 정보 -> 클레임(claim)이라고 함.
      • {name, value}쌍으로 구성
    • claim은 세 가지로 분류됨
      • Registered claim
      • Public claim: 충돌 방지 이름이 필요(주로 URI 형식으로 네이밍)
      • Private claim: 클라이언트와 서버 간의 협의 하에 사용됨

 

 

Spring Security - 인증

  • Spring security는 세션-쿠키 방식으로 인증한다. (HttpSession 사용)
  • 유저가 로그인을 시도 (http request)
  • AuthenticationFilter
    • 사용자가 보낸 아이디와 패스워드를 Dispatcher Servlet(Front Controller)으로 가기 전에 ServletFilter를 거치게 된다.
    • UsernamePasswordAuthenticationFilter를 사용해서 인증을 진행
    • AuthenticationManager를 통한 인증 실행
    • 인증 성공 실패 처리
      • 인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행
      • 인증 실패 시, AuthenticationFailureHandler 실행
  • AuthenticationManager
    • Authentication 객체 생성
      • 이 객체를 사용해서 Spring security가 인증 수행
    • 유저의 request에 담긴 Authentication을 넘겨 받아, 내용을 채운다.
  • AuthenticationProvider
    • 실제 인증이 일어남.
    • UserDetailsService에서 인증 확인하고, 인증된 사용자면 UsernamePasswordAuthenticationToken 생성
  • UserDetailsService
    • 사용자 인증(확인)
    • 사용자 정보 load
  • User
    • Spring security에서 제공하는 클래스로 이름과 패스워드 권한들에 대한 필드만 있다.
    • 그 외의 정보를 다루려면 UserDetails 구현체를 직접 만들어서 사용해야 한다.
  • DB에 있는 유저라면 UserDetails로 꺼내서 유저의 session 생성
  • Spring security의 인메모리 세션저장소인 SecuirtyContextHolder에 저장
  • 유저에게 session ID와 함께 응답을 내려줌
  • 이후 요청에서는 요청쿠키에서 JSESSIONID를 까봐서 검증 후 유효하면 Authentication를 쥐어준다.

 

SecurityContext

  • 접근 주체(Authentication)와 인증정보(GrantedAuthority)를 담고 있는 context
  • 현재 인증된 사용자의 details(principle)를 저장하는데 사용됨.
    • 사용자의 username이나 다른 details는 얻으려면, 이 SecurityContext를 먼저 얻어야한다.

 

SecurityContextHolder

  • SecurityContext에 접근하는데 도움을 주는 클래스
  • 기본적으로, ThreadLocal 객체를 사용하여 SecurityContext를 저장한다. 즉, SecurityContext 객체를 전달하지 않더라도 동일한 실행 쓰레드의 메서드에서 SecurityContext를 항상 사용할 수 있습니다. 
  • SecurityContext는 ThreadLocal에 저장되어 있어서, UserDetails를 알고 싶을 때, Spring MVC controller에서 Principal or Authentication 객체 사용하면 된다. -> SecurityContextHolder 사용할 필요 없다.

Example

@PostMapping("/users")
public ResponseEntity<AnyView> funcName(@Authentication authentication) {

  // get User Name
  String userName = authentication.getName();

  // get User Role
  String role = authentication.getAuthorities().toString();

}

 

* ThreadLocal이란?

일반 변수의 수명은 특정 코드 블록(메서드 범위, for 블록 범위 등) 범위 내에서만 유효하다.

반면에 ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있게 된다.

 

 

 

 

 

 

출처

 

반응형
Comments