import jakarta.servlet.DispatcherType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
@EnableMethodSecurity(securedEnabled = true)
@EnableWebSecurity // Spring Security 설정을 활성화 - 스프링 시큐리티 필터가 필터 체인에 등록됨
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable) // CSRF 보안 토큰 disable처리.
.authorizeHttpRequests(request -> request
.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
.requestMatchers("/", "/loginForm/**", "/joinForm/**", "/info/**").permitAll()
.requestMatchers("/manager/**").hasAnyRole("MANAGER", "ADMIN")
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(login -> login
.loginPage("/loginForm") // 로그인 페이지
.loginProcessingUrl("/login") // login이 호출되면 시큐리티가 낚아채서 대신 로그인을 진행해줌
.defaultSuccessUrl("/") // 로그인이 정상적으로 완료되면 "/"로 이동
// .loginProcessingUrl("/loginForm")
.usernameParameter("username")
.passwordParameter("password")
)
.logout(withDefaults()); // 로그아웃은 기본설정으로 (/logout으로 인증해제)
// .logout((logout) -> logout
// .logoutSuccessUrl("/loginForm")
// .permitAll()
// );
return http.build();
}
@Bean // 비밀번호 암호화
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
=======================================================================
* 인가
특정한 경로에 요청이 오면 Controller 클래스에 도달하기 전 필터에서 Spring Security가 검증을 함
- 해당 경로의 접근은 누구에게 열려 있는지
- 로그인이 완료된 사용자인지
- 해당되는 role을 가지고 있는지
((죄근 설정 - 간단 설정))
@Configuration // 설정 파일로 선언
@EnableWebSecurity // Spring Security를 활성화
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 상단에서 부터 순서대로 적용되므로, 순서에 주의하여 작성!!
// 3.1.X 버전 부터 람다형식 표현 필수!!
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "login").permitAll() // /, /login 경로는 모든 사용자에게 허용
.requestMatchers("/admin").hasRole("ADMIN") // /admin 경로는 ADMIN 권한을 가진 사용자에게만 허용
.requestMatchers("/my/**").hasAnyRole("ADMIN", "USER") // /my/** 경로는 ADMIN, USER 권한을 가진 사용자에게만 허용
.anyRequest().authenticated()
);
// 사용자 정의 로그인 설정
http
.formLogin((auth) -> auth.loginPage("/login") // 로그인 페이지 경로
.loginProcessingUrl("/login_proc") // 로그인 Form Action 경로
.permitAll() // 로그인 페이지는 모든 사용자에게 허용
);
// csrf 설정(기본적으로 활성화 되어있음 --> 개발시 비활성화 권장 --> 운영시 활성화 권장)
http
.csrf((auth) -> auth.disable());
return http.build(); // 설정한 내용을 적용
}
// 패스워드 암호화를 위한 빈 등록
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // BCryptPasswordEncoder 객체 반환
}
}