인증과 인가에 대해서 간단하게 다루고 Spring Security에서의 인증과 인가 흐름에 대해서도 다루는 글이다.
인증
인증이란 사용자가 누구인지 확인하는 과정이다.
아이디/비밀번호 기반 인증
OAuth2.0/JWT기반 인증
소셜 로그인(Google, Facebook 등)
API Key / Token 기반 인증
인가
인가란 요청하는 유저가 권한이 있는지 체크하는 절차이다.
jwt에 유저의 권한 정보도 전달해서 수월하게 인가 체크
인증(Authentication)과 인가(Authorization)의 차이
보안에 관련된 작업을 위한 절차라는 공통점이 있지만 역할에서 다르다.
인증은 인가로 이어지지만 인가는 인증으로 이어지지 않는 차이가 있다.
Spring Security란?
Spring Security는 스프링 기반 애플리케이션의 보안을 책임지는 프레임워크로, 주로인증(Authentication)과인가(Authorization) 기능을 제공합니다. 이 프레임워크를 통해 애플리케이션에서 접근 제어를 설정하고 관리할 수 있습니다.
Spring Security의 가장 큰 장점은 복잡한 보안 로직을 직접 구현할 필요 없이, 이미 검증된 보안 메커니즘을 제공한다는 것입니다. 로그인, 권한 부여, 암호화, 세션 관리 등을 간단한 설정만으로 쉽게 구현할 수 있어 개발 시간과 노력을 절약할 수 있습니다.
Spring Security의 주요 기능
인증 처리: Spring Security는 폼 기반 로그인, OAuth2 소셜 로그인, Basic Authentication 등 다양한 인증 방식을 지원합니다.
인가 처리: 인증된 사용자가 접근할 수 있는 리소스를 정의하고 관리할 수 있으며, 역할 기반으로 접근을 제어할 수 있습니다.
보안 설정: URL 경로에 따라 접근 권한을 설정할 수 있으며, 특정 리소스에 대해 로그인한 사용자만 접근 가능하게 할 수 있습니다.
암호화: 사용자 비밀번호는 안전하게 암호화되어 저장되며, Spring Security는 다양한 암호화 알고리즘을 지원하여 데이터 유출을 최소화합니다.
세션 관리: Spring Security는 세션 고정 공격(session fixation)을 방지하는 등 세션 관리를 위한 다양한 기능을 제공합니다.
Spring Security : 필터 기반 구조
필터는 웹 애플리케이션에서문지기역할을 하는 도구입니다. 웹 사이트에 들어오는 모든 요청(예: 사용자가 웹 페이지를 열 때의 요청)과 나가는 모든 응답(예: 서버가 웹 페이지 내용을 사용자에게 보낼 때)을 통과하는 곳이 필터입니다.
Spring Security는 여러 개의 보안 필터를 통해 인증, 권한 부여, 공격 방지 등의 작업을 처리합니다. 각 필터는 요청이 들어올 때 또는 응답을 보낼 때 특정 보안 작업을 수행합니다. 이 필터들은필터 체인(Filter Chain)이라는 구조로 연결되어 있으며, 특정 순서대로 실행됩니다.
Spring Security 인증 흐름
1. 클라이언트가 HTTP요청을 보냄
사용자가 로그인 요청을 하면 요청이 AuthenticationFilter로 전달됨.
2. AuthenticationFilter가 인증 객체 생성
사용자의 ID와 비밀번호를 포함한 UsernamePasswordAuthenticationToken을 생성.
3. AuthenticationManager에게 인증 요청을 전달
AuthenticationFilter는 AuthenticationManager를 호출하여 인증을 시도.
4. AuthenticationManager가 AuthenticationProvider에게 인증 요청을 위임
AuthenticationManager는 하나 이상의 AuthenticationProvider에게 인증을 수행하도록 위임.
5. UserDetailsService에서 사용자 정보를 조회
AuthenticationProvider는 UserDetailsService를 이용하여 사용자의 정보를 검색.
6. UserDetailsService가 UserDetails 객체를 반환
UserDetailsService는 데이터베이스 또는 기타 저장소에서 사용자를 찾고, UserDetails 객체를 반환.
7. AutenticationProvider가 사용자 정보 검증
UserDetails 객체를 이용해 사용자의 비밀번호를 검증.
8. 인증이 성공하면 Authentication 객체를 생성
인증이 성공하면 Authentication 객체를 생성하여 반환.
9. AuthenticationFilter가 SecurityContextHolder에 인증 정보 저장
Spring Security의 설정(http.authorizeRequests())을 기반으로 접근 가능 여부를 결정.
사용자의 Authentication 객체에서 역할(Role)을 가져와 인가 여부 확인.
java
복사편집
http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") // 관리자만 접근 가능 .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // 일반 사용자, 관리자 가능 .anyRequest().authenticated(); // 그 외 모든 요청은 인증 필요
예를 들어, 다음과 같은 설정이 되어 있다고 가정하면:
5. 접근 승인 또는 거부
승인(Authorized): 사용자의 역할이 요구된 권한과 일치하면, 컨트롤러로 요청을 전달.
거부(Forbidden, 403 에러): 사용자가 필요한 권한이 없으면 AccessDeniedHandler를 통해 403 응답.
Stateful(상태유지) vs Stateless 인증방식 (상태없음)
Stateful이란 유저(클라이언트)의 정보가 서버측에 저장되어 있음을 나타냄.
Stateless이란 유저(클라이언트)의 정보가 클라이언트 측에저장되어 있음을 나타낸다.
서버에 유저의 상태가 저장되어 있지 않다면 서버에 요청을 보낼 때마다 유저의 상태를 반복적으로 전달해야 하므로 성능에도 안 좋고 복잡할 것이라는 생각이 들 수도 있지만
갑자기 클라이언트의 요청이 급증했다고 생각해서 서버를 늘리고 첫번째 요청과 두번째 요청을 처리하는 서버가 다르다고 가정해보자.
그럴경우 매번 필요한 데이터를 전달하는statleless방식이 효율적일 것이다. 상태를 저장하지 않는 쪽에서 훨씬 수월하게 요청을 처리할 수 있을 것이다.
방식
Stateless 인증
Stateful 인증
개념
서버가 사용자 상태(Session)를 유지하지 않음
서버가 세션(Session)에 인증 정보를 저장
사용 방식
JWT, OAuth 2.0
세션(Session), 쿠키(Cookie)
인증 정보 저장 위치
클라이언트(토큰 저장)
서버 (Session 저장소)
스케일링
확장성 뛰어남 (서버가 인증 상태 저장 안 함)
확장성이 낮음 (세션 공유 필요)
예제
REST API, 마이크로서비스
전통적인 웹 애플리케이션 (JSP, Thymeleaf)
JWT(JSON WEB TOKEN)을 사용하면 암호화된 토큰을 클라이언트에 전달하고 이 토큰을 클라이언트에서 바꿀 수 없게 함으로써 효율적으로 stateless를 적용할 수 있다. (단 탈취 위험 존재)
session방식은 서버에 클라이언트의 정보를 저장하고 클라이언트에게 세션 ID를 전달해서 이를 가지고 식별하는 방식이다.
시큐리티는 두 방식 모두 구현이 가능하다.
Stateless (JWT) 방식을 선택해야 하는 경우
REST API, 마이크로서비스 환경
서버 확장이 필요한 경우 (Load Balancing)
OAuth 2.0 / OpenID Connect 기반 인증 사용
클라이언트가 다양한 환경(웹, 모바일, API)에서 접근
Stateful (Session) 방식을 선택해야 하는 경우
단일 서버 또는 작은 규모의 웹 애플리케이션
보안이 중요한 기업 내부 시스템 (권한 변경 즉시 반영 필요)
브라우저 기반 웹 애플리케이션 (CSRF 보호 가능)
OAuth2.0 + JWT 인증
OAuth 2.0 개념
https://hudi.blog/oauth-2.0/
OAuth 2.0은 사용자가 직접 비밀번호를 입력하지 않고도 외부 서비스(예 Google, Facebook, Naver)를 통해 애플리케이션에 안전하게 로그인할 수 있도록 도와주는 권한 부여 프로토콜입니다.
OAuth 2.0 주요 개념
Resource Owner (사용자) → 자신의 리소스(예: 계정 정보)를 보호하고 관리하는 사람
Client (클라이언트) → 리소스에 접근하려는 애플리케이션 (예: 모바일 앱, 웹 앱)
Authorization Server (인가 서버) → 클라이언트에게 Access Token을 발급
Resource Server (리소스 서버) → 실제 데이터를 저장하고 보호하는 서버 (예: API 서버)
OAuth 2.0 인증 흐름
사용자가 클라이언트 애플리케이션에 로그인 요청
클라이언트가 Authorization Server로 인증 요청
Authorization Server가 사용자 인증 후 Access Token 발급
클라이언트가 Resource Server로 요청 시 Access Token을 포함
Resource Server가 Access Token을 검증 후 데이터 제공
2. JWT(JSON Web Token) 개념
JWT 구조 예시 (출처: BizSpring)
JWT는 서버와 클라이언트 간의 인증을 위한 JSON 기반의 토큰입니다. JWT는 Stateless(무상태) 인증에 적합하여 OAuth 2.0과 함께 사용됩니다.