시큐리티 인증 / 인가 흐름도

이번 파트에서 인증 아키텍처 내용을 6가지로 설명할 건데 그 6가지의 내용이 다 들어가 있다. 그리고 그 6가지 외에 Spring Security 의 인증이나 인가와 관련된 전체 흐름들을 요약한 그림. 이 흐름도, 패턴을 정확하게 숙지한다면 Spring Securtity 의 인증, 인가 관련 흐름도, 뼈대를 이해하기 수월할 것.

스크린샷 2025-02-02 오후 6.09.33.png

지금 보면 총 4가지 영역으로 구분되어 있다. Servlet Filter 는 어떻게 보면 서블릿 컨테이너 쪽이고 나머지는 스프링 컨테이너 쪽이 될 것.

먼저 서블릿 필터 쪽을 살펴보자. 먼저 사용자가 요청을 보내면 DelegateFilterProxy 가 요청을 처음 받아서 스프링 컨테이너 쪽으로 요청을 넘겨준다. 즉, 스프링에서 필터를 사용할 수 있는 그 중개 역할을 한다. FilterChainProxy 라는 클래스를 찾아 이 클래스에 요청을 넘겨 주고 FilterChainProxy 가 가지고 있는 여러 개의 Spring Security의 필터들을 하나하나씩 호출하며 사용자 요청을 처리하는 클래스이다. 이 클래스가 AuthenticationFilter를 호출하고 있다. 이전에도 여러 필터를 거쳐왔겠지만 인증쪽을 현재 보고있으니, 인증 필터 호출. 이 인증 필터는 Authentication 객체를 만든다. 이번 아키텍처 첫번째 시간은 Authentication 으로 위치를 살펴볼 것. 여기서 어떤 역할을 하는지가 중요하다. 필터가 요청에 대해 사용자의 정보를 담은 다음 Authentication 에 넘겨주는 역할을 하는게 이 역할이다. 밑에 보면 Authentication 이 하나 더 존재한다. 이 경우는 인증에 성공한 이후 Authentication 객체를 만들어서 다시 리턴하는 것. 두개 위치에서 각각의 역할을 한다.

그러면 AuthenticationFilter 가 인증 처리를 할 때 Authentication 객체를 만들어서 AuthenticationManager 에 넘겨준다. 그럼 이 AuthenticationManagerAuthenticationProvider 에게 사용자의 아이디가 맞는지 사용자가 가지고 있는 Password 가 맞는지에 대한 처리를 위임한다. 그러면 AuthenticationProvider 는 첫 번째로 사용자 정보가 맞는지, 즉 현재 데이터베이스나 메모리에 로그인을 시도한 그 사용자의 인증 정보, User 객체가 존재하는지를 확인해야 할 것. 시스템에 그 정보가 없으면 그 사용자는 회원가입을 안 한 사용자이기 때문. 따라서 이 AuthenticationProviderUserDetailService 를 통해 사용자 정보를 가지고 온다. 그리고 이 UserDetailService 는 그 처리를 한 다음 최종적으로는 UserDetails 타입의 객체를 만들어서 다시 올라간다 (반환). 그리고 AuthenticationProvider 에서 만약 사용자의 객체가 없다면 (null) 더이상 인증 처리를 할 필요가 없을 것. 사용자 정보가 없다는 말은 회원가입을 안했고 사용자 정보가 없기에 실패 처리를 한다. 성공했다면 올라가서 다시 AuthenticationProvider 에서 Authentication 객체를 만든다. 이 객체를 만들기 전에 사용자의 비밀번호가 맞는지 홗인하는 작업도 필요할 것. 그때 PasswordEncoder 클래스를 통해 사용자가 입력한 비밀번호와 시스템의 비밀번호가 같은지 확인하는 작업을 거친다. 만약 여기서도 같지 않으면 로그인 실패 후 실패 처리. 비밀번호도 같다면 성공적으로 로그인에 성공해야 하기에 Authentication 객체를 만들어 여기에 User 객체와 권한 정보를 포함해 다시 역으로 AuthenticationManager 에 넘겨주고 이 AuthenticationManager 는 다시 필터까지 계속 넘겨준다. 그렇게 되면 이 필터가 최종적으로 Authentication 객체를 SecurityContextSecurityContextHolder 를 통해 저장. 따라서 최종적으로 SecurityContext 에는 Authentication 이 저장되어 있고 Authentication 안에는 UserDetails 타입이 저장되어 있는 것.

여기까지가 인증 프로세스이다.

Authentication

간단하게 말해 당신은 누구인가 그 자체가 신원을 확인하는 한 방법. 그래서 현재 시스템에 접속하려는 사용자의 존재가 시스템에 존재한다면 그 사람의 신원은 보증되는 것. 그게 인증.

그러면 사용자 인증을 일반적인 방법으로 오떻게 처리할까. 보통 사용자 이름과 비밀번호를 입력하게 되고 이걸 통해 인증이 수행되면 신원을 알게 되는 것. 신원이 확인이 되면 그때 별도의 권한을 부여할 수 있다. 그래서 여기까지는 인증이라면 권한 부여는 인가의 영역이 될 것. 먼저는 인증이 선행되어야 인가가 부여될 수 있을 것. Spring Security 에서도 인증영역과 인가영역이 나눠져있는데 먼저 인증을 받아야만 그다음부터 이 사람이 특정 자원에 접근할 수 있는 권한이 있는지 체크할 수 있는 것.

Authentication 는 어떤 사용자의 정보를 담고 있는 토큰을 들고 다니면서 내가 바로 그 시스템에 존재하는 누구이다 라는 개념으로 객체화 시키는 것. 그래서 인증 이후 SecurityContext 에 저장되며 전역적으로 참조 가능 → SecurityContext 에서 학습 예정.

구조

구조는 Authentication 이 있고 이게 상속받는 클래스가 있는데 그게 Principal 이다. Authentication 는 스프링에 있는 클래스지만 Principal 은 자바에 있는 클래스이다.

Authentication 는 총 6개의 API가 정의되어 있다.