728x90
ERROR 30400 --- [auth-service] [io-19095-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Filter execution threw an exception] with root cause
java.lang.StackOverflowError: null
모놀리틱에서 msa로 전환을 시도해보았다.
모놀리틱에서는 잘되던 Authentication 필터에서 저 에러가 발생했다.
해결
https://kwakscoding.tistory.com/51
[스프링부트] 멀티인증 AuthenticationManager + Stackoverflow feat. UserDetailsService 무한재귀오류 해결
나는 REST-API용 로그인을 구축해놓은 상태에서 어드민 페이지를 추가로 만들어야 하는 상황이였다.보통 admin과 rest-api용 서버는 따로 나누지만 나같은경우 서버비용 절약 및 규모가 작은 프로젝
kwakscoding.tistory.com
근데 나는 반대로 UserDetailsService가 없어서 에러가 난 것이었다.

🔍 Spring Security에서 AuthenticationManager가 하는 역할
1️⃣ AuthenticationManager는 Spring Security에서 사용자 인증을 담당하는 인터페이스
- AuthenticationManager는 사용자의 인증 요청(아이디/비밀번호 로그인, JWT 토큰 인증 등)을 처리하고, 성공하면 Authentication 객체를 반환합니다.
2️⃣ 기본적으로 SecurityFilterChain이 AuthenticationManager를 자동으로 구성해야 하지만, Spring Boot 3 & Security 6에서는 기본 설정이 없음
- 이전 버전(Spring Boot 2.x, Security 5.x)에서는 자동 설정이 포함되어 있어서 AuthenticationManager를 별도로 등록하지 않아도 동작했음.
- 하지만 Spring Boot 3.x & Spring Security 6.x부터는 자동으로 AuthenticationManager를 등록하지 않기 때문에, 명시적으로 @Bean으로 등록해야 함.
✅ 코드 분석
- DaoAuthenticationProvider를 생성
- DaoAuthenticationProvider는 Spring Security의 기본 인증 제공자로, UserDetailsService와 PasswordEncoder를 사용하여 아이디/비밀번호 인증을 수행합니다.
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailsService); provider.setPasswordEncoder(passwordEncoder());- provider.setUserDetailsService(userDetailsService); → UserDetailsServiceImpl을 이용해서 사용자 정보를 가져옴.
- provider.setPasswordEncoder(passwordEncoder()); → 비밀번호를 암호화하고 비교할 PasswordEncoder를 설정.
- ProviderManager를 이용해 AuthenticationManager를 생성
- ProviderManager는 여러 개의 AuthenticationProvider를 관리하는 Spring Security의 인증 관리자입니다.
return new ProviderManager(provider);- 여기서는 DaoAuthenticationProvider 하나만 사용하지만, 필요하면 다른 AuthenticationProvider도 추가할 수 있음.
- Spring Security가 AuthenticationManager를 찾을 수 있도록 @Bean으로 등록
- @Bean으로 등록하면 Spring Security가 AuthenticationManager를 주입받을 수 있기 때문에 authenticationManager must be specified 오류가 해결됨.
🔍 UserDetailsImpl과 UserDetailsServiceImpl의 역할 차이
✅ 1. UserDetailsImpl (사용자 정보 저장 및 관리)
- Spring Security가 사용자 정보를 다룰 수 있도록 커스텀 UserDetails 구현체입니다.
- 데이터베이스에서 가져온 사용자 정보를 Spring Security가 이해할 수 있는 객체로 변환하는 역할을 합니다.
✅ 2. UserDetailsServiceImpl (사용자 정보 조회 및 반환)
- Spring Security에서 사용자 정보를 가져올 때 호출되는 UserDetailsService의 구현체입니다.
- DB에서 username으로 사용자 정보를 조회하고, 조회된 정보를 UserDetailsImpl 객체로 변환하여 반환합니다.
더보기
Spring Security 인증 과정에서 UserDetailsImpl과 UserDetailsServiceImpl의 역할
✅ 1. 로그인 요청 (/auth/signIn)
- 클라이언트가 username과 password를 입력하여 로그인 요청을 보냄.
✅ 2. JwtAuthenticationFilter가 요청을 가로챔
- JwtAuthenticationFilter에서 authenticationManager.authenticate()를 호출.
- UsernamePasswordAuthenticationToken을 생성하여 Spring Security의 AuthenticationManager에게 인증 요청.
✅ 3. AuthenticationManager가 UserDetailsServiceImpl.loadUserByUsername() 호출
- UserDetailsServiceImpl이 username으로 사용자를 DB에서 조회.
✅ 4. UserDetailsImpl을 반환
- 조회된 사용자 정보를 UserDetailsImpl 객체로 변환하여 반환.
✅ 5. 비밀번호 검증
- DaoAuthenticationProvider가 입력된 비밀번호와 DB에서 가져온 비밀번호를 비교.
✅ 6. 인증 성공 시 SecurityContextHolder에 저장
- SecurityContextHolder.getContext().setAuthentication(auth)를 호출하여 인증된 사용자 정보를 저장.
728x90
'TIL' 카테고리의 다른 글
spring cloud - Gateway (0) | 2025.03.11 |
---|---|
@NoArgsConstructor,@AllArgsConstructor와(access=AccessLevel.PROTECTED) + @Builder (0) | 2025.03.10 |
Delivery프로젝트_5. (Trouble Shooting) JPA 연관관계 (단방향, 양방향) (0) | 2025.02.20 |
Delivery프로젝트_6. 단위테스트와 통합테스트 (1) | 2025.02.19 |
Delivery프로젝트_5.(Trouble Shooting)AOP/프록시객체/Lazy Loading (0) | 2025.02.18 |