Spring

[Spring] Spring Security 기본 개념(JWT / OAuth 2.0 / 동작방식 / 구성요소)

do_hyuk 2023. 11. 6. 23:49

이번엔 Spring Security의 기본 개념에 대해 공부했다.

1. JWT(Jason Web Token)

유저 인증, 식별하기 위한 토큰 기반의 인증에 쓰인다.

 

- 구조

  • 헤더(Header)
    • 타입(Type) : 항상 JWT
    • 알고리즘(alg)
  • 페이로드 (Payload) : 사용자 정보 담김
  • 서명 (Verify Signature)

- 동작 방식

  1. 클라이언트 측에서부터 서버 측으로 JWT 받음
  2. 서버 측의 비밀 값과 JWT의 헤더, 페이로드를 alg에 넣고 서명값과 같은지 확인
  3. 같다면 유저에 인가한다.

- 특징

  • 시간에 따라 상태 값이 달라지지 않음(Stateless)
  • 서버가 통제하지 않아 여러 사용자가 같은 JWT로 여러 요청 보내도 추적 불가능

- 종류

  • Access Token : 인가받았을 때 쓰는 수명이 짧은 토큰
  • Refresh Token : Access Token을 재발급받을 때 쓰는 수명이 긴 토큰(DB에 저장, 관리)

2. OAuth

사용자들이 특정 사이트에 직접 회원가입 및 비밀번호를 제공하지 않고 접근하기 위해 권한을 부여받는 수단으로 사용되는 방식

✅회원 관리 기능(회원 가입, 로그인, 비밀번호 찾기 등) 구현 시 신경 써야 할 부분들을 대신 개발, 관리 편함

  • 인증 Authentication : 해당 사용자가 본인이 맞는지 판단 (사용자 신원 확인)
  • 인가 Authorization : 인증된 사용자가 요청한 자원에 권한이 있는지 판단 (사용자 권한 위임)

- OAuth 1.0

  • 역할
    • Resource Owner
    • OAuth Client
    • OAuth Server
  • 동작방식
    • 1. Client에서 Server로 요청
    • 2. 인증, 인가 처리
    • 3. Client에서 Resource Owner에게 전달(인증)
    • 4. Server에서 Resource Owner 확인받음(인가)
    • 5. Server에서 Client로 접근 = JWT 발급
  • 문제점
    • Scope 개념 없음(Scope : 유저 토큰(JWT)을 통해 데이터를 얻어오는 범위)
    • 토큰의 유효 기간 문제
    • 역할이 정확히 나눠져있지 않음
    • Client 구현 복잡
    • 제한적인 웹 환경(정적 리소스)

- OAuth 2.0

  • 바뀐 점
    • Scope 기능 추가 : 해당 토큰에 대한 접근 제한 범위 설정
    • client 구현 복잡성 간소화 -> Bearer Token + TLS
    • 토큰 탈취 문제 개선 -> Access Token + Refresh Token
    • 동적 리소스 웹 환경까지 확장

스프링 5와 vue.js2로 시작하는 모던 웹 애플리케이션 개발 357p


3. Spring Security

https://docs.spring.io/spring-security/reference/index.html

 

Spring Security :: Spring Security

If you are ready to start securing an application see the Getting Started sections for servlet and reactive. These sections will walk you through creating your first Spring Security applications. If you want to understand how Spring Security works, you can

docs.spring.io

Spring에서 필터를 사용해 유저 인증 / 인가 등 보안 기능을 쉽게 하도록 제공하는 프레임 워크

✅ 모든 요청이 인증되어야 자원에 접근 가능해짐 (메서드 단위 권한 부여)

 

-  주요 제공 기능

  • 애플리케이션과의 모든 상호작용을 위해 인증된 유저 요청
  • 기본 로그인 폼 제공
  • BCrypt로 저장된 비밀번호 보호
  • CSRF 공격 방지

-  구조

> FilterChain : Servlet 컨테이너가 관리하는 ApplicationFilterChain( =/= SecurityFilterChain)

1. 클라이언트가 애플리케이션에 요청을 보냄

2. 컨테이너는 Filter 인스턴스와 Servlet(요처 URI 기반의 HttpServletRequest를 진행)를 포함한 FilterChain 생성

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
	
    // do something before th rest of the application
    chain.doFilter(request, response);
    // invoke the rest of the application
    // do something after the rest of the application
}

 

> DelegatingFilterProxy : Servlet 컨테이너의 라이프사이클과 스프링 ApplicationContext 사이의 연결을 허용하는 필터 구현체

(= Servlet 컨테이너와 Spring IOC 컨테이너 사이의 연결해 주는 역할)

DelegatingFilterProxy

> FilterChainProxy : SecurityFilterChain을 통해 많은 필터 인스턴스를 위임하게 해주는 특별한 필터

FilterChainProxy

> SecurityFilterChain : FilterChainProxy에 의해 스프링 시큐리티 필터 인스턴스가 현재 요청을 호출하도록 함

SecurityFilterChain

SecurityFilterChain 여러 개 사용하는 경우

Multiple SecurityFilterChain

 

- 요처 처리 구성 요소

HTTP 요청이 서버에 들어오면 DelegatingFilterProxy를 통해 Spring Security Filter Chain이 생성된다.

이는 요청 단위의 보안을 제공하는데 이 작업의 요청이 어떻게 처리되어야 하는지 결정된다.

모든 필터를 통과하면 각 요청은 등록된 Controller로 도달한다.

이후 서비스단으로 가기 전에 스프링 시큐리티는 AOP를 통해 메서드 단위로 권한 부여를 수행한다.

 

- 핵심 개념

  • Authentication : 인증된 사용자 객체 (현재 로그인된 사용자)
  • GrantedAuthority : 사용자에게 부여된 권한
  • SecurityContext : Authentication 객체를 캡슐화하는 인스턴스
  • SecurityContextHolder : 권한 부여를 수행할 때 사용

Maven

<dependency>	
    <groupId>org.springframwork.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

Gradle

dependencies{
	compileOnly "org.springframework.boot:spring-boot-starter-security"
}

 

의존성 추가 후 서버를 실행하면 이렇게 자동으로 security password가 생성된다.

 

그리고 기본 포트로 접속하면 로그인 창이 뜬다. 이는 스프링 시큐리티로 인해 그 어떤 요청을 하든 인증을 해야 접근할 수 있게 된 것이다.

 

아이디는 user, 비밀번호는 생성한 대로 적어 sign in을 해줘야 내가 설정한 대로 요청-응답이 된다.

아직 기본 화면조차 만들지 않아 404 에러가 뜨는 모습

 

application.properties에서 내가 직접 스프링 시큐리티 이름과 비밀번호를 설정해 줄 수도 있다.

spring:
  security:
    user:
      name: user
      password: 1234

 

- 세션

인증된 사용자에게 스프링 시큐리티는 세션 ID를 발급하고 이를 통해 관리한다.

 

- 스프링 시큐리티 설정

: WebSecurityConfigurerAdapter 상속해 커스텀 설정

✅ 커스텀 된 FilterChainProxy가 추가되는 것

 

OAuth 로그인 관련 설정도 여기서 해준다.