Spring security 기초

HUSII·2023년 7월 17일
0

스프링 시큐리티

목록 보기
1/7

스프링 시큐리티에 대해 공부하기 전에 기본적으로 알아야할 개념들을 알아보겠다.

인증과 인가

인증(Authentication)이란 사용자의 신원을 검증하는 프로세스를 뜻한다.
가장 간단한 예시로는 ID와 PW를 통해 로그인하는 행위를 인증이라 할 수 있다.
(그외에 생체인식, 일회용 핀, 인증 앱 등...)

인가(Authorization)란 사용자에게 특정 리소스나 기능에 액세스할 수 있는 권한을 부여하는 프로세스를 말한다.
이 용어는 흔히 액세스 제어나 클라이언트 권한을 서로 대체하여 사용되기도 한다.
대표적으로, 서버에서 특정 파일을 다운로드할 수 있는 권한을 부여하거나, 개별 사용자에게 관리자 권한으로 애플리케이션에 액세스할 수 있는 권한을 부여하는 경우가 여기에 해당한다.

보안 환경에서 권한 인증(인가)은 항상 인증 이후에 진행되어야 한다. 사용자가 먼저 자신의 자격 증명을 입증하면 서비스가 해당 사용자에게 요청한 리소스에 액세스할 수 있는 권한을 부여하게 된다.

인증 (Authentication)인가 (Authorization)
기능자격 증명 확인권한 허가/거부
진행 방식비밀번호, 생체인식, 일회용 핀 또는 앱보안 팀에서 관리하는 설정 사용
사용자가 볼 수 있는가?아니오
사용자가 직접 변경할 수 있는가?부분적으로 가능불가능
데이터 전송ID 토큰 사용액세스 토큰 사용

인증과 인가는 어떻게 구현해야 할까?
HTTP의 stateless라는 특성을 인증과 함께 생각해보면 로그인을 통해 인증을 거쳐도 이후 요청에서는 이전의 인증된 상태를 유지하지 않게 된다.
이러한 상황에서 웹 사이트를 이용하려면 인증/인가가 필요한 모든 상황에서 사용자는 반복적으로 ID/PW를 입력해야 하는 불상사가 생기게 될 것이다.

쿠키에 유저 정보를 담거나, RequestBody에 액세스 토큰 정보를 담는 경우는 설명하지 않겠습니다.
(쿠키에 유저 정보를 담는 것은 보안 상의 위험이 있음)
(RequestBody는 GET 메소드일때 사용을 못함)


세션, 토큰

1. 세션
Session은 고객의 주요 정보가 아닌, 단지 고객을 식별할 수 있는 값 생성해 Cookie로 주고받는다. 예를 들어 A 사용자가 ID/PW를 통해 로그인을 했다면 A 사용자를 식별할 수 있는 값를 생성해 Cookie로 브라우저에 심고 매번 요청 때마다 생성한 값을 통해 인증/인가를 진행하게 된다.

이러한 방식은 고객의 로그인 정보를 주고받지 않아 이전 방식보다 보안상 이점이 있지만, 사용자를 식별할 수 있는 값을 생성하고 서버에 저장해두어야 하는 작업이 생기게 된다.

2. 토큰
세션 기반 인증이 인증 정보를 서버에 저장하는 방식이라면, 토큰 기반 인증은 인증 정보를 클라이언트가 직접 들고 있는 방식이다. 이때 인증 정보가 토큰의 형태로 브라우저의 로컬 스토리지(혹은 쿠키)에 저장된다. 토큰의 종류에 따라 다르겠지만, 대표적인 토큰인 JWT의 경우 디지털 서명이 존재해 토큰의 내용이 위변조 되었는지 서버측에서 확인할 수 있다.

토큰 기반 인증에서는 사용자가 가지고 있는 토큰을 HTTP 의 Authorization 헤더에 실어 보낸다. 이 헤더를 수신한 서버는 토큰이 위변조 되었거나, 만료 시각이 지나지 않은지 확인한 이후 토큰에 담겨있는 사용자 인증 정보를 확인해 사용자를 인가한다.

세션 vs 토큰

세션과 토큰 모두 존재 목적은 거의 같다.

하지만 차이점은 존재합니다.

차이점 1.사이즈
세션 < 토큰
세션을 사용시 주고받는 session id의 크기는 토큰에 비해 매우 작다.
반면 (JWT기준) 토큰은 같은 데이터를 담고 있어도 그에 비해 크기가 크다.

차이점 2.안전성
세션
세션은 서버측에서 저장/관리하기 때문에 상대적으로 온전한 상태를 유지하기 유리합니다.
하지만 여전히 공격의 위험이 있기에 유효기간, HttpOnly, Secure 옵션 등을 주어 쿠키에 저장합니다.

토큰
반대로 토큰은 웹 브라우저측 (local storage, 혹은 쿠키 등)에 저장되기 때문에 공격에 노출될 가능성이 더 큽니다.
이런 경우를 대비해 토큰에는 민감한 정보를 담지 않습니다.
그리고 유효기간을 짧게 설정해 공격에 노출될 수 있는 시간을 최소화합니다.
하지만 짧은 주기로 토큰이 무효화되면 서비스 사용자는 계속 로그인을 해줘야 하는 번거로움이 있기 때문에

애초에 로그인(인증)시 refresh token이라는 것을 추가적으로 발급합니다.
refresh token은 좀 더 긴 유효기간을 가졌으며 최대한 안전한 곳에 저장됩니다.
기존의 토큰이 만료되거나 변질되면 refresh token을 통해 토큰을 재발급합니다.

차이점 3. 확장성
최근 대부분의 웹 서비스가 토큰 방식을 선택하게 된 이유가 바로 확장성에 있습니다.
세션은 서버에 저장되기 때문에 한꺼번에 다중 접속자가 발생한다면 과부하가 걸릴 수 있습니다.
그럼 과부하를 덜어주기 위해 서버를 여러 대를 두면 되겠죠?
하지만 또 서버가 여러대라면 세션을 쓰기가 복잡해집니다.

서버 분산 / 클러스터 환경에서 드러나는 결정적인 차이
요즘 많은 서비스들은 서버 과부하 부담을 줄이기 위해 여러 서버를 두고 서비스를 운영합니다.
그리고 앞서 언급했듯 HTTP는 stateless, connectionless 하기 때문에 request마다 내가 접속한 서버가 달라질 수도 있습니다!!
이렇게 되어 버리면 session 정보가 없는 다른 서버에 접속할 때마다 계속 로그인해줘야 합니다.

물론 이러한 세션의 단점을 해결하기 위해 sticky session, session clustering과 같은 방안이 나오기도 했습니다

애초에 토큰방식을 사용한다면 추가 서버 없이 인증/인가를 처리할 수 있습니다.

profile
공부하다가 생긴 궁금한 것들을 정리하는 공간

3개의 댓글

comment-user-thumbnail
2023년 7월 18일

항상 좋은 글 감사합니다.

1개의 답글
comment-user-thumbnail
2023년 7월 18일

정말 좋은 정보 감사합니다!

답글 달기