KKanging

[SpringSecurity] SecurityContextFilter 코드 뜯어보기 본문

백엔드/SpringSecurity

[SpringSecurity] SecurityContextFilter 코드 뜯어보기

천방지축 개발자 2024. 5. 23. 02:55

SecurityContextFilter의 역할

SecurityContextFilter은 세션 기반의 서버를 구현했을 때 사용자가 인증을 기반을 하는 요청을 보낼 때 세션 id에 해당하는 SecurityContext 를 가져오고 ContextHolder에 Load한다.

 

코드 뜯어보기

SecurityContextHolderFilter

GenericFilterBean을 상속 받고

SecurityContetRepository 와 SecurityContextHolderStrategy 를 참조 한다.

request에 이 FILTER를 거쳤다는 확인을 위해 값을 저장한다.

securityContextRepository로 사용자가 보낸 세션 id에 해당하는 객체를 세션 DB에서 조회후 가져온다.

 

Supplier은 지연된 로딩을 지원하는 문법이므로 따로 공부하면 될거 같다.

 

SecurityContextRepository 로 가져온 Context를 securityContextHolderStrategy 로 ContextHolder에 저장한다.

securityContextHolderStrategy 에 대해 궁금하다면

[SpringSecurity] SecurityContextHolder ,Security Context, Authentication (tistory.com)

그리고 finally로 context를 비우고 request 에 값을 삭제한다.

 

SecurityContextRepository

위에 설명과 같이 SecurityContextRepository로 세션에 인증 정보를 가져온다.

하지만 Session DB를 운영하는데에 여러가지 방법이 있다(메모리, rediss…)

그래서 SecurityContextRepository은 인터페이스로 구현되었고 다음과 같이 구현되어있다.

구현체들 정리

  • HttpSessionSecurityContextRepository (Default)
    • 서버 세션 기반 구현체
  • NullSecurityContextRepository
    • JWT를 구현할 때 STATELESS 로 설정하는데 쓰임
    • 즉 세션을 사용하지 않을 때 사용 (아무 기능이 없음)
  • RequestAttributeSecurityContextRepository
    • HttpServletRequest에 값을 저장
  • 커스텀 필터 등록
    • 세션DB를 조회하는 로직을 커스텀할려면 다음과 같이 등록하면된다.
  • public SecurityFilterChain filterChain(HttpSecurity http) {
    	http
    		// ...
    		.securityContext((securityContext) -> securityContext
    			.securityContextRepository(new RequestAttributeSecurityContextRepository())
    		);
    	return http.build();
    }
    
    • DelegatingSecurityContextRepository
    • 여러 로직을 적용하여 등록할 수 있게 할 수 있다.
    • DelegatingSecurityContextRepository가 List로 Repository를 가지고 하나씩 탐색하여 실행한다.DelegatingSecurityContextRepository

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	http
		// ...
		.securityContext((securityContext) -> securityContext
			.securityContextRepository(new DelegatingSecurityContextRepository(
				new RequestAttributeSecurityContextRepository(),
				new HttpSessionSecurityContextRepository()
			))
		);
	return http.build();
}

 

 

SecurityContextPersistenceFilter

 

예전에 SecurityContextPersistenceFilter 를 사용했었다.

 

무슨 차이점이 있을까

위에 사진이 SecurityContextPersistenceFilter 로직이고

아래 사진이 SecuirtyContextFilter 이다.

차이점은 마지막 finally로 세션을 업데이트 하냐 안하냐 차이다.

만약 user의 정보를 수정하는 로직이 수행됐다면 SecuirtyContextFilter 는 업데이트 안하므로 이점을 유의해서 따로 구현하던지 해야한다.

 

참고 문헌

Persisting Authentication :: Spring Security