담비의 개발블로그

[Spring Boot]Security 본문

언어&프레임워크/Spring&Spring Boot

[Spring Boot]Security

담비12 2024. 10. 2. 20:55

 

 

Spring Security 주요 개념

 

1. Authentication (인증): 사용자가 누구인지 확인하는 과정이다. 일반적으로 사용자가 입력한 사용자명과 비밀번호를 사용하여 본인 확인을 한다.

2. Authorization (인가): 사용자가 애플리케이션 내에서 어떤 작업을 수행할 수 있는지 결정하는 과정이다. 예를 들어, 특정 페이지나 API에 접근할 권한을 확인한다.

3. Filter 기반 구조: Spring Security는 필터 체인을 사용하여 보안을 적용한다. SecurityFilterChain이 애플리케이션의 모든 요청을 가로채고 보안 처리를 수행한다.

4. Role 및 Authority: 사용자가 수행할 수 있는 작업이나 접근할 수 있는 리소스를 정의하는 개념이다. Role은 주로 그룹 단위의 권한을 나타내며, Authority는 세부적인 권한을 나타낸다.

 

 

 

Spring Security 설정 방법

 

1. 의존성 추가

Maven

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

 

Gradle

implementation 'org.springframework.boot:spring-boot-starter-security'

 

 

2. 기본 보안 설정

기본적으로 Spring Boot는 username과 password를 사용하여 애플리케이션에 접근할 수 있는 로그인 폼을 제공한다. application.properties 파일에서 사용자와 비밀번호를 설정할 수 있다.

spring.security.user.name=admin
spring.security.user.password=admin123

 

 

3. 커스텀 보안 설정

기본 보안 설정 외에도, SecurityConfig 클래스를 통해 커스텀 설정을 적용할 수 있다. 이를 위해 @EnableWebSecurity 애노테이션을 사용하고, WebSecurityConfigurerAdapter를 확장하여 설정을 오버라이드할 수 있다.

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()  // /public 경로는 누구나 접근 가능
                .antMatchers("/admin/**").hasRole("ADMIN")  // /admin 경로는 ADMIN 권한만 접근 가능
                .anyRequest().authenticated()  // 나머지 모든 요청은 인증 필요
            .and()
            .formLogin()
                .loginPage("/login")  // 커스텀 로그인 페이지 설정
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }
}

 

 

4. 사용자 정의 인증 로직 구현

사용자 정의 인증 로직을 구현하려면 UserDetailsService 인터페이스를 구현하여 사용자 정보를 제공하는 로직을 작성할 수 있다. Spring Security는 이 인터페이스를 사용하여 사용자 정보를 조회하고 인증을 처리한다.

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 데이터베이스에서 사용자 정보 조회
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));

        // 사용자 정보와 권한을 UserDetails로 반환
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getAuthorities());
    }
}

 

5. 비밀번호 인코딩

Spring Security는 비밀번호를 안전하게 저장하기 위해 인코딩을 요구한다. PasswordEncoder를 사용하여 비밀번호를 인코딩할 수 있다. 가장 많이 사용되는 인코더는 BCryptPasswordEncoder다.

import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

 

6. OAuth2 및 JWT 통합

Spring Security는 OAuth2 인증 및 JWT(JSON Web Token)와 같은 토큰 기반 인증도 쉽게 통합할 수 있다. 이를 통해 OAuth2 소셜 로그인이나 JWT 기반 인증을 구현할 수 있다.

 

▶ OAuth2

OAuth2는 권한 부여 프로토콜로, 사용자가 자신의 자격 증명을 제공하지 않고도 제3자 애플리케이션에 자신의 리소스(예: 이메일, 프로필 정보)를 안전하게 액세스할 수 있도록 한다. OAuth2는 주로 소셜 로그인에 사용되며, 대표적으로 구글, 페이스북, 깃허브와 같은 서비스와 통합할 때 사용된다. 쉽게말하면 우리가 어떤 쇼핑몰에 들어가서 로그인이나 회원가입을 할때 "카카오톡 로그인", "네이버로그인"같이 신뢰할 수 있는  어플리케이션의 Open API와 통신하여 카카오와 네이버가 해당 사용자의 인증을 처리해주는 방식이다.

 

JWT

JWT(JSON Web Token)는 세션을 사용하지 않고도 인증 상태를 유지할 수 있는 방법이다. Json 객체에 인증에 필요한 정보들을 담은 후 비밀키로 서명한 토큰으로, 인터넷 표준 인증 방식이다. 공식적으로 인증(Authentication) & 권한허가(Authorization) 방식으로 사용된다.