@RequiredArgsConstructor
@Configuration
public class WebSecurityConfig {
private final UserDetailService userService;
// 스프링 시큐리티 비활성화 - a
@Bean
public WebSecurityCustomizer configure() {
return (web) -> web.ignoring()
.requestMatchers(toH2Console())
.requestMatchers("/static/**");
}
// 특정 HTTP 요청에 대한 웹 기반 보안 구성 - b
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests() // 인증, 인가 설정 - c
.requestMatchers("/login", "/signup", "/user").permitAll()
.anyRequest().authenticated()
.and()
.formLogin() // 폼 기반 로그인 설정 - d
.loginPage("/login")
.defaultSuccessUrl("/articles")
.and()
.logout() // 로그아웃 설정 - e
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.and()
.csrf().disable() // csrf 비활성화 - f
.build();
}
// 인증 관리자 관련 설정 - g
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http, BCryptPasswordEncoder bCryptPasswordEncoder, UserDetailService userDetailService) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userService) // 사용자 정보 서비스 설정
.passwordEncoder(bCryptPasswordEncoder)
.and()
.build();
}
// 패스워드 인코더로 사용할 빈 등록 - h
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
일반적으로 정적 리소스(보통 기본적으로 공개되어 있는 데이터)에 대한 요청은 스프링 시큐리티를 비활성화 한다.
특정 HTTP 요청에 대한 웹 기반 보안 구성 - b
특정 HTTP 요청에 대해 웹 기반 보안을 구성하는 클래스이다. 해당 클래스의 메서드에서 인증/인가 및 로그인, 로그아웃 관련 설정을 한다.
폼 기반 로그인 설정 - d
로그아웃 설정 - e
csrf 비활성화 - f
csrf 설정을 비활성화 한다.
하지만, 실제 운영 환경에서는 CSRF 공격에 노출되지 않도록 설정을 하는 것이 좋다.
경우에 따라, 애플리케이션이 API 서버 형태로만 사용되고, 웹 페이지에서의 사용자 입력이 없거나 CSRF 공격 가능성이 적은 경우에는 CSRF 보호 기능을 비활성화 할 수도 있다.
- CSRF 공격
사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 해서 특정 웹페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법이다.
인증 관리자 관련 설정 - g
사용자 정보를 가져올 서비스를 재정의하거나, 인증 방법(LDAP, JDBC 기반 인증, ...)을 설정한다.
- LDAP(Lightweight Directory Access Protocol) 기반 인증
LDAP은 계층적 디렉터리 서비스를 제공하는 프로토콜로, 주로 조직의 사용자 및 리소스 정보를 중앙 집중 적으로 저장하고 관리하는 데 사용된다. Spring Security는 LDAP 서버와 통신하여 사용자의 인증을 확인하고 사용자의 권한을 관리한다.
Spring Security의 LdapAuthenticationProvider를 사용하여 LDAP 기반 인증을 구성한다.
- JDBC 기반 인증
사용자의 인증 정보가 관계형 데이터베이스(RDBMS)에 저장되어 있는 경우에 사용된다. Spring Security는 JDBC를 사용하여 데이터베이스에 연결하고 데이터베이스의 사용자 인증 정보를 확인한다.
Spring Security의 JdbcAuthentication을 사용하여 JDBC 기반 인증을 구성한다.
기업 환경에서 통합 인증이 필요한 경우 LDAP 기반 인증을 사용할 수 있고, 반면에 간단한 사용자 데이터베이스가 이미 구축되어 있는 경우에는 JDBC 기반 인증을 사용할 수 있다.
AuthenticationManager 인터페이스
Spring Security에서 사용자의 인증을 관리하는 데 사용되는 인터페이스이다.
사용자가 제공한 자격 증명(주로 사용자 이름과 비밀번호)을 인증하고, 사용자에 대한 권한 부여를 처리 할 수 있다.
HttpSecurity
Spring Security에서 HTTP 요청에 대한 보안 구성을 설정하는 데 사용된다.
- HttpSecurity를 이용하여 다음과 같은 작업들이 가능하다.
- 인증 설정
사용자의 인증을 처리하는 방법을 설정한다. 예를 들어, 사용자가 로그인을 하고 세션을 유지할지, HTTP Basic 인증을 사용할지 등을 결정할 수 있다.
- 인가 설정
사용자의 접근 권한을 결정하는 방법을 설정한다. 특정한 URL 패턴에 대한 접근 권한을 설정하거나, 특정한 권한을 가진 사용자만 접근을 허용하도록 설정할 수 있다.
- 로그인 설정
사용자의 로그인 페이지, 로그인 성공 후의 리다이렉트 URL 등을 설정한다. 또한 로그아웃 처리 방법도 설정할 수 있다.
- 세션 관리 설정
세션의 생성 및 종료 방법을 설정한다. 세션 고정 공격을 방지하기 위한 세션 ID 변경 등의 보안 기능도 구성할 수 있다.
- CSRF(Cross-Site Request Forgery) 보호 설정
CSRF 공격을 방지하기 위한 기능을 설정한다. CSRF 토큰을 사용하여 요청의 유효성을 검증하거나, 특정한 URL 패턴에 대해 CSRF 보호를 비활성화할 수 있다.
- 헤더 설정
HTTP 헤더를 설정하여 보안 취약점을 방지하거나 보안 정책을 강화할 수 있다.
BCryptPasswordEncoder
비밀번호를 암호화하는 데 사용되는 객체이다. 사용자가 제공한 비밀번호를 해시하여 저장하고, 저장된 비밀번호와 입력된 비밀번호가 일치하는지 확인하는 데 사용된다.
UserDetailService
사용자의 상세 정보를 제공하는 서비스 객체이다. Spring Security는 사용자의 인증을 처리할 때 이 서비스를 사용하여 사용자의 정보를 가져온다. 주로 사용자 정보를 데이터베이스에서 가져오는 역할을 한다.
passwordEncoder
비밀번호를 암호화 하기위한 인코더를 설정한다.
http.getSharedObject()
Spring Security 구성에서 공유 객체를 검색하는 데 사용되는 메서드이다.
패스워드 인코더로 사용할 빈 등록 - h
보안을 강화하기 위해 사용자의 비밀번호를 평문으로 저장하지 않고, BCryptPasswordEncoder와 같은 암호화 기법을 사용하여 저장한다.
BCryptPasswordEncoder
Spring Security에서 사용되는 패스워드 인코더 중 하나로, 비밀번호를 안전하게 저장하기 위해 BCrypt 해시 함수를 사용한다.
- BCrypt
Blowfish 암호화 기법을 기반으로 하는 해시 함수이다.