Spring Security Filter Exception 처리

문제 상황

스프링 시큐리티 미구현 필터에서 예외가 발생 해서 처리가 되지 않았다.

로그인 된 상태에서 어플리케이션이 재시작 된 후, 로그아웃 버튼을 클릭하여 로그아웃을 시도하면 인증 객체가 로그아웃 필터로 전달되지 않아 예외가 발생하였으며, 예외 발생 구간은 Logouthandler 이전에 발생되어 기본 필터 예외 처리가 되어있지 않아 White Label Error Page로 리다이렉트 되었다.

문제 파악

스프링 시큐리티에서는 구현하지 않은 기본 필터들이 동작한다. 보통 바이패스 하도록 되어 있지만 위와 같은 특수한 경우에는 요구하는 객체가 Null 이거나 기타 이유로 에러가 발생할 수 있다. 문제는 기본 필터들이 Exception 발생 시 처리가 구현되어 있지 않다는 것이다.

따라서, 이 예외가 발생한 구간의 필터를 구현해 등록 해야 예외를 처리할 수 있다.

해결

스택오버플로에서 여기 글을 찾았고 약간의 꼼수? 를 부려서 해결할 수 있었다.

기본 필터를 하나 만들어 try-catch로 예외 처리를 한 다음, doFilter()만 수행 하게 하여 패스시키도록 한다. 그리고 해당 필터를 맨 첫번째 순서로 배치하여 이후 진행되는 필터에서 예외가 발생해도 캐치할 수 있도록 구성한다.

ExceptionHandlerFilter.kt

/**  
 * 스프링 시큐리티 필터 체인 최 상단에서 필터 내 발생하는 Exception을 캐치하여 처리하기 위한 기본 필터  
 *  
 * @author dk  
 * @version 0.0.1  
 * @since 0.0.1 Release  
 */open class ExceptionHandlerFilter : OncePerRequestFilter() {  
    companion object {  
        private val logger: Logger = LogManager.getLogger(ExceptionHandlerFilter::class.java)  
    }  
  
    /**  
     * 필터 상황에서 Exception 발생 시, 이를 핸들링 하기 위한 필터  
     *  
     * @param request  
     * @param response  
     * @param filterChain  
     */  
    override fun doFilterInternal(  
        request: HttpServletRequest,  
        response: HttpServletResponse,  
        filterChain: FilterChain  
    ) {  
        try {  
            filterChain.doFilter(request, response)  
        } catch (e: RuntimeException) {
            e.printStackTrace()
            // 에러 페이지로 보낸다~
            response.sendRedirect("/view/default/error/accessDenied")  
        }  
    }  
}

해당 필터를 시큐리티 설정 등록 상황에서 첫번째 동작 필터인 CORSFilter 앞으로 등록한다.

.addFilterAt(ExceptionHandlerFilter(), CorsFilter::class.java)

이렇게 하면 예외를 핸들링 할 수 있다.


© 2024. Chiptune93 All rights reserved.