📌CocO 깃허브 보러가기
⭐Spring Security
✅ Spring Security란?
Spring Security는 스프링 기반 애플리케이션의 보안을 책임지는 프레임워크로, 주로 인증(Authentication)과 인가(Authorization) 기능을 제공합니다. 이 프레임워크를 통해 애플리케이션에서 접근 제어를 설정하고 관리할 수 있습니다.
Spring Security의 가장 큰 장점은 복잡한 보안 로직을 직접 구현할 필요 없이, 이미 검증된 보안 메커니즘을 제공한다는 것입니다. 로그인, 권한 부여, 암호화, 세션 관리 등을 간단한 설정만으로 쉽게 구현할 수 있어 개발 시간과 노력을 절약할 수 있습니다.
✅ 인증과 인가
인증(Authentication): 사용자가 누구인지 확인하는 과정입니다. 주로 사용자 이름과 비밀번호로 이루어지며, 로그인 과정에서 사용자가 올바른 자격 증명을 했는지 검증하는 것을 의미합니다.
인가(Authorization): 인증된 사용자가 시스템 내에서 어떤 자원에 접근할 수 있는지를 결정합니다. 예를 들어, 일반 사용자는 자신의 정보만 볼 수 있지만, 관리자는 모든 사용자의 데이터를 수정할 수 있는 권한을 가질 수 있습니다.
✅ Spring Security의 주요 기능
- 인증 처리: Spring Security는 폼 기반 로그인, OAuth2 소셜 로그인, Basic Authentication 등 다양한 인증 방식을 지원합니다.
- 인가 처리: 인증된 사용자가 접근할 수 있는 리소스를 정의하고 관리할 수 있으며, 역할 기반으로 접근을 제어할 수 있습니다.
- 보안 설정: URL 경로에 따라 접근 권한을 설정할 수 있으며, 특정 리소스에 대해 로그인한 사용자만 접근 가능하게 할 수 있습니다.
- 암호화: 사용자 비밀번호는 안전하게 암호화되어 저장되며, Spring Security는 다양한 암호화 알고리즘을 지원하여 데이터 유출을 최소화합니다.
- 세션 관리: Spring Security는 세션 고정 공격(session fixation)을 방지하는 등 세션 관리를 위한 다양한 기능을 제공합니다.
✅ Spring Security : 필터 기반 구조
필터는 웹 애플리케이션에서 문지기 역할을 하는 도구입니다. 웹 사이트에 들어오는 모든 요청(예: 사용자가 웹 페이지를 열 때의 요청)과 나가는 모든 응답(예: 서버가 웹 페이지 내용을 사용자에게 보낼 때)을 통과하는 곳이 필터입니다.
Spring Security는 여러 개의 보안 필터를 통해 인증, 권한 부여, 공격 방지 등의 작업을 처리합니다. 각 필터는 요청이 들어올 때 또는 응답을 보낼 때 특정 보안 작업을 수행합니다. 이 필터들은 필터 체인(Filter Chain)이라는 구조로 연결되어 있으며, 특정 순서대로 실행됩니다.
✅ Spring Filter Chain
Security Filter Chain은 Spring Security에서 인증과 인가를 처리하기 위해 제공하는 필터들의 집합입니다.
HTTP 요청과 응답을 효과적으로 관리하고, 보안을 강화하는 데 중요한 역할을 합니다. 필터를 통해 요청을 처리하고, DelegatingFilterProxy, FilterChainProxy, SecurityFilterChain과 같은 컴포넌트를 사용하여 유연하게 필터 체인을 구성할 수 있습니다.
Spring Security는 기본적으로 여러 필터를 제공하지만, 사용자는 자신의 개발 목적에 맞춰 커스텀 필터를 추가하여 필터 체인에 포함시킬 수 있습니다.
Filter Chain
클라이언트는 응용 프로그램에 요청을 보내고 컨테이너는 요청 URI의 경로를 기반으로 HttpServletRequest를 처리해야 하는 FilterInstance와 Servlet을 포함하는 위와 같은 FilterChain을 생성합니다.
서블릿이란, 자바 기반의 서버 사이드 기술로, 클라이언트의 요청을 받아서 처리하고, 응답을 생성하는 자바 프로그램입니다.
FilterChain은 HTTP 요청을 처리하는 과정에서 필터의 체인을 구성하고, 요청을 필터 체인을 통해 전달하는 역할을 합니다.
필터는 FilterChain을 통해 연결되어 있으며, FilterChain의 순서대로 요청을 처리합니다. 각 필터는 doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 메서드를 구현하여, 다음 필터 또는 최종 서블릿으로 요청을 전달합니다.
DelegatingFilterProxy
Spring Framework에서 제공하는 필터로, 서블릿 컨테이너와 스프링 애플리케이션 컨텍스트 사이에서 필터 기능을 연결하는 역할을 합니다.
서블릿 컨테이너는 자체적인 필터 등록 방법을 가지고 있습니다. 예를 들어, 서블릿 컨테이너의 설정 파일(web.xml)이나 어노테이션을 통해 필터를 등록할 수 있습니다. 하지만, 이 필터는 서블릿 컨테이너의 관점에서 독립적으로 동작 하기 때문에 Spring의 빈(Bean)을 사용할 수는 없습니다. 즉, 서블릿 컨테이너는 스프링 애플리케이션 컨텍스트에 접근하지 못하며, 스프링의 빈(Bean) 관리 기능이나 의존성 주입(Dependency Injection) 기능을 알지 못합니다. 따라서, 서블릿 컨테이너는 스프링 컨테이너에서 정의된 빈을 직접적으로 필터로 사용할 수 없습니다. 이를 해결하기 위해 DelegatingFilterProxy를 사용합니다.
DelegatingFilterProxy는 서블릿 컨테이너의 필터로 등록되지만, 실제 필터 작업을 스프링 컨텍스트에서 관리되는 빈(Bean)으로 구현된 필터에게 위임할 수 있습니다. 이렇게 하면 스프링의 의존성 주입(Dependency Injection)과 같은 기능을 필터에서도 사용할 수 있게 됩니다.
이를 통해 스프링 애플리케이션 내에서 관리되는 객체(빈)를 서블릿 필터로 동작하게 할 수 있어 의존성 주입, AOP 기능을 필터에서도 사용할 수 있게 됩니다.
FilterChainProxy
FilterChainProxy는 Spring Security의 중심 필터로, 여러 개의 보안 필터들을 관리합니다. 이 필터는 SecurityFilterChain을 통해 어떤 필터들이 현재 요청에 적용될지 결정합니다. FilterChainProxy는 보안 필터 체인에서 가장 먼저 실행되며, 보안 컨텍스트 초기화, HTTP 방화벽 적용 등 중요한 작업들을 수행합니다.
SecurityFilterChain
SecurityFilterChain은 특정 요청에 대해 어떤 보안 필터가 실행될지를 결정합니다. 이 체인 내에서 각 필터는 특정 작업을 담당하며, 필터의 순서는 매우 중요합니다. 예를 들어, CsrfFilter는 CSRF 공격을 방지하고, UsernamePasswordAuthenticationFilter와 BasicAuthenticationFilter는 인증을 처리하며, AuthorizationFilter는 권한을 확인합니다.
필터 체인 요청 흐름
- 클라이언트 요청: 클라이언트(예: 웹 브라우저)가 HTTP 요청을 서버로 보냅니다.
- 서블릿 컨테이너 수신: 서블릿 컨테이너는 이 요청을 수신하고 FilterChain을 생성합니다.
- FilterChainProxy: FilterChainProxy가 요청을 받으면, 적절한 SecurityFilterChain을 선택합니다.
- SecurityFilterChain 처리: 선택된 SecurityFilterChain에 따라 여러 보안 필터가 순차적으로 요청을 처리합니다. (예: 인증, 권한 부여)
- 필터 체인 처리: 각 보안 필터는 doFilter 메서드를 호출하여 요청을 처리하고, 다음 필터로 전달합니다.
- 최종 서블릿 처리: 필터 체인을 통과한 요청은 최종 서블릿(예: DispatcherServlet)으로 전달됩니다. 서블릿은 비즈니스 로직을 처리하고 응답을 생성합니다.
- 응답 반환: 서블릿이 생성한 응답은 다시 필터 체인을 통해 클라이언트에게 반환됩니다. 필터는 응답을 수정하거나 추가 작업을 수행할 수 있습니다.
✅ 보안 컨텍스트(Security Context)
보안 컨텍스트는 애플리케이션이 현재 사용자가 누구인지 기억하는 메모리 공간입니다.
이 컨텍스트는 사용자가 로그인하면 생성되며, 사용자가 애플리케이션을 사용하는 동안 유지됩니다. 컨텍스트 안에는 사용자의 아이디, 권한, 인증 상태와 같은 정보가 들어 있습니다.
만약 사용자가 웹사이트에 로그인하면, 보안 컨텍스트는 이 사용자가 누구인지, 어떤 권한이 있는지 기억합니다. 이후 사용자가 페이지를 이동할 때마다, 애플리케이션은 이 보안 컨텍스트를 참고하여 사용자가 접근할 수 있는 자원이나 기능을 결정합니다.
간단히 말해, 보안 컨텍스트는 사용자의 신원과 권한을 관리하는 기억 장치입니다.
✅ Spring Security를 사용해야하는 이유
Spring Security는 복잡한 보안 로직을 쉽게 구현할 수 있도록 도와주는 강력한 도구입니다. 인증, 인가, 암호화, 세션 관리 등 애플리케이션 보안에 필요한 대부분의 기능을 제공하므로, 직접 구현하는 것보다 훨씬 안전하고 효율적으로 보안 기능을 구현할 수 있습니다.
개발자는 이 강력한 툴을 활용해 최소한의 노력으로 안전한 웹 애플리케이션을 개발할 수 있습니다.
⭐ OAuth2.0
✅ OAuth 2.0이란?
OAuth 2.0은 사용자가 직접 비밀번호를 입력하지 않고도 외부 서비스(예: Google, Facebook, Naver)를 통해 애플리케이션에 안전하게 로그인할 수 있도록 도와주는 권한 부여 프로토콜입니다.
사용자로부터 위임받은 권한을 통해 서드파티 애플리케이션이 데이터를 안전하게 접근할 수 있게 해줍니다. 예를 들어, 어떤 앱이 사용자의 구글 계정에 있는 사진에 접근하려 할 때, 구글에 로그인한 후 "이 앱이 내 사진에 접근하도록 허용할까요?"라는 화면이 나타납니다. 사용자가 허용하면, 그 앱은 사용자의 비밀번호를 모르는 상태에서도 사진에 접근할 수 있습니다.
이 기능은 우리가 흔히 '소셜 로그인'이라고 부르는 서비스에서 자주 사용됩니다. 예를 들어, 이 티스토리에서도 아래와 같이 자체 회원가입을 하지 않고도 카카오톡 계정으로 로그인할 수 있는 것을 떠올리시면 됩니다. 티스토리는 사용자를 직접 인증하는 대신, 카카오톡 서비스를 통해 사용자 정보를 확인하게 되는 것입니다.
결론적으로, OAuth 2.0은 서드파티 서비스에 인증과 인가를 맡기고, 이를 통해 클라이언트 애플리케이션이 사용자로부터 안전하게 접근 토큰을 받아 필요한 데이터를 접근하는 구조를 제공합니다.
✅ OAuth 2.0에서 사용하는 주요 용어 정리
- 리소스
사용자가 소유하고 있는 데이터나 자산을 말합니다. 예를 들어, 이름, 이메일 등이 될 수 있습니다. - 리소스 소유자(Resource Owner)
OAuth 2.0 프로토콜을 사용하여 보호되는 리소스에 대한 액세스 권한을 부여하는 사용자(엔티티)입니다. 클라이언트를 인증(Authorize)하는 역할을 수행합니다. 예를 들어 네이버 로그인에서 네이버 아이디를 소유하고 third-party 애플리케이션(클라이언트)에 네이버 아이디로 소셜 로그인 인증을 하는 사용자를 의미합니다. - 클라이언트(Client)
OAuth 2.0을 사용하여 리소스에 접근하려는 third-party 애플리케이션이나 서비스입니다. - 권한 서버(Authorization Server)
보호된 사용자 데이터를 가지고 있는 서버 클라이언트를 인증하고 권한을 부여하는 서버입니다. 권한 서버는 사용자 인증, 권한 부여 및 토큰 발급을 관리합니다. - 리소스 서버(Resource Server)
리소스 서버는 보호되는 리소스를 호스팅하는 서버로, 액세스를 허용하거나 거부합니다. 이 서버는 OAuth 2.0 토큰을 사용하여 클라이언트에게 리소스에 액세스할 권한을 부여하고 실제 데이터를 제공합니다. - Access Token
리소스 서버로부터 데이터를 가져오기 위해 사용하는 토큰입니다. 뒤에서 더 자세히 설명할 예정입니다.
✅ OAuth 2.0의 작동 방식 예
- 사용자가 앱을 통해 자신의 구글 데이터를 사용하려고 하면, 그 앱은 구글에 권한을 요청합니다.
- 사용자는 구글 로그인 페이지로 이동하여 앱이 접근하도록 허용할지 결정합니다.
- 사용자가 허용하면, 구글은 그 앱에 액세스 토큰을 줍니다. 이 토큰을 통해 앱은 사용자의 비밀번호를 몰라도 구글 서버에서 사용자의 데이터에 접근할 수 있게 됩니다.
✅ OAuth 2.0의 Access Token
OAuth 2.0의 Access Token은 클라이언트 애플리케이션이 사용자의 자원에 접근할 수 있도록 허용하는 권한 증명입니다.
클라이언트가 자원 서버에 API 요청을 할 때 이 토큰을 함께 보내어 요청이 유효한지 확인할 수 있습니다.
Access Token은 보통 문자열로 되어 있으며, 뒤에서 설명할 JWT(JSON Web Token) 형태일 수도 있고, 단순한 문자열일 수도 있습니다. JWT 형식일 경우, 토큰에 인코딩된 정보를 통해 클라이언트와 자원 서버 간의 안전한 통신이 가능합니다.
Access Token은 권한 부여 서버(Authorization Server)에서 발급됩니다. 사용자가 클라이언트 애플리케이션에 권한을 부여하면, 권한 부여 서버는 클라이언트에게 Access Token을 제공합니다. 이 발급 과정은 바로 아래에서 더 자세히 설명해드리겠습니다!
Access Token은 유효 기간이 설정되어 있습니다. 유효 기간이 지나면 토큰은 만료되며, 클라이언트는 새로 발급받아야 합니다. 이 유효 기간은 보안성을 높이기 위해 상대적으로 짧은 경우가 많습니다.
Access Token은 클라이언트가 자원 서버에 접근할 수 있는 권한을 갖고 있다는 것을 증명하므로, 안전하게 관리해야 합니다. 만약 Access Token이 유출되면, 악의적인 사용자가 자원에 접근할 수 있습니다.
✅ OAuth 2.0 권한 부여 과정
- 인증 코드 요청
- 클라이언트가 사전에 권한 서버로부터 발급한 클라이언트 ID, redirect_uri 정보와 함께 response_type을 code로 지정하여 요청합니다.
- 로그인
- 권한 서버에서 로그인 페이지를 제공하고 리소스 소유자가 로그인 합니다.
- 인증 코드 전달
- 로그인에 성공하면 권한 서버는 전달받은 redirect_uri로 인증 코드를 전달합니다.
- Access Token 요청
- Client는 발급받은 권한 부여 코드를 사용해 Authorization Server에 Access Token을 요청합니다.
- client_id, redirect_url, grant_type, code(권한 부여 코드)와 같은 쿼리 파라미터가 포함됩니다.
- grant_type 파라미터는 클라이언트가 Access Token을 요청하는 방식(여기서는 authorization_code)을 명시합니다. Authorization Code는 클라이언트가 사용자의 권한을 얻었음을 증명하는 코드로, 이를 Authorization Server에 보내면, 서버는 클라이언트의 요청을 검토하여 Access Token을 발급합니다.
- 중요성: 이 과정은 보안에 중요합니다. 만약 Authorization Code 없이 바로 Access Token을 발급받으면 보안상 큰 문제가 발생할 수 있습니다. Authorization Code 발급 과정이 포함되면, 클라이언트는 백엔드에서 Authorization Code를 통해 Access Token을 요청할 수 있어 브라우저를 통한 직접적인 토큰 노출을 방지할 수 있습니다. 따라서 보안적으로 더 안전합니다.
- 엑세스 토큰 발급
- 클라이언트가 권한 부여 승인 코드를 통해 엑세스 토큰 (및 리프레시 토큰)을 발급받습니다.
- 이때 사전에 권한 서버로부터 발급한 클라이언트 ID와 클라이언트 시크릿 (Client Secret) 정보가 필요합니다.
- Resource 요청
- 클라이언트는 발급받은 access_token을 사용하여 리소스 서버에 보호된 자원을 요청합니다. 리소스 서버는 토큰을 검증하고, 적절한 경우 자원을 반환합니다.
✅ Spring OAuth2 Client 라이브러리
Spring에서는 OAuth2 Client 라이브러리가 제공되는데, 이 라이브러리는 OAuth2 클라이언트가 해야 할 복잡한 작업을 쉽게 처리할 수 있도록 도와주는 도구입니다.
예를 들어, 이 라이브러리를 사용하면 OAuth2 로그인 화면으로 자동으로 이동하는 기능이나, 권한 부여 승인 코드를 통해 Access Token을 발급받는 과정 등을 직접 코드로 작성하지 않아도 쉽게 구현할 수 있습니다. 추가로, Access Token을 사용해 자원 서버에서 데이터를 가져오는 서비스만 별도로 구현하면, OAuth2 로그인과 관련된 모든 과정을 간단하게 처리할 수 있습니다.
만약 이 라이브러리가 없었다면, 각 소셜 로그인 제공 업체(예: 구글, 카카오)의 API 문서를 일일이 확인한 후, RestTemplate이나 WebClient 같은 도구로 직접 통신하고, 엔드포인트를 만드는 컨트롤러도 직접 만들어야 했을겁니다. 이런 전통적인 방식은 시간이 많이 들고 번거롭겠죠!
그래서 이 라이브러리를 사용하면 소셜 로그인 기능을 훨씬 더 쉽게 개발할 수 있습니다.
⭐JWT Token (JSON Web Token)
✅ JWT란?
JWT는 JSON 형식의 데이터를 서로 주고받기 위한 표준입니다. 주로 인증과 인가 정보를 안전하게 교환하는 데 사용되며, 특히 웹 애플리케이션에서 많이 사용됩니다. 이러한 JWT로 발급된 토큰이 JWT Access Token입니다.
✅ JWT Access Token이란?
JWT Access Token은 사용자 인증 또는 권한 부여 정보를 포함한 토큰으로, 클라이언트가 서버에 요청을 보낼 때 이 토큰을 함께 전송합니다. 서버는 이 토큰을 확인해 사용자가 인증된 상태인지, 어떤 권한을 가지고 있는지 판단할 수 있습니다.
✅ JWT의 구조
JWT는 크게 3가지 부분으로 나뉩니다. 보통 아래와 같이 생겼는데요.
색으로 구분해봤습니다!
여기에서 빨간 부분이 Header, 노란 부분이 Payload,초록 부분이 Signature입니다.
- Header (헤더): 토큰의 타입(JWT)과 암호화 방식(예: HS256)을 정의합니다.
- Payload (페이로드): 사용자에 대한 정보나 권한 등의 데이터를 담고 있습니다. 이 부분에 인증 정보나 추가적인 데이터를 넣을 수 있습니다.
- Signature (서명): 헤더와 페이로드를 각각 Base64 인코딩을 거친 문자열과 백엔드 서버가 소지하고 있는 Secret Key를 포함해서 다시 인코딩한 긴 문자열 입니다.Secret Key는 시그니쳐의 일부를 구성하게 되는 문자열로 랜덤한 문자열로 개발자가 생성해서 사용하면 됩니다. 인터넷 상의 Key Generator를 사용하기 보다, 키보드를 랜덤하게 길게 입력해 구성하는 것이 좋습니다.서버가 이 서명을 사용해 토큰이 위조되지 않았는지 확인할 수 있습니다. 일반적으로 Springboot 프로젝트에서 Secret Key를 application.yml에 별도로 저장해 노출되지 않도록 해야합니다.
✅ JWT 사용의 장점
JWT(토큰 기반 인증)의 가장 큰 장점은 서버에서 상태 정보를 따로 관리할 필요가 없다는 점입니다. 서버는 클라이언트가 보내는 JWT를 통해 사용자의 상태를 확인할 수 있습니다. 이 방식은 서버의 부담을 줄이고, 시스템의 확장성을 높여줍니다.
✅ Access Token의 단점과 보완책
JWT로 발급된 Access Token을 사용하는 경우, 보안상의 단점이 있습니다. 만약 누군가가 Access Token을 탈취해 사용한다면, 서버는 이 토큰이 실제 사용자에게서 나온 것인지, 탈취된 것인지 구분할 수 없습니다. 이는 클라이언트가 토큰을 안전하게 관리하지 못한 탓이지만, 서버도 별도로 정보가 저장되지 않기 때문에 이를 해결하기 어렵습니다.
이를 보완하기 위해 Access Token의 만료 시간을 짧게 설정하는 방법이 있습니다. 이렇게 하면 토큰이 탈취되더라도 피해를 줄일 수 있습니다. 그러나 만료 시간이 너무 짧으면 사용자가 자주 로그인을 해야 하는 불편함이 생깁니다. 이를 해결하기 위해 'Refresh Token' 개념이 도입되었습니다.
✅ Refresh Token의 역할
Refresh Token은 Access Token이 만료되었을 때, 새로운 Access Token을 발급받기 위해 사용됩니다. Access Token의 유효 기간을 짧게 설정해 보안을 강화하면서도, 사용자가 자주 로그인을 하지 않도록 Refresh Token을 사용해 새로운 토큰을 발급받을 수 있게 합니다.
✅ Refresh Token 구현 방법
Refresh Token은 주로 두 가지 방식으로 구현됩니다.
- JWT 기반 Refresh Token
이 방법은 기존의 JWT를 그대로 활용하는 방식입니다. Access Token과 동일하게 JWT 형식으로 Refresh Token을 생성합니다. 이 방식의 장점은 JWT 구조를 그대로 활용해 토큰 만료 기간을 설정하기 쉽다는 것입니다.
그러나 Access Token과 Refresh Token이 동시에 탈취되면, 대응하기 어렵습니다. 서버가 상태 정보를 따로 저장하지 않기 때문입니다. - UUID 기반 Refresh Token
이 방법은 UUID(고유한 랜덤 문자열)를 Refresh Token으로 사용하는 방식입니다. UUID는 만료 기간을 포함하지 않으므로, 서버에 이 토큰을 저장하고 관리해야 합니다. Redis와 같은 인메모리 데이터베이스를 활용해 Refresh Token을 저장하고 관리할 수 있습니다. 이 방식은 많은 서비스에서 사용되고 있습니다. 세션 방식에 비해 세션 서버에 대한 요청 횟수를 줄일 수 있다는 점이 장점입니다. 세션 방식에서는 클라이언트가 세션 ID를 쿠키에 담아 서버로 보내고, 서버는 세션 스토리지에서 해당 세션을 확인해야 합니다. 하지만 JWT Access Token을 사용하면, 서버는 토큰 자체의 유효성만 검증하면 되므로 요청 처리 과정이 더 간결해집니다.
물론, 프로젝트에 따라 이러한 장점이 큰 도움이 될 수 있지만, 더 중요한 요소가 있다면 다른 방식을 선택하는 것이 더 나을 수 있습니다.
✅ 결론:완벽한 방법은 없다
소프트웨어 공학에서 "은탄환은 없다"라는 말이 있습니다. 이는 모든 문제를 해결할 수 있는 완벽한 방법은 없다는 의미입니다. JWT와 Refresh Token은 세션 방식을 대체하려고 나온 개념이지만, 모든 문제를 해결할 수 있는 방법은 아닙니다.
따라서 각 서비스의 요구사항에 맞는 최적의 방법을 찾아야 합니다. 앞으로 세션 방식도 직접 구현해보고 각 방식의 차이점을 경험해보면 더 좋은 선택을 할 수 있을 것입니다.
⭐ OAuth 2.0과 JWT의 차이점
OAuth 2.0은 사용자가 자신의 정보를 다른 앱이나 웹사이트와 안전하게 공유할 수 있도록 도와주는 규칙입니다. 이 규칙은 어떻게 해서 사용자의 정보를 다른 애플리케이션이 접근할 수 있는지, 즉 권한을 부여하는 방법을 정합니다.
이때 Access Token이라는 것이 발급되는데, 이 토큰은 내 정보에 접근할 수 있도록 허락된 일종의 ‘열쇠’입니다.
JWT는 이러한 ‘열쇠’인 Access Token의 형식을 정의합니다. JWT는 정보를 안전하게 전달할 수 있는 포맷을 제공하며, 이 토큰이 변조되지 않았는지 확인할 수 있게 합니다.
즉, OAuth 2.0은 권한을 부여하는 규칙이고 JWT는 권한 부여 규칙에 따라 발급된 토큰의 형식이라고 할 수 있습니다.
OAuth 2.0과 JWT는 서로 보완하는 관계로, OAuth 2.0이 권한 부여의 방법을 제공하면 JWT는 토큰의 형식과 내용을 명확하게 정의하여 보안성을 강화합니다. OAuth 2.0과 JWT는 함께 사용되어, 안전하고 효율적인 권한 부여와 데이터 전송을 지원할 수 있습니다.
⭐ Spring Security & OAuth2.0 & JWT 의 동작 과정
- 로그인 및 인증 과정:
- 사용자 인증 요청:
- 사용자가 애플리케이션에 로그인하려고 하면, Spring Security는 OAuth 2.0 프로토콜을 사용하여 권한 서버에 인증 요청을 보냅니다.
- OAuth 2.0 권한 부여:
- 사용자는 권한 서버에서 로그인하고, 권한 서버는 인증 코드를 발급합니다.
- 이 인증 코드는 사용자가 권한을 부여한 앱에 전달됩니다.
- 사용자 인증 요청:
- Access Token 발급:
- 인증 코드로 Access Token 요청:
- 애플리케이션은 받은 인증 코드를 사용하여 권한 서버에 Access Token을 요청합니다. 이때, client_id, client_secret, redirect_uri, grant_type (여기서는 "authorization_code"), 그리고 발급받은 code를 포함합니다.
- Access Token 발급:
- 권한 서버는 이 요청을 검증하고, 유효하다면 Access Token을 발급합니다. 이 Access Token은 JWT 형식일 수 있습니다.
- 인증 코드로 Access Token 요청:
- 자원 접근:
- API 호출:
- 애플리케이션은 발급받은 Access Token을 사용하여 자원 서버(예: API 서버)에 보호된 자원에 대한 요청을 보냅니다.
- JWT 검증:
- 자원 서버는 JWT의 서명을 확인하고, 토큰의 유효성을 검증하여 요청을 처리합니다. 토큰의 페이로드에서 사용자 정보와 권한을 확인할 수 있습니다.
- API 호출:
예시 시나리오 (사용자 로그인의 경우)
- 사용자가 애플리케이션에 로그인하려고 하면, Spring Security는 OAuth 2.0의 인증 프로세스를 시작합니다.
- 사용자에게 로그인 페이지를 제공하고, 로그인 후 권한 서버는 인증 코드를 애플리케이션에 전달합니다.
- 애플리케이션은 이 인증 코드를 사용하여 Access Token을 요청하고, 받은 Access Token은 JWT 형식으로 제공됩니다.
이 조합을 통해, 애플리케이션은 사용자의 인증과 권한 부여를 안전하게 처리할 수 있으며, 토큰 자체에 필요한 정보를 담아 보다 효율적으로 작업을 수행할 수 있습니다.
참고자료