본문 바로가기
컴공/스프링 부트 (Spring boot)

스프링 부트(Spring Boot) 보안 관리: 스프링 서큐리티

by 만슨 2023. 12. 5.

투표 앱을 만들면서 클라이언트들의 보안 부분을 어떻게 처리해야할 지 고민하고 알아보다가 스프링 서큐리티(Spring Security)를 이용하여  보안(인증, 권한) 부분을 구현하게 되었다.

 

스프링 서큐리티에 대해서 한 번 알아보자!

 

 

1. 스프링 시큐리티(Spring Security)

 

1.1 스프링 시큐리티란?

스프링 시큐리티는 스프링 기반의 애플리케이션에서 보안 관련 작업을 처리하는 프레임워크.인증, 권한 부여, 공격 방어, 보안 설정 관리 등을 간편하게 설정하고 사용할 수 있는 도구이다.

 

우선 스프링 시큐리티의 주요 기능을 한 번 보자

 

 

1.2 주요 기능

 

첫 번째, 

인증(Authentication) : 사용자가 누구인지 확인.
사용자의 아이디/패스워드를 사용한 로그인, 소셜 로그인, 인증서, API 키 등 다양한 인증 방식을 지원.
사용자의 identification을 확인하는 절차

 

두 번째,

인가(Authorization) : 인증된 사용자에게 특정 리소스 또는 기능에 대한 접근 권한을 부여.
역할 기반의 권한 관리와 표현식 기반의 권한 관리를 제공합니다.

 

세 번째,

공격 방어(Cross-Site Scripting, Cross-Site Request Forgery 등) : 웹 애플리케이션에서 발생할 수 있는 다양한 보안 공격에 대응하여 애플리케이션을 보호.

 

네 번째,

세션 관리 : 사용자의 세션을 관리하고, 로그인 상태를 유지하는데 필요한 여러 기능을 제공.

 

 

 

스프링 서큐리티는 위 인증, 인가, 공격 방어, 세션 관리 등의 기능을 쉽게 구현해주는 프레임 워크 이다!

 

 

그럼 스프링 서큐리티가 어떻게 인증을 처리하는지 한 번 살펴보자

 

 

 


2. 인증(Authentication)

 

인증은 사용자가 자신이 주장하는 신원을 확인하는 과정.

 

사용자의 identification을 확인하는 절차

 

스프링 시큐리티에서는 주로 UserDetails와 UserDetailsService 인터페이스를 사용하여 인증을 처리한다.

 

2.1 UserDetails 인터페이스

UserDetails 인터페이스는 사용자의 정보를 나타내며, 다음과 같은 메서드를을 가진다.

getUsername(): 사용자의 아이디를 반환.

 

getPassword(): 사용자의 패스워드를 반환.

 

getAuthorities(): 사용자에게 부여된 권한 목록을 반환.

 

 

 

2.2 UserDetailsService 인터페이스

UserDetailsService 인터페이스는 사용자의 정보를 가져오는 역할을 한다.

 

주로 데이터베이스에서 사용자 정보를 조회하거나 메모리에 저장된 정보를 제공하는 등 다양한 방식으로 사용자 정보를 가져온다.

 

 

loadUserByUsername(String username) 메소드를 통해 사용자의 정보를 불러오는 예시 이다

 

위 loadUserByUsername(String username) 메소드는 인자로 받은 nickname을 통해 사용자를 조회하고, 조회된 사용자의 정보를 UserDetails 타입으로 반환해준다.

이 UserDetails 자료형에는 사용자의 아이디, 패스워드, 권한 등에 대한 정보가 들어 있다

따라서 필요한 사용자 정보를 UserDetails에서 꺼내서 사용하면 되는데 그 때 꺼내 사용하는 매서드가 위에서 봤던 getUsername(), getPassword() 등이 있다.

 

 

여기서 중요한 점

 

getUsername() 메소드가 반환하는 값은 UserDetailsService의 loadUserByUsername 메소드에 전달되는 nickname 값과 일치해야 한다는 것!

 

본인은 프로잭트에서

 

위 사진처럼 @AuthenticationPrincipal 어노테이션을 사용하여 현재 로그인한 유저의 정보를 UserDtails 객체에 담아서 받아오고 

 

 

유저의 닉네임이 담긴 User 필드랑 userDtails.getUsername() 매서드를 비교하여 인증 절차를 구현 하였다!