Hyun_dev

Spring Security 흐름 알아보기

9/2/2025

Spring Security 흐름

1. User enters credentials

사용자가 로그인 폼에 정보와 함께 인증 요청

2. Spring Security Filters

모든 인증/인가 요청은 Filter Chain을 통과
AbstractAuthenticationProcessingFilter를 구현한 UsernamePasswordAuthenticationFilter를 활용.

Role

  • 인증 요청 감지 /login POST
  • UsernamePasswordAuthenticationToken 인증용 객체 생성, ProviderManager에 전달
    • 요청으로 받은 username, password를 담음.
  • AuthenticationManager 호출 -> 실제 인증 로직 위임
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (this.postOnly && !request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}
		String username = obtainUsername(request);
		username = (username != null) ? username.trim() : "";
		String password = obtainPassword(request);
		password = (password != null) ? password : "";
		UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
				password);
		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}

3. AuthenticationManager

인증 요청을 실제 인증 로직으로 위임한다.
AuthenticationManager를 구현한 ProviderManager로 위임

Role

  • UsernamePasswordAuthenticationToken을 입력 받는다.
  • 등록된 AuthenticationProvider에게 인증 요청 전달
  • 인증 성공 시, Authentication 객체 반환, 실패 시 AuthenticationException발생

4. AuthenticationProvider

실제 인증 로직을 수행
AuthenticationProvider 인터페이스를 실제로 구현한다.

Role

  • AuthenticationManager로부터 인증 요청을 받음
  • UserDetailsService로 사용자 정보 조회
  • PasswordEncoder로 비밀번호 검증
  • 인증 성공 시, Authentication 객체 반환

SomeAuthenticationProvider

@Component
@RequiredArgsConstructor
public class SomeAuthenticationProvider implements AuthenticationProvider {

  private final SomeUserDetailsService userDetailsService;
  private final PasswordEncoder passwordEncoder;

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = authentication.getCredentials().toString();
    userDetailsService.loadUserByUsername(username);
    UserDetails userDetails = userDetailsService.loadUserByUsername(username);

    if (passwordEncoder.matches(password, userDetails.getPassword())) {
      return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
    } else {
      throw new BadCredentialsException("Invalid password!");
    }
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
  }
}

5. UserDetailsService / UserDetailsManager

SomeAuthenticationProvider 에서 사용하기 위한 사용자 정보를 조회하는 서비스

Role

  • AuthenticationProviderusername을 전달
  • DB 또는 저장소에서 사용자 정보조회
  • UserDetails 객체 반환

SomeUserDetailsService

@Service
@RequiredArgsConstructor
public class SomeUserDetailsService implements UserDetailsService {

  private final CustomerRepository customerRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Customer customer = customerRepository.findByEmail(username).orElseThrow(() -> new
      UsernameNotFoundException("User not found: " + username));

    List<GrantedAuthority> authorities = customer.getAuthorities().stream().map(authority -> new
      SimpleGrantedAuthority(authority.getName())).collect(Collectors.toList());
    return new User(customer.getEmail(), customer.getPwd(), authorities);
  }
}

6. PasswordEncoder

비밀번호 암호화 및 검증 수행
PasswordEncoder를 구현한 구현체를 주로 사용한다.

  • BCryptPasswordEncoder
  • Pbkdf2PasswordEncoder
  • 그 외 등등등.. passwordencode하거나, 저장된 password와 비교하여 일치 여부를 확인한다.

7. Authentication Token

인증 요청 및 인증 결과를 담는 객체
UsernamePasswordAuthenticationToken (폼 로그인 기본) or JwtAuthenticationToken (JWT 기반 인증)

  • 인증 요청 시 -> UsernameAuthenticationToken (isAuthenticated = false)
  • 인증 성공 후 -> Authentication 객체 (isAuthenticated = true)

8. AuthenticationManager 결과 반환

  • 인증 성공 시 -> Authentication 객체 반환
  • 인증 실패 시 -> AuthenticationException 발생

9. Security Context

현재 인증된 사용자 정보 저장

  • SecurityContext
  • SecurityContextHolder 인증 성공 시, SecurityContextHolderAuthentication 저장

10. Filter Chain 종료 & 응답 반환

인증 / 인가 결과에 따라 Controller 호출 또는 예외 처리

  • ExceptionTranslationFilter
  • AccessDeniedHandler
  • AuthenticationEntryPoint

Reference