Spring/Security

Spring Security : Spring Security 개념 및 필터들

짱엉 2024. 7. 10. 23:32
728x90

Spring Security(스프링 시큐리티) 란?

애플리케이션 내의 보안 중 사용자에 대한 ‘인증’과 ‘인가’에 대한 처리를 담당하는 프레임워크를 의미한다.
  • 접근 주체(Principal)
    • 보호된 대상에 접근하는 유저
  • 인증(Authenticate)
    • 현재 유저가 누구인지 확인 (ex 로그인)
    • 애플리케이션의 작업을 수행할 수 있는 주체임을 증명한다.
  • 인가(Authorization)
    • 현재 유저가 어떤 서비스, 페이지에 접근할 수 있는 권한이 있는지 검사한다.
    • 어떤것을 할 수 있는지
  • 권한 부여(Authorization)
    • 인증된 주체가 애플리케이션의 동작을 수행할 수 있도록 허락되었는지를 결정
    • 권한 승인이 필요한 부분으로 접근하려면 인증 과정을 통해 주체가 증명되어야 한다.
    • 권한 부여에도 두가지 영역이 존재하는데 웹 요청 권한, 메소드 호출 및 도메인 인스턴스에 대한 접근 권한 부여

스프링 시큐리티 특징과 구조

스프링 시큐리티에서는 주로 서블렛 필터(Filter)와 이들로 구성된 필터체인, 그리고 필터체인들로 구성된 위임모델을 사용한다.

Client (request) → Filter → DispatcherServlet → Interceptor → Controller

인증관리자(Authentication Manager), 접근 결정 관리자(Access Decision Manager)를 통해 사용자의 리소스 접근을 제어

  • 인증 관리자 ⇒ UsernamePasswordAuthenticationFilter
  • 접근 결정 관리자 ⇒ FilterSecurityInterceptor
  • 보안과 관련하여 체계적으로 많은 옵션을 제공하여 편리하게 사용할 수 있다.
  • Filter 기반으로 동작하여 MVC와 분리하여 동작한다.
  • 어노테이션을 통한 간단한 설정
  • 기본적으로 Session & Coockie 방식으로 인증한다. 

 

⚠️ Spring Security 5.7.x 버전에 대한 이슈 사항

public class SecurityConfig extends WebSecurityConfigurerAdapter{}
  • 5.6.x 버전 이하에서는 WebSecurityConfig 클래스에서 WebSecurityConfiguredAdapter를 상속받아서 사용했다
  • 5.7.x 버전부터는 Deprecated되어서 사용이 안됨!
    • 5.7.x 버전 이상부터는 컴포넌트 기반의 Configuration을 구성하는 것으로 권장된다. 

 


Spring Security Authentication Architecture

(1) 전체적인 Spring Security 흐름도와 (2) 아이디와 암호를 입력했을 때 이를 처리하는 필터는 AuthenticationFilter이다. 해당 필터는 다음 그림과 같은 순서로 동작한다.

  1. 사용자가 로그인 정보와 함께 인증 요청을 한다 → Http Request (사용자가 Form을 통해 로그인 정보를 입력하고 인증 요청을 보낸다.)
  2. AuthenticationFilter(사용할 구현체 UsernamePasswordAuthenticationFilter)가 HttpServletRequest에서 사용자가 보낸 아이디와 패스워드를 인터셉트(가로챈다, 확인)한다. 가로챈 정보를 통해 UsernamePasswordAuthenticationToken의 인증용 객체를 생성한다.
  3. HttpServletRequest에서 꺼내온 사용자 아이디와 패스워드를 진짜 인증을 담당할 AuthenticationManager인터페이스(구현체 - ProviderManager)에게 인증용 객체(UsernamePasswordAuthenticationToken) 객체를 전달한다.
  4. AuthenticationManager는 AuthenticationFilter에게 인증용 객체(UsernamePasswordAuthenticationToken)을 전달받는다.
  5. 실제 인증을 할 AuthenticationProvider에게 Authentication객체(UsernamePasswordAuthenticationToken)을 다시 전달한다.
  6. AuthenticationManager는 등록된 AuthenticationProvider(들)을 조회하여 인증을 요구한다.
  7. 실제 DB에서 사용자 인증정보를 가져오는 UserDetailService에 사용자 정보를 넘겨준다.
    • DB에서 인증에 사용할 사용자 정보(사용자 아이디, 암호화된 패스워드, 권한 등)를 UserDetails라는 객체로 전달 받는다.
    • UserDetailsService는 인터페이스이다.
    • 즉, 해당 인터페이스를 구현한 빈(Bean)을 생성하면 스프링 시큐리티는 해당 빈을 사용하게 된다.
  8. UserDetailsService는 로그인한 ID에 해당하는 정보를 DB에서 읽어들여 UserDetails 객체를 만들어 세션에 저장한다.
  9. AuthenticationProvider는 UserDetails 객체를 전달 받은 이후 실제 사용자의 입력 정보와 UserDetails 객체를 가지고 인증을 시도한다.
  10. 인증이 완료되면 권한 등의 사용자 정보를 담긴 Authentication 객체를 반환한다.
  11. 다시 최초의 AuthenticationFilterAuthentication 객체가 반환된다.
  12. Authentication 객체를 인메모리 세션저장소인 SecurityContextHolder에 담는다.
    • 클라이언트(유저)에게 session ID(JSESSION ID)와 함께 응답을 한다. 이후 요청에서는 요청 쿠키에서 JSESSION ID정보를 통해 이미 로그인 정보가 저장되어 있는지 확인하고 이미 저장되어 있고 유효하면 인증처리를 한다.
    • 성공시 AuthenticationSuccessHandle를 실행한다.
    • 실패시 AuthenticationFailureHandler를 실행한다.
    • 사용자 정보를 저장한다는건 Session-Cookie 방식을 사용한다는걸 의미한다.

 

