Closed byunyourim closed 2 days ago
스프링 기반의 애플리케이션의 인증과 권한을 담당하는 프레임워크
필터를 기반으로 동작한다. 필터는 Dispatcher Serevlet으로 가기 전 적용되며 가장 먼저 URL 요청을 받는다.
Interceptor는 Dispather와 Controller 사이에 위치한다.
스프링 MVC에서 요청을 가장 먼저 받는 것은 DispaqtcherServlet인데, DispaqtcherServlet이 요청을 받기 전 여러 필터가 존재한다.
Spring Security도 인증 및 인가를 처리하기 위해 Filter를 기반으로 동작한다. 이를 위해서 DelegatingFilterProxy와 FilterChainProxy를 사용한다.
DelegatingFilterProxy는 서블릿 컨테이너에 등록된 여러 필터 중 하나로, 요청을 Spring Security로 전달하기 위한 브릿지 역할을 한다. 모든 요청을 Spring 컨텍스트에서 관리되는 FilterChainProxy로 위임한다.
FilterChainProxy는 SecurityFilterChain을 관리하며, 요청 URL 패턴에 따라 적절한 필터 체인을 선택해 실행한다.
Security Filter Chain은 인증, 세션 관리, 인가 등 다양한 보안 작업을 수행하는 여러 필터로 구성되어 있으며, 각 필터는 체인 방식으로 연결되어 순차적으로 요청을 처리한다. Security Filter를 모두 통과한 요청은 DispatcherServlet 또는 다음 필터로 이동한다.
이러한 구조를 통해 Spring Security는 요청을 안전하게 처리하고 애플리케이션으로 전달되도록 보장한다.
Spring Security 에서 요청을 처리하는 필터의 순차적인 집합이다. 클라이언트의 http 요청이 서버에 도달할 때 실행되며, 주로 인증 및 권한 부여와 관련된 작업을 수행한다.
가장 먼저 초기화가 진행된다.
Spring Security에서는 인증, 인가에 대한 처리를 여러개의 필터를 연쇄적으로 수행한다.
WebSecurityConfigurerAdapter를 구현한 설정 파일의 내용을 기반으로 필터를 생성한다.
이때, 실제 필터를 생성하는 클래스가 HttpSecurity 이다. 설정 파일 별로 필터 목록을 갖게된 후, 필터들은 WebSecurity 클래스에게 전달된다. WebSecurity는 각각 설정 클래스로 부터 필터 목록들을 전달받고, 다시 FilterChainProxy를 생성자의 인자로 전달한다.
따라서, FilterChainProxy는 각각의 설정 클래스 별로 필터 목록을 갖는다.
후에 사용자가 처음 요청을 하면 가장 먼저 DelegatingFilterProxy가 요청을 받는다. 그리고 나서 FilterChainProxy에게 요청을 위임한다.
DelegatingFilterProxy는 서블릿 필터로, 위임할 때는 SpringSecurityFilterChain이라는 이름을 갖는 Bean을 찾는데, 그 Bean이 FilterChainProxy이다.
이렇게 위임 받은 요청을 가지고 있는 필터들에게 순서대로 요청을 맡긴다.
각각의 필터들이 체인으로 연결되어 수행 -> 넘김 -> 수행
으로 진행된다.
이때, 수행되는 메서드가 doFilter이다.
스프링 시큐리티는 다양한 필터를 기본적으로 제공한다. 이렇게 제공되는 필터를 Security filter chain이라고 한다.
클라이언트가 요청을 보내면 SecurityContextPersistenceFilter가 먼저 실행되어 SecurityContextRepository를 통해 이전의 보안 컨텍스트를 로드한다. 이 컨텍스트는 SecurityContextHolder에 저장되어 현재 스레드에서 사용할 수 있게된다. 저장된 SecurityContext는 현재 사용자의 인증 정보를 포함하며, 그 안에 Authentication객체가 포함된다.
이렇게 연결된 흐름을 통해 Spring Security는 사용자의 인증상태를 관리하고, 보안을 유지한다.
로그아웃 요청을 요청하면 세션을 무효화하고, SecurityContext를 삭제한다. LogoutSuccessHandler가 호출되어 로구아웃 후 동작을 정의한다.
ID, passwrod 를 사용하는 실제 Form 기반 유저 인증을 처리한다.
인증 객체를 만들어 Authentication 객체를 만들어 아이디와 패스워드를 저장하고,
AuthenticationManager에게 인증 처리를 맡긴다.
성공 시 AuthenticationSuccessHandler, 실패 시 AuthenticationFailureHandler를 호출한다.
기본 로그인 페이지를 생성한다.
HTTP Basic 인증 헤더를 처리하여 사용자를 인증한다.
사용자가 동시에 여러 세션을 유지하는 것을 방지, 제한하기 위해 사용된다.
동일한 사용자 계정으로 여러 브라우저, 탭에서 로그인 한 경우, 이전 세션을 무효화하거나, 사용자의 로그인 세션 수를 제한한다.
매 요청마다 사용자의 세션이 만료되었는지 확인하고, session.expireNow 값으로 만료 설정을 구분한다.
세션이 사라지거나 만료되더라도, 쿠키 또는 DB를 사용하여 저장된 토큰 기반으로 인증을 처리한다.
remember-me 기능을 활성화하고 인증 받고 세션이 만료되면 실행되는 필터이다.
세션이 만료되거나 무효화되어 세션 안에 있는 SecurityContext내의 인증 객체가 null일 경우 해당 필터가 작동한다.
인증 객체가 null일 경우 현재 사용자가 요청하는 request header에 remember-me cookie 값을 헤더에 저장한 상태로 왔을 때 이 필터가 접속한 사용자 대신 인증 처리를 시도한다.
세션 정책(동시 로그인 제한)을 적용한다ㅏ.
필터 체인 내에서 발생되는 인증, 인가 예외를 처리한다. 인증 실패 시 AccessDeniedException, 인가 실패 시AuthenticationExceptiton을 던진다.
인증되지 않은 사용자에게 익명 인증 객체를 할당한다. 익명 사용자 필터는 이 필터가 호출되는 시점까지, 인증 시도를 하지 않고 권한도 없이 어떤 자원에 바로 접속을 시도하는 경우 실행된다.
SecurityContext를 통해 인증 객체를 제공하고, 현재 사용자의 권한을 요청과 연결한다.
최종 필터로, 요청의 리소스에 대해 사용자의 접근 권한을 확인한다. 권한 확인은 AccessDecisionManager와 SecurityMetadataSource 가 담당한다.
인증시 아이디와 패스워드를 담고 인증 검증을 위해 사용된다 . 인증 후 최종 인증 결과 (user 객체, 권한정보) 를 담고 SecurityContext 에 저장되어 전역적으로 참조가 가능합니다.
현재 인증 상태를 저장하고 관리하며, 필터나 다른 인증 관련 객체가 이를 참조한다.
인증 프로세스를 조정하는 핵심 구성 요소로, 요청을 AuthenticationProvider에 전달한다.
실제 인증을 처리하며, 사용자 정보를 검증하거나 외부 시스템과 연동하여 인증을 수행한다.
사용자 정보를 로드하는 서비스로. 주로 데이터베이스에서 사용자 정보를 가져온다.
UserDetailsService에서 반환하는 사용자 객체로, 사용자 이름, 비밀번호, 권한 등의 정보를 포함한다.
사용자가 가진 권한(예: ROLE_USER, ROLE_ADMIN)을 나타낸다..
SessionAuthenticationStrategy 세션 생성/인증 시 세션 관련 정책을 사용한다.
활성 사용자와 세션 정보를 추적 및 관리한다.
요청에 대한 접근 권한을 결정한다. 여러 DecisionVoter를 사용하여 다수결 방식(예: AffirmativeBased)으로 판단한다..
요청 URL, HTTP 메서드, 리소스에 대해 필요한 권한을 정의한다..
요청에 대해 허용할지, 거부할지, 중립 상태인지 판단한다. 예: RoleVoter는 사용자의 권한이 리소스에 필요한 역할(Role)을 포함하는지 확인한다.
인증되지 않은 사용자가 접근 시 처리한다
권한이 없는 사용자가 리소스에 접근하려 할 때 호출된다.
여러 투표자의 결과를 바탕으로 접근 결정합니다.
역할 기반으로 접근 권한을 평가한다.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class) // 사용자 정의 필터 추가
.authorizeRequests()
.antMatchers("/public/**").permitAll() // 공개 URL
.anyRequest().authenticated() // 나머지 요청은 인증 필요
.and()
.formLogin() // 폼 로그인 사용
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
사용자가 로그인 정보 (id, password)를 입력하고 Authentication 요청한다.
AuthenticationFilter는 사용자가 입력한 정보를 받아 UsernamePasswordAuthenticationToken 객체로 생성한다.
UsernamePasswordAuthenticationToken이 AuthenicationManager에 전달된다.
AuthenticationManager는 여러 AuthenticationProvider 중 하나를 선택해 인증과정을 진행한다.
선택된 AuthenticationProvider는 사용자 정보를 가져오기 위해 UserDetailsService를 호출한다.
UserDetailsService는 사용자 정보를 포함하는 UserDetails 객체를 반환한다.
AuthenticationProvider는 반환된 UseerDetails를 사용하여 인증을 검증한다.
ProviderManager는 여러 AuthenticationProvider를 관리하고, 해당 프로세스를 구현한다.
인증이 성공하면 AuthenticationManager는 인증 결과를 반환한다.
최종적으로 인증 정보가 SecurityContextHolder에 설정되어 애플리케이션의 보안 컨텍스트가 업데이트 된다.
인증 요청을 처리하는 객체로, 로그인 시 사용자 정보를 확인한다.
사용자의 정보를 제공하는 서비스로, loadUserByUsername()메서드를 통해 사용자의 정보(아이디, 비밀번호 등)를 반환한다.
비밀번호를 암호화하는 컴포넌트로 BcryptPasswordEncoder, NoOpPasswordEncoder 등의 구현체가 있다.
현재 사용자와 관련된 인증 정보를 저장하는 장소로 SecurityContext 객체를 통해 인증된 사용자 정보를 가져올 수 있다.
요청이 처리되는 동안 다양한 보안 필터들을 순차적으로 실행하는 체인
HTTP 요청에 대한 보안 구성을 설정하는데 사용된다. URL에 대한 접근 권한을 설정하거나, 세션 관리, CSRF 보호 등을 설정할 수 있다.
사용자가 가지고 있는 권한을 나타내는 객체
인증, 권한 부여를 위한 필터 체인으로, 각 필터는 요청을 처리하면서 특정 작업을 수행한다.
이슈: Spring Security의 동작
배경
목표
세부 내용
진행 상황
등록일: 2024.11.20
문서화 결과
일정
이 이슈에 대한 문서화를 금주 내로 진행할 예정.