Spring Boot - 4. Spring Security deprecated 코드로 인한 오류 해결

Bloooooooooooooog..·2023년 5월 8일

스프링 시큐리티 6.0

스프링부트에서 스프링 시큐리티를 이용해서 로그인 페이지를 구현하고 있었다. 시큐리티가 일반적으로 이동시키는 인증 화면이 아닌 개인이 구현한 로그인 페이지 구현을 위해서 아래와 같은 코드가 쓰였다.

@Configuration // IoC
public class SecurityConfig {
	

	@Bean
	SecurityFilterChain configure(HttpSecurity http) throws Exception {
		http
				.authorizeRequests()
				.antMatchers("/auth/**").permitAll()
				.anyRequest().authenticated()
				.and()
				.formLogin().loginPage("/auth/loginForm");

		return http.build();
	}

}

authorizeRequests() : 시큐리티 처리에 HttpServletRequest를 사용한다는 것을 의미
antMatchers("주소") : 지정한 주소에 대해 예외를 두어 설정
permitAll() : 앞에 지정한 주소를 모두에게 접근 허가
anyRequest().authenticated() : 다른 어떤 접근에도 보안 검사를 한다.
formLogin().loginPage("주소") : 로그인 페이지로 주소값으로 이동 설정

문제는 2023년 5월 기준으로 2개월 전의 코드를 보고 공부하고 있었는데도 최신 버전에서 사용할 수 없는 코드가 있었다.
configuration을 bean에 등록해서 필터로 설정을 만드는 과정이었는데, 최신 업데이트에서 .authorizeRequests()와 antMatchers() 더 이상 사용이 불가능했다.

수정된지 얼마 되지 않아서 구글링에서도 딱히 큰 정보가 나오지 않아 chatGPT에도 쳐보고 난리를 치고, 원문 업데이트 로그를 보면서 일단 수정을 했다.

@Configuration // IoC
public class SecurityConfig {
	@Bean
	SecurityFilterChain configure(HttpSecurity http) throws Exception {
		http
				.authorizeHttpRequests()
				.requestMatchers("/auth/**").permitAll()
				.anyRequest().authenticated()
				.and()
				.formLogin().loginPage("/auth/loginForm");

		return http.build();
	}

}

리디렉트 반복 접근

업데이트 사항대로

authorizeRequest() => authorizeHttpRequests()로 수정
antMatchers() => requestMatchers()로 수정

이렇게 하였지만 화면에서 리디렉트가 과도하게 요청되었다는 오류만 떴다. 분명 /auth 주소 하위는 모두 permitAll()을 설정했음에도 권한이 없어 같은 로그인 주소로 재요청이 무한히 반복되다가 오류가 나는 상황이었다.

해결

스프링시큐리티 6부터는 forward에도 기본으로 인증이 걸리게 설정되었다

해결방안

dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll() 추가

@Configuration // IoC
public class SecurityConfig {
	

	@Bean
	SecurityFilterChain configure(HttpSecurity http) throws Exception {
		http
				.authorizeHttpRequests()
				.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
				.requestMatchers("/auth/**").permitAll()
				.anyRequest().authenticated()
				.and()
				.formLogin().loginPage("/auth/loginForm");

		return http.build();
	}

}
profile
공부와 일상

0개의 댓글