2021.05
사내 프레임워크 중 로그인/권한인증 모듈 개발시 사용하였다.
구현 기능 : 로그인, 회원가입, 권한인증 및 관리(method, api), 비밀번호 실패, 회원정보 수정
Spring Security를 사용하여 권한인증 모듈을 개발하게 되었는데, 처음에 Spring Security가 무엇인지 어떻게 동작하는지, 또 어떤 기능들을 제공하는지에 대하여 제대로 알지 못하는 상태에서 급하게 구현을 하였다..
그 결과,, 중간 점검시 팀장님께서 왜 servlet filter를 사용하여 구현하였나요? 라는 질문에 나는 아무것도 대답하지 못하였다..
팀장님께서 알려주셨다. 최소한 내가 사용한는 툴, 라이브러리에 대해서는 정확하게 알고 가야한다고. 그래야 그 툴을 올바르게 사용할 수 있다고.
맞는 말씀을 해주셨다. 나는 그동안 제대로 알지못한 채 구글리을 통해 가볍게 알게된 지식에만 의지한 채 개발을 해왔고, 그 결과가 수도없이 부실했었다.
그래서 이제는 그러지 않으리라!! 내가 사용하려는 것에 대해 정확히 알고 가자!!
Spring Security가 어떤 아이인지 알아보면서 직접 그림 그려가면서 정리해보았다.
Spring Security란?
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
(Spring Security는 강력하고 고도로 사용자 정의 가능한 인증 및 액세스 제어 프레임워크입니다.
Spring 기반 애플리케이션을 보호하기 위한 사실상의 표준입니다.)
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
(Spring Security는 Java 애플리케이션에 인증과 권한 부여를 모두 제공하는 데 중점을 둔 프레임워크입니다. 모든 Spring 프로젝트와 마찬가지로 Spring Security의 진정한 힘은 사용자 정의 요구 사항을 충족하기 위해 얼마나 쉽게 확장할 수 있는지에 있습니다.)
- 스프링 시큐리티는 Spring boot 기반 Java Application의 인증 및 인가 처리를 제공하는 프레임워크이다.
- Servlet Filter기반의 Filter Chain으로 동작한다.
- 시큐리티의 보안 관련 용어로는 Principal, Authentication, Authorization, Authority가 있다.
Security 보안관련 용어
- Principal (접근 주체)
- 보호된 대상에 접근하는 유저
- Application을 사용하려고 인증 및 인가를 요청하는 사용자이다.
- Authentication (인증)
- 현재 접근하려고 하는 사용자가 누구인지 확인하는 행위이다. (로그인)
- Application을 사용할 수 있는 사용자임을 증명하는 것이다.
- Authorization (인가)
- 인증된 사용자가 특정 서비스 사용 및 페이지 접근할 수 있는 권한이 있는지를 확인하는 행위이다.
- Authority (권한)
- 인증된 사용자가 Application이 제공하는 서비스를 사용할 수 있도록 허락되어 있는지 결정하는 수단이다.
- 사용자가 보유한 권한을 통해 인가 처리를 한다.
- 권한에는 두 가지 유형이 존재한다.
- 웹 요청 권한
- 메서드 호출 및 도메인 인스턴스에 대한 접근 권한
Security Filter Chain
Security Filter Chain은 Application이 빌드되어 실행될 때 Spring boot의 DelegatingfilterProxy로 인해 각 요청마다 Security Filter Chain을 등록한다.
Security Filter Chain에는 인증 및 인가 처리를 위한 기능별 Filter들이 존재한다. Security Filter들은 각각 역할을 가지고 있으며, 필터 순서에 따라 동작한다.
Security Filter Chain에는 대표적으로 아래 필터들이 순서대로 존재한다.
(아래 필터들 이외에 다양한 필터들이 더 존재한다.)
위 필터들은 모든 요청마다 순서대로 동작하며 Skip 되는 필터는 없다.
해당 요청에 대해 모든 필터를 거치면서 담당 역할이 아니면 다음 필터로 그냥 넘겨준다.
Security 필터를 통해 인증된 주체(Principal)는 Security Context에 Authentication 객체로 저장되어 필터끼리 서로 공유한다.
Security Context & Authentication
SecurityContextHolder.getContext().getAuthentication();
SecurityContextHolder
SecurityContext에 접근할 수 있도록 지원한다.
SecurityContext
Authentication이 저장되는 곳이다. 로그인한 사용자 정보를 가지고 있는 저장소로, ThreadLocal에 보관되며 SecurityContextHolder를 통해 접근할 수 있다.
Authentication
Authentication은 인증 정보를 의미하는 인터페이스로 SecurityContext에 저장된다.
제공 메서드
- Object getPrincipal() :로그인 ID 또는 인증된 User객체가 제공된다.
- Object getCredentials() : 비밀번호가 제공된다.
- Oject getDetails() : 인증된 User의 상세정보가 제공된다.
- Collection <> getAuthorities() : 인증된 User의 권한 목록이 제공된다.
- boolean isAuthenticated() : 인증 여부가 제공된다.
- void setAuthenticated() : 인증 전 false, 인증 후 true를 세팅한다.
인증 (Authentication) 관련 Filter
Spring Security는 대표적으로 Form기반 로그인, 자동 로그인 두 가지 방식의 인증을 처리한다.
인증은 세션-쿠키 기반으로 이루어진다.
UsernamePasswordAuthenticationFilter
- UsernamePasswordAuthenticationFilter는 폼 기반 로그인 인증을 담당하는 서블릿 필터이다.
- 아래 캡처 사진에서 노란색박스 표시는 내가 Security 사용하면서 customizing 한 부분이다. (+ DaoAuthentication)
UsernamePasswordAuthenticationFilter 동작 흐름은 아래와 같다.
- 폼 로그인 인증이 요청되면 UsernamePassworAuthenticationFilter에서 ProviderManager로 요청 정보(아이디, 패스워드)를 넘긴다.
- ProviderManager는 1.로 부터 전달받은 정보로 아직 인증되지 않은 익명의 Authentication을 생성해 SecurityContext에 저장한다.
- 다양한 AuthenticationProvider들 중 폼로그인 인증을 담당하는 DaoAuthenticationProvider를 호출한다.
- DaoAuthenticationProvider는 UserDetailsService에게 요청 정보 중 아이디를 넘긴다.
- UserDetailsService는 4.으로부터 전달받은 아이디로 DataBase에서 조회한다.
- 만일 이때 조회된 정보가 없으면 UserDetailsService는 exception을 날린다.
- 5. 에서 조회된 사용자 정보를 UserDetails객체로 만든다.
- 6. 에서 만들어진 UserDetails객체를 DaoAuthenticationProvider에거 retuen 한다.
- DaoAuthenticationProvider는 7.으로부터 return 받은 UserDetails에 담긴 비밀번호와 Authentication의 비밀번호를 비교하여 일치하는지 확인한다.
- 일치하지 않는다면 exception을 날린다.
- 인증이 성공되었다면, UserDetails를 Authentication객체로 SecurityContext에 저장하고 AuthenticationSuccessHandler를 통해 인증 처리를 마무리한다.
만일, 인증 과정에서 exception이 발생한 경우 AuthenticationFailureHandler가 이를 캐치하여, 인증 실패 처리로 마무리한다.
RememberMeAuthenticationFilter
- RememberMeAuthenticationFilter는 자동 로그인 인증을 담당하는 서블릿 필터이다.
- 아래 캡처 사진에서 노란색박스 표시는 내가 Security 구현하면서 customizing 한 부분이다.
RememberMeAuthenticationFilter의 동작 흐름은 다음과 같다.
- 자동 로그인 쿠키가 전달되면 RememberMeAuthenticationFilter는 Request, Response 객체를 AbstrackRememberMeService로 전달한다.
- AbstrackRememberMeService는 Request에 담긴 자동로그인 쿠키 데이터로 UserDetails 객체를 생성한다.
- 2. 에서 생성된 UserDetails를 RememberMeAuthenticationFilter가 익명의 Authentication으로 SecurityContext에 저장한다.
- ProviderManager를 호출한다.
- ProviderManager는 자동 로그인 인증을 담당하는 RememberMeAuthenticationProvider를 통해 DB에서 사용자 정보를 조회하여 가져와 UserDetails로 생성한다.
- 5. 에서 가져온 UserDetails와 토큰 값을 비교하여 인증 처리를 진행한다.
- 인증 성공 시 DB를 통해 가져온 UserDetails를 Authentication으로 SecurityContext에 저장한다.
- 인증 실패 시 SecurityContext를 초기화시킨다.
- 6. 의 인증 성공 여부에 따라 인증 처리를 마무리한다. 인증 실패 시 Request의 쿠키를 제거한다.
인가 (Authorization) 관련 Filter
Spring Security는 모든 요청에 대한 인가 처리를 수행한다.
FilterSecurityInterceptor
- 아래 캡처 사진에서 노란색박스 표시는 내가 Security 구현하면서 customizing 한 부분이다.
FilterSecurityInterceptor 필터는 Spring Security Filter의 맨 마지막에 동작하는 필터로 인가 처리를 담당한다.
- 모든 요청에 대한 인가처리를 담당하고, 인증된 사용자에 한해서만 동작한다.
- Application이 빌드되어 실행되면 Security에서 사용자가 정의한 uri별 권한 정보가 SecurityMetadataSource로 만들어진다.
- FilterSecurityInterceptor 필터는 SecurityMetadataSource에서 현재 요청 uri의 권한 value를 가져와 사용자가 해당 권한을 가지고 있는지를 확인하여 인가 처리한다.
https://spring.io/projects/spring-security#overview
https://docs.spring.io/spring-security/site/docs/5.3.x/reference/pdf/spring-security-reference.pdf
Spring Security 구현
2021.10.23 - [IT 기술/권한 인증&인가] - [Spring Security] Authentication 라이브러리 구현
'기술 > Spring Security' 카테고리의 다른 글
[Spring security] 인증 및 권한 체크 (0) | 2021.10.24 |
---|---|
[Spring Security] 로그인 기능 구현 (0) | 2021.10.24 |
[Spring security] Authentication 라이브러리 구현 (0) | 2021.10.23 |