일단 Spring Security라는 단어 자체를 직역해보겠습니다. Spring Security를 직역하면 스프링 보안 입니다. 따라서, Spring Security라는 것은 스프링을 통해서 API를 작성하면 그에 대한 보안을 지원해주는 tool이라고 볼 수 있겠습니다.
그러면 Spring 공식 사이트에서 소개하는 Spring Security에 대한 개념을 알아보도록하죠.
출처: https://spring.io/projects/spring-security
위의 글에서 주목해야할 부분은, Spring Security는 Authentication과 Authorization을 자바 어플리케이션에 제공하는데 초점을 맞춘 프레임워크이다 라는데 있습니다.
실제로도 Spring Security를 공부하다 보면 모든 것은 Authentication과 Authorization을 커스텀하는게 거의 대부분이라는 것을 알 수 있습니다. 저도 갓 시작했지만요
그러면, Spring Security에서 정의하는 Authentication과 Authorization이 무엇인지 알아야겠죠? 알아봅시다.
Authentication 이라는 단어를 구글 번역을 돌려보면 다음이 나옵니다.
인증, 입증 이라는 뜻을 가지는 단어라는 것을 구글 선생님께서 알려주셨습니다.
그러면, Spring Security에서 사용하는 Authentication이란 단어의 정의를 알아봐야겠죠?
Spring Security에서 사용하는 Authentication은 API에 접근하는(혹은 접속하는) 사용 주체가 누구인지 입증하는 과정 을 의미한다고 보시면 됩니다.
그러면 왜 이런 과정이 필요한지에 대해서 궁금하실겁니다. 그런데 상식적으로 생각해보면, 당연하게도 이런 과정이 필요하다는 것을 저희는 경험적으로 알고있습니다.
어떤 게임이 있다고 해봅시다. 게임이라는 서비스를 이용하기 위해서는 본인이 게임 서비스에 접근하려고 함을 입증하는 과정이 필요합니다. (흔히, 로그인이라고 하는 일련의 과정이죠) 그래야만 게임은 자신의 서버, 혹은 데이터베이스가 가지고있던 정보를 안전하게 개인에게 넘겨주는게 가능할겁니다.
결국에는, Spring Security가 추구하는 Authentication의 목적은 서버가 가진 리소스 혹은 데이터의 개인화된 사용성을 보장한다 에 있다고 볼 수 있습니다. 말이 좀 어렵다!
쉽게 생각하면, 로그인이 곧 Authentication 이다! 라고 당장에 이해하셔도 무방할겁니다.
다음으로는, Authorization이 무엇인지에 대해서 살펴보겠습니다.
Authorization 이라는 단어를 구글 선생님께 물어보면 다음의 대답을 해주십니다.
결국에는, 권한을 부여하는 것이 Authorization 이라는 것을 알 수 있습니다.
그러면, Spring Security에서 정의하는 Authorization이 무엇인지 살펴볼 필요가 있습니다.
Authorization을 통해서 특정 API에 접근하려는 사람이 누구인지 입증하는게 끝났다면, 그 다음에 해야하는 행위는 과연 이 사람이 이 API를 사용할 자격(권한)이 있는가? 에 대한 문제를 해결해야합니다.
왜 이런 과정이 필요한지에 대해서 의문을 가져볼 필요가 있습니다. 그런데 우리는 경험적으로 이런 과정이 왜 필요한지를 알 수 있습니다.
다시 게임으로 예를 들어보겠습니다. 플레이어가 어떤 게임 서비스를 이용하고 있습니다. 그리고 그 게임에는 GM만이 사용할 수 있는 하나의 커맨드 모든 유저를 몰살시킨다 라는게 있다고 가정을 해보겠습니다. 그러면 이 커맨드는 GM만이 사용할 수 있도록 설정이 되어있어야합니다.
그런데 만약에 이 기능이 GM만이 사용할 수 있는게 아니라, 다른 플레이어에게도 열려있다면 문제가 될 수 있습니다. 분명히 어떤 플레이어는 이런 생각을 가질수도 있기 때문입니다.
어라? 이런 기능이 된다고? 심심한데 모든 유저를 몰살시키고 다녀야지.
이렇게 된다면, 그 게임의 생태계는 완전히 작살이 날겁니다.
Spring Security는 위와 같은 사태를 방지하기 위해서 Authentication에 대한 기능도 제공하고 있다고 보시면 되겠습니다. 따라서, Spring Security에서는 Authentication을 인증된 사용자가 어디까지의 웹 리소스와, 기능, 그 외의 것들을 사용할 수 있도록 설정을 해줄것인가? 라고 정의를 하고있다. 라고 보셔도 무방하겠습니다.
저희가 위에서 살펴본 바에 따르면, Spring Security는 Authentication과 Authorization 이라는 과정을 통해서 사용자에 대한 Resource, 기능 등의 접근 권한을 제한한다 를 담당하는 프레임워크 라고 요약이 가능합니다.
그러면 저희는 이런 궁금증을 가질 수 있습니다. 그러면 저런 기능을 하는 Spring Secirity는 어떻게 동작을 할까? 사실 엄청 중요한 질문입니다. 정답을 보기 전에, 일단 예측이라도 해보죠.
분명히 저희는, Spring Security는 기능에 대한 접근을 제한한다 라고 말을 하였습니다. 그러면, Spring Security는 request가 기능에 접근을 하기 전에 검증을 해봐야한다는 것을 추측할 수 있습니다. 그런데 Spring Framework는 전체적으로 아래와 같은 life cycle을 지닙니다.
위의 life cycle 구조를 보시면, request를 낚아채서 검증하는 부분은 두 군데 있다는 것을 알 수 있습니다. (물론 낚아채는건 exception handler에서도 낚아채기는 하지만, 이거는 request가 api를 탄 이후에 exception이 발생할 때 낚아채기 때문에 제외를 하겠습니다)
그런데 interceptor에서 request를 낚아채기에는, 문제가 하나 있습니다. 경우에 따라서는 Web resource에 대한 접근도 제한해야할 수도 있기 때문입니다.
따라서, 저희는 위의 논리에 따라서 Spring Security는 Filter 단계에서 작동한다 라고 추측을 해볼수 있습니다.
그런데 이는 정답입니다. 실제로도 Spring Security는 Filter 단에서 동작합니다. 자세하게 알아보겠습니다.
참고: https://docs.spring.io/spring-security/reference/servlet/architecture.html
위의 그림을 확인해봅시다. 위의 그림은 client가 http request를 보낼 때 먼저 filter를 거친다는 뜻을 내포하는 그림입니다. 위의 그림에서 보시다시피, client가 보낸 http request는 여러개의 filter를 거쳐가게됩니다.
그런데 이러한 filter들이 여러개로 엮여서 chain의 형태를 띈다고 해서 위의 형태를 Filter chain(필터 체인) 이라고 부릅니다.
그리고 Spring Security는 이러한 Filter chain 사이에 DelegatingFilterProxy 라는 것을 끼워넣어서 보안 정책을 수행합니다. 이유는 다음과 같습니다.
경우에 따라서는 보안 정책을 달리해야하기 때문에 filter의 적용을 다르게 해야할 수도 있다. 따라서 필터체인 사이에 그룹을 하나 끼워넣어서 경우에 따라 다른 보안 정책을 적용하겠다
그런데 위의 그림으로도 뭔가 부족합니다. 실세계에서는, 필터체인 단위로 filter를 갈아끼워야 하는 경우가 많기 때문입니다. (보안 필터를 여럿 거쳐야 많은 검증을 할 수 있기 때문이지요)
따라서, DelegatingFilterProxy 내부에는 FilterChainProxy 라는 것을 포함시켜서 경우에 따라 filter chain을 갈아끼울 수 있게 Spring Security에서는 사용하고 있습니다.
위의 그림에 따르면, api 요청에 따라서 다른 보안 정책을 수행할 수 있게 filter를 사용하는 모습을 확인할 수 있습니다.
다음 포스트부터는 Spring Secrity 에서 지원하는 기능 중 하나인 Authentication 에 관해서 깊숙하게 알아보도록 하겠습니다.
다음 포스트에서 뵙겠습니다.