주뇽's 저장소
[Spring Security] 스프링 시큐리티 커스터마이징 Spring Security Filter Chain 본문
스프링 시큐리티 필터 체인 설정
스프링 시큐리티(Spring Security)는 자바(Java) 기반의 애플리케이션을 위한 강력한 인증 및 접근 제어 프레임워크다. 스프링 프레임워크(Spring Framework)의 일부로, 웹 애플리케이션과 메소드 수준의 보안을 제공한다. 이는 애플리케이션의 보안을 강화하기 위해 맞춤화하고 확장할 수 있는 다양한 기능들을 포함하고 있다.
주요 특징
- 인증(Authentication): 사용자가 누구인지 확인하는 과정이다. 스프링 시큐리티는 다양한 인증 메커니즘을 지원하며, 이를 통해 사용자 이름과 비밀번호, 토큰 기반 인증, LDAP, OAuth 등 다양한 방식으로 인증을 수행할 수 있다.
- 권한 부여(Authorization): 인증된 사용자가 특정 자원에 접근하거나 특정 작업을 수행할 수 있는 권한을 가지고 있는지 결정하는 과정이다. 역할 기반 접근 제어(RBAC)를 포함해 다양한 접근 제어 모델을 지원한다.
- 세션 관리(Session Management): 사용자 세션을 관리하며, 동시 세션, 세션 고정 보호, 세션 만료 등의 기능을 제공한다.
- CSRF(Cross-Site Request Forgery) 보호: 웹 애플리케이션을 CSRF 공격으로부터 보호한다. 이는 사용자가 의도하지 않은 작업을 수행하도록 만드는 공격을 막아준다.
- CORS(Cross-Origin Resource Sharing): 다른 도메인에서의 자원 접근을 안전하게 허용하는 방법을 제공한다.
- LDAP(Lightweight Directory Access Protocol) 통합: 디렉토리 서비스와의 통합을 지원하여 사용자 인증 및 권한 부여에 LDAP 서버를 사용할 수 있다.
- OAuth 및 OpenID Connect 지원: 외부 서비스를 이용한 인증 방식을 지원하여, 소셜 로그인 같은 기능을 구현할 수 있다.
사용 방법
스프링 시큐리티는 spring-boot-starter-security 의존성을 프로젝트에 추가함으로써 쉽게 통합할 수 있다. 기본 설정은 많은 보안 기능을 자동으로 제공하지만, SecurityFilterChain을 정의해줌으로 세부적으로 커스텀 할 수있다.
아래는 기본적인 Filter를 커스텀한 것이다. 모든 설정은 람다식으로 해야한다.
package com.spring_react_board_study.spring_react_board.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SpringConfig {
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/login", "/signup").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("/api/v1/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);
http.httpBasic(Customizer.withDefaults());
http.sessionManagement(
session -> session.sessionCreationPolicy
(SessionCreationPolicy.STATELESS));
http.csrf(AbstractHttpConfigurer::disable);
http.headers().frameOptions().sameOrigin();
return http.build();
}
}
0. 기본 Bean 설정
- @Configuration: 이 클래스가 스프링의 설정 클래스임을 나타낸다
- @EnableWebSecurity: 이 어노테이션은 웹 보안을 활성화한다.
1. 보안 필터 체인
- SecurityFilterChain: HTTP 요청에 대한 보안 처리를 정의한다. HttpSecurity 객체를 사용하여 HTTP 보안 구성을 커스터마이징한다.
1-1 authorizeHttpRequests(): HTTP 요청에 대한 보안 규칙을 정의한다.
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/login", "/signup").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("/api/v1/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);
- .requestMatchers(...).permitAll(): 특정 경로들에 대해 모든 사용자의 접근을 허용한다.
- 홈페이지, 로그인, 회원가입 페이지에 대해서는 인증없이 접근이 가능해야 한다.
- .requestMatchers("/admin").hasRole("ADMIN"): "/admin" 경로에는 "ADMIN" 역할을 가진 사용자만 접근할 수 있다.
- .requestMatchers("/api/v1/**").hasAnyRole("USER", "ADMIN"): "/api/v1/**" 경로에는 "USER" 또는 "ADMIN" 역할을 가진 사용자가 접근할 수 있다.
- anyRequest().authenticated() : 이외 모든 접근에 대해서는 인증을 진행한다.
- 위 필터들은 순차적으로 실행되므로 순서에 유의 하도록 하자.!
1-2 httpBasic(): 기본 HTTP 인증을 사용한다.
http.httpBasic(Customizer.withDefaults());
JWT로 바꿀 경우 필요없을듯
1-3 sessionManagement(): 세션 관리 설정을 정의한다. 여기서는 SessionCreationPolicy.STATELESS를 사용하여 세션을 생성하지 않는다.
http.sessionManagement(
session -> session.sessionCreationPolicy
(SessionCreationPolicy.STATELESS));
- JWT로 RestFull하게 인증을 진행할 경우 세션을 생성하지 않아도 된다.(View를 React나 다른 프레임워크를 사용할 경우)
1-4 csrf().disable(): CSRF(Cross-Site Request Forgery) 보호 기능을 비활성화한다.
http.csrf(AbstractHttpConfigurer::disable);
- CSRF : 세션이 남아있는 경우에 대한 PUT, POST, DELETE 요청에 대한 보호
- Stateless한 RestAPI를 사용하는 경우 CSRF를 비활성화 해도 보안상 큰 문제가 없다.
1-5 headers().frameOptions().sameOrigin(): 클릭재킹 방지를 위한 설정이다. 동일 출처의 프레임에서만 응답을 허용한다.
http.headers().frameOptions().sameOrigin();
- h2 데이터베이스를 사용하는경우 프레임이 안보이는 문제를 해결하기 위한 코드이며 h2-consle을 사용하지 않는다면 필요 없는 코드이다.
참고
RESTful API는 상태가 없는(stateless) 특성을 가진다. 즉, 각 요청은 독립적이며 이전 상태를 기억하지 않는다. JWT를 사용한 인증은 이 원칙을 따른다. 클라이언트는 각 요청마다 JWT를 전송하며, 서버는 세션을 유지할 필요 없이 토큰을 검증하여 요청을 처리한다.
'웹개발 > SpringBoot' 카테고리의 다른 글
[Spring] [GPT] Spring Boot에서 OpenAI API를 이용하여 GPT 연동하기 (2) | 2024.02.18 |
---|---|
[Troubleshooting] Spring Boot 양방향 관계를 가지고 있는 엔티티로 인한Jackson 무한 루프 문제 (4) | 2024.01.04 |
[JUnit] 단위 테스트 (0) | 2023.12.21 |