로그인_Spring Security / JWT

jngyoon·2024년 1월 12일
0

혼공일기

목록 보기
24/24

Spring Security

사용자 정의가 가능한 인증 및 액세스 제어 프레임워크
주로 인증(Authentication)과 인가(Authorization)를 다루며, 다양한 보안 관련 기능을 제공함
Spring Security는 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다는 장점이 있음

주요 기능

1. 인증(Authentication)
	사용자가 본인이 맞는지 확인하는 과정으로, 아이디/비밀번호, 토큰, 소셜 미디어 연동 등 다양한 인증 방식을 지원합니다. 
    Spring Security는 사용자의 인증 정보를 관리하고 검증하여 안전한 인증을 제공합니다.

2. 권한 부여(인가)(Authorization) 
	인증된 사용자에게 어떤 리소스에 접근할 권한이 있는지를 결정하는 기능을 제공합니다. 
    이를 통해 애플리케이션의 보안성을 향상시키고, 특정 리소스에 대한 접근을 제어할 수 있습니다.

3. 세션 관리(Session Management) 
	사용자의 세션을 관리하고, 세션 공격에 대비하여 세션을 안전하게 유지합니다.

4. CSRF(Cross-Site Request Forgery) 방어 
	웹 애플리케이션에서 발생할 수 있는 CSRF 공격을 방어하기 위한 기능을 제공합니다.

5. 암호화와 보안 관련 기능 
	비밀번호 저장 시 안전한 방식으로 암호화하여 보관하고, 
	다양한 보안 헤더 설정 등을 통해 애플리케이션의 보안을 강화합니다.

6. 사용자 관리 
	사용자 계정의 생성, 비밀번호 변경, 잠금/해제 등의 기능을 지원하여 사용자 관리를 용이하게 합니다.
    
Spring Security에서는 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다. 

Principal(접근 주체): 보호받는 Resource에 접근하는 대상
Credential(비밀번호): Resource에 접근하는 대상의 비밀번호

주요 모듈

SecurityContextHolder

보안 주체의 세부 정보를 포함하여 응용프래그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장된다. 
SecurityContextHolder는 기본적으로
SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 방법과
SecurityContextHolder.MODE_THREADLOCAL 방법을 제공한다.

SecurityContext

Authentication을 보관하는 역할을 하며, 
SecurityContext를 통해 Authentication 객체를 꺼내올 수 있다.

Authentication

Authentication는 현재 접근하는 주체의 정보와 권한을 담는 인터페이스이다. 
Authentication 객체는 Security Context에 저장되며,
SecurityContextHolder를 통해 SecurityContext에 접근하고, 
SecurityContext를 통해 Authentication에 접근할 수 있다.
public interface Authentication extends Principal, Serializable {
    // 현재 사용자의 권한 목록을 가져옴
    Collection<? extends GrantedAuthority> getAuthorities();
    
    // credentials(주로 비밀번호)을 가져옴
    Object getCredentials();
    
    Object getDetails();
    
    // Principal 객체를 가져옴.
    Object getPrincipal();
    
    // 인증 여부를 가져옴
    boolean isAuthenticated();
    
    // 인증 여부를 설정함
    void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

JWT

JWT(JSON Web Token)는 웹에서 정보를 안전하게 전송하기 위한 토큰 기반의 인증 방식
클라이언트와 서버 간의 정보를 안전하게 주고받기 위해 사용됨
JSON형식으로 표현하며, 암호화된 서명(signature)을 포함하여 안전성을 보장함

JWT 구조

Header(헤더)

토큰의 유형 및 사용되는 암호화 알고리즘에 대한 정보를 담음
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload(내용)

토큰에 포함되는 클레임(claim) 정보를 담음
클레임은 토큰에 담기는 정보의 한 조각을 의미함 

등록된 클레임(Registered claims): 토큰에 대한 정보를 제공하는 데 사용되는 클레임으로, 예를 들면 발급자, 만료 시간 등이 있음
공개 클레임(Public claims): 사용자 정의 클레임으로, 토큰을 사용하는 서비스 간의 공유 정보를 전달하기 위해 사용됨
비공개 클레임(Private claims): 서버와 클라이언트 간의 사용자 정의 정보를 전달하기 위해 사용돰
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Signature(서명)

헤더와 페이로드의 내용을 인코딩한 후, 서버에서 관리하는 비밀 키를 사용하여 서명함
이 서명은 토큰이 변경되지 않았음을 검증하기 위해 사용됨

과정

1. 로그인 요청 -> 서버에서 Header, Payload, Signature를 정의하고 인코딩 후 한 번 더 암호화하여 JWT 생성 -> 쿠키에 담아 클라이언트에게 전송
2. 클라이언트는 JWT를 로컬 스토리지 등에 저장하고 API 서버에 요청할 때 헤더에 토큰을 담아 전송
3. 해당 JWT를 서버에서 일치 여부 확인 후 인증 여부 체크 -> 인증 성공시 완료 응답 전송
4. 클라이언트가 서버에 요청했는데 토큰의 기간이 만료된 상태이면, 
	리프레시 토큰을 이용하여 새로운 토큰을 발급

0개의 댓글