기본적으로 spring security 의존성을 추가하면
아래와 같은 형태로 변경된다.
요청이 들어오면 톰캣 컨테이너에 있는 DelegatingFilterProxy 필터가 스프링 컨테이너에 있는 FilterChainProxy라는 Bean에 요청을 전달하고, 이 Bean은 SecurityFilterChain이라는 Bean에 요청을 다시 전송한다.
cf) SecurityFilterChain은 여러개 만들 수 있는데 이 중 하나에만 요청을 보냄. 요청을 보낼 Bean을 선택하는 기준은 등록 인덱스 순으로 RequestMacher값이 일치하는지이다. 만약 모든 Bean에서 일치하지 않으면 가장 최상단 Bean에 요청을 보낸다.(Requestmacher는 인가 설정에 대한 것이 아님)
http.securityMatchers((auth) -> auth.requestMatchers("/user"));
와 같이 SecurityFilterChain 메소드에 선언해주면 /user로 들어오는 요청은 인덱스 순위가 맨 마지막이라도 이 설정을 한 SecurityFilterChain으로 요청이 들어온다. 이 설정을 안 하면 기본적으로 /**이다.
인덱스 순서를 정하려면 메소드위에 @Order(숫자)를 적으면 된다. 낮은 숫자가 더 빨리 거치게 된다.
SecurityFilterChain을 안 거치게 하여 서버의 자원을 아끼게 하는 방법은 아래와 같다.
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers("/img/**");
}
주로 정적 자원의 경우 이러한 설정을 한다.
이러한 설정을 하면 하나의 SecurityFilterChain이 생성되는데, 0번 인덱스를 갖게 되며 Chain 내부에는 필터가 없는 상태로 설정된다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
OncePerRequestFilter의 경우 redirect는 브라우저에서 다시 한 번 요청을 보내는 것이기 때문에 각각 내부 로직을 수행하지만, forward의 경우 브라우저가 새로 요청하는 것이 아니기 때문에 forwarding 포함 한 번만 내부 로직을 수행한다.
forwarding
redirect
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
DisableEncodeUrlFilter : URL 파라미터에 세션 id가 유출되는 것을 방지하기 위한 필터.
모든 filterChain에 가장 맨 처음으로 등록되어 있다.
이 filter를 사용하지 않으려면 http.sessionManagement((manage)->manage.disable());하면 된다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
SecurityContextHolderFilter : 세션에 대해 이전 요청을 통해 이미 인증한 사용자 정보를 서버 세션 메모리에서 가져와 현재 요청의 SecurityContextHolder의 SecurityContext에 할당하는 역할을 수행. 응답이 완료되면 초기화 된다.
모든 filterChain에 세 번째로 등록되어 있다.
이 filter를 사용하지 않으려면 http.securityContext((context)->context.disable());하면 된다.
주의할 점으로는 유저의 정보가 바껴도 세션 메모리에 SecurityContextRepository를 통해 새롭게 저장하지 않는다. 따라서 이 부분을 커스텀해야 할 필요가 있다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
CsrfFilter : CSRF 공격 방어를 위해 HTTP 메소드 중 GET, HEAD, TRACE, OPTIONS메소드를 제외한 요청에 대해서 검증을 진행.
cf)CSRF 공격 : 사용자의 의지와 무관하게 해커가 강제로 사용자의 브라우저를 통해 서버측으로 특정한 요청을 보내도록 공격하는 방법이다. 세션 쿠키를 탈취하기 쉬워서 주로 세션방식에서 많이 발생.
해커가 만든 form에는 토큰이 존재하지 않으므로 요청을 처리하지 않게 된다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
AbstractAuthenticationProcessingFilter : 인증을 위한 필터로서, form 방식인 UsernamePasswordAuthenticationFilter이 구현하고 있다. 따라서 Form방식이 아닌, JSON과 같은 것을 사용할 때 이 필터를 상속하고 구현함으로써 SecurityContextHolder에 저장할 Authentication 객체를 생성해야 한다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
BasicAuthenticationFilter : Basic 기반의 인증을 수행하기 위함. 커스텀 SecurityFilterChain을 만들시에 자동으로 등록이 안되므로 사용하려면 http.httpBasic(Customizer.withDefaults()); 입력. 세션을 생성하지 않으므로 세션을 stateless 상태로 둬도 무방하다.
cf) Basic 인증 : 사용자 이름과 비밀번호를 결합하여 Base64로 인코딩한 후 HTTP 헤더(Authorization)에 포함시켜 서버에 전송하는 것.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
ExceptionTranslactionFilter : 이 필터 이후에 발생하는 인증, 인가 예외를 핸들링하기 위해 사용. 이 필터 이전에 발생한 예외의 경우는 처리하지 못한다. 커스텀 filterchain에도 기본적으로 등록된다.
'Spring Boot > Security' 카테고리의 다른 글
Spring Boot InternalAuthenticationServiceException (0) | 2024.07.29 |
---|---|
Spring Boot Principal -> UserDetails (0) | 2024.07.29 |
Spring Boot - 프론트에서 OAuth2.0 책임 다 지을 때 (0) | 2024.04.18 |
Spring Boot - jwt 다중 토큰 사용하기 (0) | 2024.04.18 |
Spring Boot - 계층 권한 ( Role Hierarchy ) (0) | 2024.04.13 |