본문 바로가기

프로그래밍/Spring Security

Spring Security를 들어가며...

개인적으로 Spring Framework를 사용하면서 가장 적용해보고 싶었던 것이 바로 이 Spring Security 였다. 우리가 일반적으로 Web 관련 Project를 하면서 항상 따라다니는 것이 바로 로그인 관련 개발이다. 로그인이 없는 사이트는 거진 없다고 봐도 과언이 아닌 현실에서 이 개발이 아주 없을수는 없기 때문이다. 또한 로그인을 개발해야 한다는건 결국 회원 관리를 한다는 의미이기 때문에 회원 관리에 대한 개발을 해야 하는 것이고, 회원 관리를 개발한다는건 사이트의 Admin을 개발한다는것을 의미한다. 또 회원을 관리하면 결국 권한 관리가 같이 따라오기 마련이다. 이런 일련의 개발을 하면서 우리는 얼마나 많은 시간을 허비했는지 모른다(응? 웬지 요즘 타이어 광고 멘트 느낌이..) 그러나 Spring Security를 적용하면서 이런 부분을 나름 체계화된 흐름이 잡힌 개발을 할수 있게 되었다(물론 Spring Security에서 제공하는 아주 기본적인 셋팅만으로는 절대 실제 운영 사이트에 반영할수 없다. 커스터마이징이 필수적으로 들어간다) 그래도 로그인 관리와 권한 관리에 대한 체계를 잡을수 있다는데에는 개인적으로 높게 평가한다.

 

사실 이 글을 쓰기 이전에도 개인적으로 Spring Security를 공부했고 나름 정리가 되었으나 그것을 실제 적용시키기엔 자신이 없었다. 앞에서도 잠깐 얘기했다시피 Spring Security는 커스터마이징이 필연적으로 따르게 되어있다. 기본적인 셋팅만으로는 절대 현업의 요구조건을 만족시킬수가 없기 때문이다. 근데 여러 다양한 현업의 요구 조건을 만족시킬만큼 나의 스킬이 과연 올랐는지는 자신할수 없었다. 그래서 내가 나름 발언권을 가지고 있고 추진력있게 수행할수 있는 프로젝트에서 조차도 Spring Security를 사용해서 로그인과 권한 관리 해봅시다!!! 란 말을 꺼낼수가 없었다. 물론 지금도 그런 자신감은 없다. 그러나 언젠가는 맨땅에 헤딩하며 해야 할 상황이 분명 올것이고 그게 굳이 내가 아니더라도 다른 사람이 헤딩할때 조금이라도 참조할 자료는 정리해야 겠다 싶었다. 그래서 정리해놓은 것도 있었지만..공개하기엔 오래 지난데다가..참고 자료라는게 책의 인용이라 공개하기도 그래서 아예 새로이 자료를 만들어서 공개해볼까 한다.

 

Spring Security와 관련되어서 자주 접하게 되는 내용은 인증(Authentication)권한(Authorization)의 개념과 그리고 Spring Security에서 제공되는 Filter들의 얘기이다. 사실 인증과 권한의 개념을 명확하게 이해하고 Spring Security에서 제공하는 Filter들의 이해와 적절한 활용만 할줄 알면 Spring Security의 반을 이해했다고 해도 과언이 아니다(물론 세세한것 까지는 아니지만..)

 

인증(Authentication)이란 무엇인가? 인증은 사용자가 맞는지 아닌지를 확인하는 것이다. 우리가 어떤 사이트를 이용할때 로그인 아이디와 비밀번호를 왜 넣을까? 그건 내가 내다(부산 사투리에 이런 표현이 있는거 같던데..)라는 것을 증명하기 위함이다. 사이트를 이용하는 사람이 나라는 것을 증명할려면 어떻게 해야 하는가? 내가 회원 가입할때 만든 아이디와 그에 매핑되는 비밀번호를 넣어서 나 라는 것을 증명하는 것이다. 내가 내다..라는 것을 증명하지 못한다면 사이트를 이용할 자격이 없는 것이다.

 

그럼 이렇게 인증 과정을 거쳐서 내가 내다..라는 것을 증명했다면..그때부터 내가 가입한 사이트를 이용할 자격이 주어지며 여기저기 메뉴를 클릭하고 페이지를 보게 된다.  그런데 여기서 생각해야 할 것이 있다. 내가 가입한 사이트는 모든 이용자가 모든 화면을 볼수 있는 구조는 절대로 될 수가 없다. 왜 그럴까? 위에서도 잠깐 언급했지만..관리자가 없는 사이트는 논리적으로는 절대 존재 할수가 없다.(논리적이란 표현을 쓴것은 비즈니스 로직적인 얘기를 의미함이다. 극단적으로 물리적으로 관리자를 안둘수도 있다. 그러나 그런 사이트는 관리가 안되기 땜에 스팸 댓글로 도배가 되거나 심지어는 해킹 대상이 될 것이다) 사이트를 이용하기 위해서는 회원을 가입해야 하고, 그렇기 땜에 가입된 회원에 대한 관리가 필요하다. 어디 그뿐인가? 사용자가 게시판을 도배했다면 관리자의 권한으로 이를 지워야 하는 일도 생기게 마련이다. 이렇게 관리자 자격을 가진 사람만 접근하는 화면이 별도로 존재하게 되는 것이다. 그럼 이런 화면을 일반인이 접근해야 하는것인가? 그리 되서는 안된다. 일반인이 접근하게끔 만들면 내가 미워하는 사람을 강제로 회원에서 짤리게 할수도 있다. 즉 일반회원은 접근 못하게 하고 관리자만 접근할 수 있게끔 해줘야 한다. 권한이라는 것은 이렇게 이 사이트를 이용하는 사람이 이런 화면을 이용할수 있는지 확인하는 과정을 의미하게 된다(국어 사전적인 의미에서는 과정이라기 보단 개념에 맞춰져 있다)

 

