SecurityConfig.java 3.37 KB
package daeucna.config.security;

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.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import daeucna.config.security.jwt.JwtAccessDeniedHandler;
import daeucna.config.security.jwt.JwtAuthenticationEntryPoint;
import daeucna.config.security.jwt.JwtFilter;
import daeucna.config.security.jwt.JwtTokenProvider;
import lombok.RequiredArgsConstructor;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtTokenProvider tokenProvider;
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    private final JwtAccessDeniedHandler jwtAccessDeniedHandler;

    // PasswordEncoder는 BCryptPasswordEncoder를 사용
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
        		// token을 사용하는 방식이기 때문에 csrf를 disable합니다.
		        .csrf(AbstractHttpConfigurer::disable)
		        .securityMatcher("/api/**")
		        .authorizeHttpRequests((authorizeHttpRequests) ->
	 				authorizeHttpRequests
			            .requestMatchers("/api/admin/**").hasRole("ADMIN")
		                .requestMatchers("/api/authenticate").permitAll() // 로그인 api
		                .requestMatchers("/api/refreshtoken").permitAll() // Refresh Token api
		                .requestMatchers("/api/signup").permitAll() // 회원가입 api
		                .requestMatchers("/api/exceptionDenied").permitAll() // Exception Denied		
//		                .anyRequest().permitAll()
		                .anyRequest().authenticated() // 그 외 인증 없이 접근X
	 			)
		        .exceptionHandling(exceptionHandling -> exceptionHandling
		        		.authenticationEntryPoint(jwtAuthenticationEntryPoint)
	 					.accessDeniedPage("/api/exceptionDenied")
	 					.accessDeniedHandler(jwtAccessDeniedHandler)
				)
	 			.formLogin(Customizer.withDefaults())
		        .headers((headers) ->
					headers
						.frameOptions(frameOptions -> frameOptions
			                     .sameOrigin()
			            )
				)
                // 세션을 사용하지 않기 때문에 STATELESS로 설정
		        .sessionManagement((sessionManagement) ->
					sessionManagement
		                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
		        )
		        .addFilterBefore(new JwtFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
//                .apply(new JwtSecurityConfig(tokenProvider)); // JwtFilter를 addFilterBefore로 등록했던 JwtSecurityConfig class 적용

        return httpSecurity.build();
    }

}