shinsunyoung / springboot-developer

📚 <스프링부트 3 백엔드 개발자 되기> 예제코드
222 stars 87 forks source link

[Chapter 10] 10.3.4 질문드립니다. #53

Closed SummerToday closed 5 months ago

SummerToday commented 6 months ago

10.3.4 OAuth2 설정 파일 작성하기 다음 코드 중 (교재 276p~)

@RequiredArgsConstructor
@Configuration
public class WebOAuthSecurityConfig {

    private final OAuth2UserCustomService oAuth2UserCustomService;
    private final TokenProvider tokenProvider;
    private final RefreshTokenRepository refreshTokenRepository;
    private final UserService userService;

    @Bean
    public WebSecurityCustomizer configure() { //
        return (web) -> web.ignoring()
                .requestMatchers(toH2Console())
                .requestMatchers("/img/**", "/css/**", "/js/**");
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .httpBasic(AbstractHttpConfigurer::disable)
                .formLogin(AbstractHttpConfigurer::disable)
                .logout(AbstractHttpConfigurer::disable);

        http.sessionManagement(sessionManagement -> sessionManagement
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        http.authorizeHttpRequests(request -> request
                .requestMatchers("/api/token").permitAll()
                .requestMatchers("/api/**").authenticated()
                .anyRequest().permitAll());

        http.oauth2Login(oauth2Login -> oauth2Login
                .loginPage("/login")
                .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint
                        .authorizationRequestRepository(oAuth2AuthorizationRequestBasedOnCookieRepository()))
                .successHandler(oAuth2SuccessHandler())
                .userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint
                        .userService(oAuth2UserCustomService)));

        http.logout(logout -> logout
                .logoutSuccessUrl("/login"));

        http.exceptionHandling(exceptionHandling -> exceptionHandling
                .defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
                        new AntPathRequestMatcher("/api/**")));

        return http.build();
    }

    @Bean
    public OAuth2SuccessHandler oAuth2SuccessHandler() {
        return new OAuth2SuccessHandler(tokenProvider,
                refreshTokenRepository,
                oAuth2AuthorizationRequestBasedOnCookieRepository(),
                userService
        );
    }

    @Bean
    public TokenAuthenticationFilter tokenAuthenticationFilter() {
        return new TokenAuthenticationFilter(tokenProvider);
    }

    @Bean
    public OAuth2AuthorizationRequestBasedOnCookieRepository oAuth2AuthorizationRequestBasedOnCookieRepository() {
        return new OAuth2AuthorizationRequestBasedOnCookieRepository();
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 이 부분으로 통해서 tokenAuthenticationFilter 필터를 UsernamePasswordAuthenticationFilter 앞에 추가하는데 왜 UsernamePasswordAuthenticationFilter 앞에 추가하는지 잘 모르겠습니다.. 이 부분 조금만 더 자세히 설명해주실 수 있을까요??

감사합니다.

shinsunyoung commented 5 months ago

UsernamePasswordAuthenticationFilter는 사용자의 아이디, 비밀번호를 추출해 이를 기반으로 인증을 진행하는데요. 이 필터는 form으로 로그인을 할 때 주로 사용되기 때문에 토큰 기반 인증을 하려면 필터 하나를 커스텀하게 추가해야 합니다. 그게 TokenAuthenticationFilter 인거구요.

TokenAuthenticationFilter를 사용해서 직접 SecurityContextHolder에 등록함으로서 UsernamePasswordAuthenticationFilter에서 아이디, 비밀번호가 추출되지 않더라도 인증 처리를 하기 위해 일반적으로 표준 인증 필터(UsernamePasswordAuthenticationFilter)보다 먼저 실행됩니다. 혹시 더 궁금하신거 있으면 추가 코멘트로 남겨주세요! 감사합니다.

SummerToday commented 5 months ago

그럼 기존 필터의 UsernamePasswordAuthenticationFilter 앞단에 TokenAuthenticationFilter가 추가되면 전체적인 인증 과정은 어떻게 되나요?? 기존의 필터가 순차적으로 적용되는 인증 과정과 같이 TokenAuthenticationFilter가 적용되고 난 후 뒤에 있는 필터들이 순차적으로 적용 되는건가요??

shinsunyoung commented 5 months ago

네 맞습니다. addFilterBefore()는 단순히 특정 필터 앞에 실행할 필터를 지정하는 것이지 다른 필터를 없애거나 하진 않습니다

SummerToday commented 5 months ago

감사합니다!!