인증과 권한은 그럼 어떠한 관계로 움직이게 되는가? 예를 들어 설명하겠다. A라는 사이트의 메뉴에서 로그인 화면을 통해 아이디와 비밀번호를 입력받아 로그인을 했다. 이 과정은 인증(Authentication)이다. 인증에 실패하면 적절한 에러 화면을 보게 될 것이다. 그러나 인증에 성공하면 사이트 메인 화면 등 지정된 화면을 보게 될 것이다. 이제 로그인 된 상태에서 상단 메뉴에서 관리자 메뉴를 클릭했다. 그러면 사이트는 로그인 한 나의 정보를 가지고 내가 관리자 메뉴를 이용할 수 있는지 확인하게 된다. 이 과정은 권한(Authorization)이다. 권한에 성공하면 관리자 화면을 보게 될 것이고 권한에 실패하면 이용할 자격이 없다는 에러 화면을 보게 될 것이다. 이런 설명과 같이 처음에 인증 과정이 발생 한뒤 인증 과정이 성공하면 여러번의 권한 과정이 발생하게 되는 그런 흐름인 것이다(사이트가 제공하는 화면마다 권한 과정을 거치기 때문에 여러번 발생하게 된다)

 

Spring Security에서는 이러한 인증과 권한의 과정을 Filter들의 흐름에 따라 이루어지도록 하고 있다. Spring Security에서 제공되는 Filter들을 보면 다음과 같다(지금에서야 밝히지만 앞으로 Spring Security에 대한 설명은 Spring Security 3.2.4 기준으로 설명한다. 또한 여기서 설명하는 목록은 전자정부 프레임워크 Spring Security 세미나 자료에서 발훼했다. 전체 목록은 http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/ 여기에서 4.3.6 Adding In Your Own Filters 섹션을 보면 전체 목록이 나와 있다)

 

 

 Alias

 Filter Class

 Namespace 설정

 CHANNEL_FILTER

 ChannelProcessingFilter

 http/intercept-url@requires-channel

 SESSION_CONTEXT_FILTER

 SecurityContextPersistenceFilter

 http

 CONCURRENT_SESSION_FILTER

 ConcurrentSessionFilter

 session-management/concurrent-control

 LOGOUT_FILTER

 LogoutFilter

 http/logout

 FORM_LOGIN_FILTER

 UsernamePasswordAuthenticationFilter

 http/form-login

 BASIC_AUTH_FILTER

 BasicAuthenticationFilter

 http/http-basic

 REMEMBER_ME_FILTER

 RememberMeAuthenticationFilter

 http/remember-me

 ANONYMOUS_FILTER

 AnonymousAuthenticationFilter

 http/anonymous

 SESSION_MAMAGEMENT_FILTER

 SessionManagementFilter

 session-management

 EXCEPTION_TRANSLATION_FILTER

 ExceptionTranslationFilter

 http

 FILTER_SECURITY_INTERCEPTOR

 FilterSecurityInterceptor

 http

 

나중에 Spring Security 설정 관련 XML을 보겠지만 Namespace 설정에서 http/intercept-url@requires-channel 의 의미는 Spring Security 설정 XML에서 ><http> 태그의 하위 태그로 <intercept-url> 태그를 사용하고 그 <intercept-url> 태그에서 requires-channel 속성(attribute)를 사용한다는 의미이다

즉 <http> 태그의 <intercept-url> 태그를 사용할 때 requires-channel 속성을 지정하면 ChannelProcessingFilter 클래스가 사용된다는 의미이다

 

위에서 언급한 Filter 들은 우리가 일반적으로 흔히 사용하는 Form 방식의 로그인을 사용할 경우에 자주 사용되게 되는 Filter들을 언급해둔것이다.

(BasicAuthenticationFilter의 경우는 웹페이지의 Form 방식 로그인이 아닌 클라이언트 로그인 창을 사용할 경우에 사용되는 Filter이다)

그러나 이 Filter들을 반드시 써야 하는 것은 아니다. 예를 들어 웹사이트롤 사용할때 같은 아이디로 2개 이상 로그인 하는 것을 허용시키려 하지 않을 경우 사용되는 Filter인 ConcurrentSessionFilter의 경우 이 Filter가 없다고 해서 Spring Security 처리에 문제가 발생하는게 아니다. 2개 이상 로그인 해도 상관없다면 이 Filter를 사용하지 않으면 그만이다.

 

인증과 권한의 처리 흐름 또한 Filter들 목록에서 위에서 아래로 거치게 된다. 즉 ChannelProcessingFilter -> SecurityContextPersistenceFilter -> ConcurrentSessionFilter -> ... 흐름으로 움직인다는 것이다. 또한 비즈니스 적인 이유로 인해 기존 제공되는 Filter를 새로운 Filter 클래스로 교체하거나 Filter와 Filter 사이에 특정 Filter를 거치게끔 하여 이를 처리하도록도 할 수 있다. 또 Filter 흐름의 순서를 우리가 정할수도 있다.

 

이번은 인증과 권한, 그리고 Filter에 대한 대략적인 설명을 진행했다. 다음엔 Spring Security의 설정에 대한 내용을 언급하겠다.