spring 3.x, spring security 6.x.x, h2를 사용하면서 만났던 오류들 정리중

undefined·2023년 12월 7일
0

삽질로그

목록 보기
7/7
  1. h2와 같이 사용할 때
This is because there is more than one mappable servlet in your servlet context: {org.h2.server.web.JakartaWebServlet=[/h2-console/*], org.springframework.web.servlet.DispatcherServlet=[/]}.

새롭게 고통받았던 오류이다.
springboot 3.x 와 h2를 사용할 때 발생하는 이슈라고 한다.

원인은 Spring Security는 Spring MVC 엔드포인트와 일반 AntPath 패턴에 대해 서로 다른 요청 매처를 사용하는데 패턴이 모호해서라고 한다.

Spring MVC 엔드포인트인 경우 requestMatchers(MvcRequestMatcher) 를, 아니면 antMatchers() 를 사용하라고 한다.
requestMatcher(xxxx) 를 AntPathRequestMatcher.antMatcher(xxx) 로 수정해주어서 해결

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .authorizeRequests(request -> request
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/api/v1/auth/**")).permitAll()
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/api/v1/admin/**")).hasAnyAuthority(Role.ADMIN.name())
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/api/v1/user/**")).hasAnyAuthority(Role.USER.name())
                        .anyRequest().authenticated())
                .sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider())
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .headers(h-> h.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
        return http.build();
    }
  1. 비밀번호 인코딩
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"] with root cause

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

비밀번호를 인코딩하지 않고 저장한 경우 발생하는 오류라고 한다.
나의 경우에는 인코딩 객체를 잘못 만들어줘서 발생했었다.

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

처음엔 위처럼 썼었는데 이 매서드는 id를 반환하지 않음. 그래서 id가 null어쩌고 오류가 발생한 것.

따라서

@Bean
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder("bcrypt");
}

이렇게 id를 지정해주거나 (여기서 id는 bcrypt)

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

BCryptPasswordEncoder를 사용하면 된다.

profile
이것저것 하고 싶은 게 많은 병아리 개발자

0개의 댓글