스프링 시큐리티란?
Spring Security is a framework that provides authentication, authorization, and protection against common attacks. With first class support for securing both imperative and reactive applications, it is the de-facto standard for securing Spring-based applications.
출처 - https://docs.spring.io/spring-security/reference/index.html
스프링 시큐리티는 인증과 인가, 그리고 일반적인 공격에 대한 보호를 제공하는 프레임워크입니다. 명령형 및 반응형 어플리케이션 모두를 보호하기 위한 최고 수준의 지원으로 스프링 기반 어플리케이션 보호를 위한 표준 기술입니다.
인증과 인가의 개념은 다음과 같습니다.
인증(Authentication) : 유저가 누구인지 확인하는 절차
인가(Authorization) : 유저에 대한 권한을 허락하는 것

스프링 시큐리티는 여러 필터로 구성된 필터 체인이라고 할 수 있습니다.
- DelegatingFilterProxy

1. 필터는 스프링 맥락에서 벗어나 있기 때문에 스프링에서 정의된 빈을 주입해서 사용할 수 없습니다.
2. 스프링에서 정의된 빈을 사용하기 위해 필요한 것이 DelegatingFilterProxy입니다.
3. 해당 필터는 서블릿 필터이고 요청이 들어오면 SpringBean에 요청을 위임할 뿐 실제 보안처리는 하지 않습니다.
- FilterChainProxy
1. springSecurityFilterChain이라는 이름으로 생성되는 필터 빈입니다.
2. 위에서 언급한 DelegatingFilterProxy로 부터 요청을 위임받고 실제 보안처리를 수행합니다.
3. 스프링 시큐리티 초기화 시 생성되는 필터들을 관리하고 제어합니다.
- 위 사진에서 보이는 필터들 중에 몇몇은 스프링 시큐리티가 기본적으로 생성하는 필터입니다.
- 그리고 다른 몇몇 필터는 시큐리티 설정 클래스에서 API추가 시 생성되는 필터입니다.
4. 사용자 요청 시 필터 순서대로 호출하여 전달합니다.
5. 사용자 정의 필터를 생성하여 기존의 필터 전 후로 추가 할 수 있습니다.
6. 마지막 필터까지 예외가 발생하지 않으면 보안을 통과하고 서블릿으로 넘어가게 됩니다.
- DelegatingFilterProxy와 FilterChainProxy 정리
1. 사용자가 요청이 들어오면 각각의 필터가 요청을 전달받게 됩니다.
2. 이 떄 DelegatingFilterProxy 필터가 요청을 전달 받으면 스프링 컨테이너에 있는
SpringSecurityFilterChain에 요청을 위임합니다. 해당 이름을 지닌 빈이 바로 FilterChainProxy입니다.
3. FilterChainProxy는 자신이 지닌 필터들을 활용하여 차례대로 보안처리를 하게 됩니다.
4. 모든 처리가 완료되면 스프링의 DispatcherServelet으로 요청을 넘겨주게 됩니다.
- Authentication 인증 주체
1. 사용자의 인증 정보를 저장하는 토큰 개념입니다.
2. 인증 시 id와 password를 담고 인증 검증을 위해 전달 되어 사용됩니다.
3. 인증후 user 객체와 권한정보를 Authentication에 담고 SecurityContext에 담아 전역적으로 참조가 가능하게 합니다.
Authentication은 인터페이스 입니다. 구조는 다음과 같습니다.
- principal : 사용자 아이디 혹은 User객체를 저장합니다.
- credentials : 사용자 비밀번호를 뜻합니다.
- authorities : 인증된 사용자의 권한 목록입니다.
- detail : 인증 부가 정보입니다.
- Authenticated : 인증 여부를 뜻합니다.
* Authentication이 시큐리티 아키텍처에서 활용되는 예시
1. 사용자가 username과 password를 지니고 로그인 작업을 요청합니다.
2. 해당 요청을 userNamePasswordAuthenticationFilter가 받아 Authentication 객체를 생성합니다.
< 이 때 보통 Authentication 인터페이스의 구현체로 UsernamePasswordAuthenticationToken을 사용합니다 >
3. 해당 객체에 Principal에 usernamed을 credential에 password를 넣습니다.
4. 만든 Authentication 객체를 AuthenticationManager에 넘겨줍니다. 사용자의 정보가 일치하여 인증에 성공하면
5. AuthenticationManager가 Authentication 객체를 만들어 반환해줍니다.
이 때 principald에는 해당 user 객체 정보와 권한 정보를 담습니다. credential은 보안문제로 비어둡니다.
6. 최종적으로 SecurityContextHolder에 반환한 Authentication 객체를 반환합니다.
SecurityContextHolder은 쓰레드 로컬로 관리되어 인증객체를 전역적으로 사용 가능하게 됩니다.
- SecurityContext
1. Authentication 객체가 저장되는 보관소입니다. 필요할 때 언제든지 Authentication 객체를 꺼내 쓸 수 있습니다.
< SecurityContext 안에 Authentication 객체가 담겨 있고 Authentication 객체 안에 User 객체가 담겨있습니다 >
2. ThreadLocal에 저장되어 아무 곳에서나 참조가 가능합니다.
- SecurityContextHolder
1. SecurityContext를 감싸고 있는 클래스, SecurityContext를 3가지 방식으로 객체를 저장합니다.
- MODE_THREADLOCAL : 위에서 언급한 쓰레드 당 SecurityContext 객체를 할당하는 걸 뜻합니다. (기본값)
- MODE_INHERITABLETHREADLOCAL : 메인스레드와 자식 스레드에 관하여 동일한 Context 유지
- MODE_GLOBAL : 응용 프로그램에서 단 하나의 SecurityContext를 저장합니다. (static 변수 선언)
- 인증 (Authentication) 과정 흐름도
1. AuthenticationManager는 직접적으로 인증 역할을 하지 않고 AuthenticationProvider에게 위임하는 역할을 합니다.
'Spring' 카테고리의 다른 글
BeanFactory와 ApplicationContext의 차이점 (0) | 2023.02.21 |
---|---|
스프링 빈의 쓰레드 안정성에 대하여 (0) | 2023.02.21 |
@Transaction에 대하여 (0) | 2023.01.06 |
스프링 검증 BindingResult에 대하여 (0) | 2022.12.28 |
스프링 빈 스코프란? (0) | 2022.12.23 |