1. AuthenticationManager - 인증 담당

AuthenticationManager - 인증 담당 관리

  • 유저의 요청을 AuthenticationFilter에서 Authentication 객체로 변환해 AuthenticationManager(ProviderManager)에게 넘겨주고, AuthenticationProvider(DaoAuthenticationProvider)가 실제 인증을 한 이후에 인증이 완료되면 Authentication객체를 반환해준다.
  • AbstractAuthenticationProcessingFilter: 웹 기반 인증요청에서 사용되는 컴포넌트로 POST 폼 데이터를 포함하는 요청을 처리한다. 사용자 비밀번호를 다른 필터로 전달하기 위해서 Authentication 객체를 생성하고 일부 프로퍼티를 설정한다.
  • AuthenticationManager: 인증요청을 받고 Authentication을 채워준다.
  • AuthenticationProvider: 실제 인증이 일어나고 만약 인증 성공시 Authentication 객체의 authenticated = true로 설정해준다.
  • Spring Security 는 ProviderManager라는 AuthenticationManager인터페이스의 유일한 구현체를 제공한다. ProviderManager 는 하나 또는 여러 개의 AuthenticationProvider 구현체를 사용할 수 있다. AuthenticationProvider는 많이 사용되고 ProviderManager(AuthenticationManager 의 구현체) 와도 잘 통합되기 때문에 기본적으로 어떻게 동작하는 지 이해하는 것이 중요하다.

 

2. Security Context Holder

  • Spring Security는 인증이 완료되면 아이디, 패스워드를 가진 사용자의 principal 과 credential 정보를 Authentication에 담는다.
  • 그 Authentication 정보를 Security Context에 보관한다.
  • 그리고 그 Security Context를 Security Context Holder에 담아 보관한다.
  • 때문에, 사용자의 정보를 얻기 위한 코드는 다음과 같다.
Object principal = SecurityContextHolder.getContext.getAuthentication.getPrincipal();

if(principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}

 

 

 

3. Password Authentication

 

  • DaoAuthenticationProvider 는 UserDetailsService 타입 오브젝트로 위임한다. UserDetailsService 는 UserDetails 구현체를 리턴하는 역할을 한다.
  • UserDetails 인터페이스는 이전에 설명한 Authentication 인터페이스와 상당히 유사하지만 서로 다른 목적을 가진 인터페이스이므로 헷갈리면 안된다.
  • Authentication : 사용자 ID, 패스워드와 인증 요청 컨텍스트에 대한 정보를 가지고 있다. 인증 이후의 사용자 상세정보와 같은 UserDetails 타입 오브젝트를 포함할 수도 있다.
  • UserDetails: 이름, 이메일, 전화번호와 같은 사용자 프로파일 정보를 저장하기 위한 용도로 사용

 


Spring Security Filter

Clinet -> FilterChain -> DelegatingFilterProxy (위임처리)  -> FilterChainProxy -> Security Filter Chain(시큐리티 필터 적용!)

ServletContainer → SpringContainer, Filter → Dispatcher Servlet

  • Spring Container와 Was 서버간에 Request 요청이 연결되어야 하는데 이를 수행하는 Filter가 DelegationFilterProxy다.
  • DelegatingFilterProxy의 내부에 FilterChainProxy라는 위임대상을 가지고 있다.
    • FilterChainProxy는 SpringSecurity에서 제공되는 특수 필터다.
    • SecurityFilterChain이라는 이름을 가진 Bean을 호출하여 SecurityFilter 역할을 수행한다.

 

 

  • 클라이언트(보통 브라우저)는 요청을 보내게 되고, 그 요청을 서블릿이나 JSP등이 처리하게 된다. 스프링 MVC에서는 요청을 먼저 받는것이 DispatcherServlet 이다.
  • 이 DispatcherServlet이 요청 받기 전에 다양한 필터들이 있을 수 있다.
  • 필터가 하는 역할은 클라이언트와 자원 사이에서 요청과 응답 정보를 이용해 다양한 처리를 하는데 목적이 있다.
    • 어떤 필터는 요청을 받은 후, 클라이언트가 원래 요청한 자원이 아닌 다른 자원으로 리다이렉트 시킬 수도 있다.
    • 또 다른 어떤 필터는 다음 필터에게 요청과 응답을 전달하지 않고, 바로 클라이언트에게 응답하고 끝낼 수 도 있다.
  • 스프링 시큐리티는 다양한 기능을 가진 필터들을 10개 이상 기본적으로 제공한다.
  • 이렇게 제공되는 필터들을 Security Filter Chain(시큐리티 필터 체인) 이라고 말한다.

 


SecurityFilterChain

 

SecurityFilterChain은 List의 형태로 구성되며, 이 리스트를 AuthenticationFilter라 부른다!

securityFilterChain 의 수많은 Filter (그냥 개념만 알면된다..)

 

 

  • (UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리함
    1. AuthenticationManager를 통한 인증 실행
  1. 인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행
  2. 인증 실패 시, AuthenticationFailureHandler 실행

 

 

 

 

728x90