본문 바로가기
Spring/Spring

[Spring Security] 스프링 시큐리티 인증 아키텍처

by 작은돼지 2023. 6. 7.

 

https://www.javainuse.com/webseries/spring-security-jwt/chap3

 

로그인을 예시로 스프링 시큐리티의 동작 과정을 정리해봤습니다. (기본 설정 기준)

 

1. HTTP 요청

클라이언트는 username(아이디), password(패스워드)를 서버에 전송(로그인 요청) 한다.

 

2. FilterChain

요청 객체는 가로채어 져서 n개의 체인 형식으로 이루어진 필터 뭉치를 차례대로 통과한다.

여기에 사용자 정의 필터를 추가할 수 있다.

 

3. UsernamePasswordAuthenticationToken

클라이언트가 보낸 username(아이디)와 password(비밀번호)를 추출하여

UsernamePasswordAuthenticationToken 객체를 생성한다.

 

4. AuthenticationManager 호출

AuthenticationManager는 하나 이상의 AuthenticationProvider를 알고 있으며

이 중 알맞은 Provider에게 처리를 위임한다.

 

주요 AuthenticationProvider

 

1. DaoAuthenticationProvider

  • (주로 DB) 저장소를 대상으로 UserDetailsService를 사용해 사용자 정보를 가져와 인증을 처리한다.
  • DB에서 가져온 사용자 정보(UserDetails)와 UsernamePasswordAuthenticationToken의 비밀번호와 비교
    이 때 DB에서 가져온 비밀번호는 암호화되어 있으므로 PasswordEncoder를 사용하여 매칭한다.
  • 일치한다면 Authentication 타입의 객체를 생성하여 반환한다.

 - UserDetailsService: loadUserByUsername 추상 메서드를 가진 인터페이스로 DB에 SELECT문을 날려 정보를 가져온다.

 - 가져온 정보는 UserDetails 타입으로 반환된다.커스텀 시엔 주로 UserDetails를 구현한 타입으로 반환한다.

public interface UserDetailsService {
	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

2. Jwt Provider: 커스텀 프로바이더. JWT 토큰 기반 인증 처리를 할 때 생성해서 사용해야 함

3. OAuth2 Provider: OAuth 2.0 프로토콜 기반 인증 처리

4. Cas, Ldap 등

 

5. 인증된 UsernamePasswordAuthenticationToken을 AuthenticationFilter에게 전달

Provider에서 인증에 성공하면, UsernamePasswordAuthenticationToken을 AuthenticationFilter에게 반환하고

성공시 수행할 동작을 정의하려면 AuthenticationSuccessHandler 인터페이스를 사용한다.

(리디렉션, 세션 작업, 직접 커스텀한 LoginSuccessHandler 등)

public interface AuthenticationSuccessHandler {
	default void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
    		FilterChain chain, Authentication authentication) throws IOException, ServletException {
        
		onAuthenticationSuccess(request, response, authentication);
		chain.doFilter(request, response);
	}

	void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException;
}

6. SecurityContext에 인증 정보 저장

AuthenticationFilter는 Provider에게서 반환받은 Authentication 객체를

SecurityContextHolder내 SecurityContext에 저장한다.

 

이 곳에 저장되었다면 이제 '인증 받은 사용자 = 로그인한 사용자'가 됐으며

자신의 권한에 맞는 자원에 접근할 수 있다.

 

SecurityContext에 저장된 객체를 가져오는 방법
SecurityContextHolder.getContext().getAuthentication();
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

제공되는 메서드를 사용하여 원하는 정보를 가져올 수 있으며 형변환하여 가져올 수도 있다.

기본적으로 ThreadLocal에 저장되기 때문에 어디서든 사용할 수 있다.

 


도움을 주신 곳

https://www.javainuse.com/webseries/spring-security-jwt/chap3

 

Understand Spring Security Architecture and implement Spring Boot Security | JavaInUse

 

www.javainuse.com