개발자의 오르막

[SpringSecurity #09] Spring Security Filter 본문

SpringFrameWork/SpringSecurity

[SpringSecurity #09] Spring Security Filter

계단 2020. 10. 2. 22:49

# 스프링 시큐리티 적용 여부 설정

- WebSecurity 의 ignoring()을 사용해서 시큐리티 필터 적용을 제외할 요청을 설정할 수 있다.

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/favicon.ico");
    }

  스프링 부트가 제공하는 PathRequest 를 사용해서 정적 자원 요청을 스프링 시큐리티 필터를 적용하지

  않도록 설정.

 

# WebAsyncManagerIntegrationFilter

- 스프링 MVC의 Async 기능 (핸들러에서 Callable을 리턴할 수 있는 기능)을 사용할 때에도

  SecurityContext를 공유하도록 도와주는 필터

  1. PreProcess : SecurityContext를 설정한다.

  2. Callable : 비록 다른 쓰레드지만 그 안에서는 동일한 SecurityContext를 참조할 수 있다.

  3. PostProcess : SecurityContext를 정리 (clean up) 한다.

 

 

- IndexController

@GetMapping("/async-handler")
    @ResponseBody
    public Callable<String> asyncHandler() {
        SecurityLogger.log("MVC");
        return () -> {
            SecurityLogger.log("Callable");
            return "Async Handler";
        };
}

 

- SecurityLogger

public class SecurityLogger {

    public static void log(String message) {
        System.out.println(message);
        Thread thread = Thread.currentThread();
        System.out.println("Thread : " + thread.getName());
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        System.out.println("Principal : " + principal);
    }
}

- Result

MVC
Thread : http-nio-8080-exec-2
Principal : org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN
Callable
Thread : task-5
Principal : org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN

 

  위의 결과를 보면 다른 Thread 에서도 Principal 의 동일한 객체를 사용할 수 있는 것을 알 수 있다.

  (2개의 Thread 가 동작하지만 우리는 동일한 Principal 을 가져올 수 있음)

  Thread Local 을 통해 한 번의 Thread 에서 자유롭게 사용하던걸 AsyncManagerIntergrationFilter 를 통해

  사용할 수 있는 것이다.

 

 

# SecurityContextPersistenceFilter

- SecurityContextRepository 를 사용해서 기존의 SecurityContext를 읽어오거나 초기화 된다.

- 기본으로 사용하는 전략은 HTTP Session 을 사용한다.

- Spring-Session 과 연동하여 세션 클러스터를 구현할 수 있다.

- 여러 요청 간 SecurityContextHolder 를 공유한다. ( 한번 인증하면 다른 url 을 타도 여러번 인증 필요 X )

- 이 필터는 SecurityContextHolder 가 비어있으면 실행되고, 인증 정보가 있으면 생략되기 때문에

  인증을 하는 필터보다 앞에 있어야 작동을 한다.

 

Comments