Spring Security란 자바 어플리케이션에서 인증과 권한 부여, 일반적인 공격에 대한 보호 기능을 제공하는 프레임워크입니다. Spring Security를 사용하면 어플리케이션의 보안 관련 기능을 자체적으로 구현할 필요없이 쉽고 안전하게 구현할 수 있습니다.
인증 구현을 위해서 Spring Security를 사용한 이유는 공식문서에서 기본적인 인증과 권한 부여 기능을 제공한다고 해서 사용했구요, 인터셉터와 AOP를 활용하는 방식이 아닌 Filter를 통해서 색다르게 인증을 구현하고 싶어서 Spring Security를 사용하였습니다.
어떻게 Security Filter에 JWT를 처리하는 필터를 만들어서 끼워 넣을까?에 대해서 설계하고 이해하는데 많이 어려웠던 것 같습니다.
Filter와 Security Filter 모두 Servlet에 요청이 맵핑되기 전에 실행되는 필터(Filter)입니다. 둘다 동일한 Filter이지만 단순한 Filter는 서블릿 컨테이너에 직접 등록해서 사용하는 필터이고 Security Filter는 DelegatingFilterProxy가 서블릿 컨테이너에 Filter로 등록되어서 Filter 작업을 Security FilterChain으로 위임해서 실행되는 필터를 의미합니다.
즉, 다시 말해서 Filter와 Security Filter 모두 서블릿에 요청이 맵핑되기 전에 실행되는 필터인데 이를 서블릿 컨테이너에 직접 등록하느냐 아니면 DelegatingFilterProxy가 Filter작업을 Security Filter Chain으로 위임해서 사용하느냐의 차이입니다.
Spring Security를 사용해서 인증을 구현하기 위해 JWT를 생성, 인증, 권한 부여, 유효성 검사, PK 추출을 할 수 있는 클래스인 JwtTokenProvider를 만들었구요, 이를 사용해서 Filter 작업을 수행할 JwtAuthenticationFilter를 만들었습니다. JWT 인증 필터가 기본 인증 필터인 UsernamePasswordAuthenticationFilter 이전에 수행할 수 있도록 Security Filter Chain 설정을 통해서 인증을 구현할 수 있었습니다.
Client가 요청을 보내면, Servlet Filter에 의해서 Security Filter로 작업이 위임되고 여러 Security Filter 중에서 JwtAuthenticationFilter에서 인증을 처리합니다.
JwtAuthenticationFilter는 Servlet 요청 객체에서 토큰을 가져와서 JwtTokenProvider가 해당 토큰을 검증해 토큰이 유효한지 검사합니다.
토큰이 유효하다면 Authentication 객체를 만들고 AuthenticationManager를 사용할 필요 없이 직접 SecurityContextHolder에 접근해서 Authentication 객체를 저장합니다.
1. 사용자가 로그인 정보와 함께 인증 요청을 한다.(Http Request)
2. AuthenticationFilter가 요청을 가로채고, 가로챈 정보를 통해 UsernamePasswordAuthenticationToken의 인증용 객체를 생성한다.
3. AuthenticationManager의 구현체인 ProviderManager에게 생성한 UsernamePasswordToken 객체를 전달한다. 4. AuthenticationManager는 등록된 AuthenticationProvider(들)을 조회하여 인증을 요구한다. 5. 실제 DB에서 사용자 인증정보를 가져오는 UserDetailsService에 사용자 정보를 넘겨준다. 6. 넘겨받은 사용자 정보를 통해 DB에서 찾은 사용자 정보인 UserDetails 객체를 만든다. 7. AuthenticationProvider(들)은 UserDetails를 넘겨받고 사용자 정보를 비교한다. 8. 인증이 완료되면 권한 등의 사용자 정보를 담은 Authentication 객체를 반환한다. 9. 다시 최초의 AuthenticationFilter에 Authentication 객체가 반환된다. 10. Authenticaton 객체를 SecurityContext에 저장한다.
웹 애플리케이션 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 하여 특정 웹페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법을 의미한다.