
템플릿 엔진의 일종
순수 HTML을 최대한 유지 (네츄럴 템플릿)
SSR 방식
보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크
인증(Authentication) : 식별 가능한 정보를 통해 사용자의 신원을 확인하는 절차
인가(Authorization) : 인증된 사용자가 리소스에 접근 시 권한 부여
인증과 권한 처리를 필터들의 집합인 FilterChain 형태로 처리
다음과 같은 Flow로 동작

UsernamePasswordAuthenticationFilter을 이용한 인증 과정
인증 요청시 UsernamePasswordAuthenticationFilter 에서 Request의 username, password를 통해 UsernamePasswordAuthenticationToken 생성
AuthenticationManager의 구현체인 ProviderManager에게 인증 책임을 위임
ProviderManager는 해당 인증을 위한 Provider에게 인증 책임을 위임
해당 Provider는 인증 절차를 수행하며, 빈으로 등록한 UserDetailsService로 부터 해당 정보를 가진 사용자의 정보를 받아와 인증 절차 수행.
인증 성공 후 Principal(인증된 사용자 객체), Credentials(자격 증명), Authorities(접근 권한)등 을 담은 Authentication 객체를 생성
SecurityContextHolder 객체 안의 SecurityContext에 저장하여 전역적으로 사용

@Configuration
@RequiredArgsConstructor
public class WebSecurityConfig {
private final UserDetailsServiceImpl userDetailsServiceImpl;
// 스프링 시큐리티 기능 비활성화 부분 설정
@Bean
public WebSecurityCustomizer configure() {
return (web) -> web.ignoring()
//.requestMatchers(toH2Console())
.antMatchers("/static/**");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests()
.antMatchers("/login", "/signup", "/user").permitAll()
.anyRequest().authenticated()
.and()
.formLogin() // 폼 로그인 방식 사용
.loginPage("/login")
.defaultSuccessUrl("/articles")
.and()
.logout() // 로그아웃 설정
.logoutSuccessUrl("/login")
.invalidateHttpSession(true) // 찾아보기
.and()
.csrf().disable()
.build();
}
// 인증 관리자 관련 설정
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http, BCryptPasswordEncoder bCryptPasswordEncoder, UserDetailService userDetailService) throws Exception {
return http
.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userDetailService)
.passwordEncoder(bCryptPasswordEncoder)
.and()
.build();
}
// 패스워드 인코더로 사용할 빈 등록
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
@RequiredArgsConstructor
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
System.out.println("email = " + email);
System.out.println(userRepository.findByEmail(email).get().getPassword());
return userRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("not found email"));
}
}
-- 진행 중