ㅅㅇ

[Spring Securtiy] Spring Securtiy 기본 개념 본문

SW_STUDY/SpringBoot

[Spring Securtiy] Spring Securtiy 기본 개념

SO__OS 2023. 3. 8. 19:12

0. Spring Securtiy

스프링 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크

1. 스프링 필터를 사용하기 위한 위임 서블릿 필터

 

https://gngsn.tistory.com/160

1. DelegatingProxyChain

: 필터와 빈을 연결해주는 클래스 즉, 서블릿 필터에서 스프링 빈들을 주입하거나 사용하기 위해 필요한 클래스가 바로 DelegatingProxyChain 이다.

  • 왜 필요한가 ?

서블릿 필터는 스프링 빈을 주입해서 사용할 수 없다.

스프링 빈은 스프링 컨테이너에서 생성 및 하는 컴포너트이고 서블릿필터는 서블릿 컨테이너에서 생성 및 관리하는 필터들이기 때문에 서로 실행되는 위치가 다르기 때문이다.

 

스프링 시큐리티는 요청에 대한 인증 및 인가와 같은 보안 처리를 필터 기반으로 처리하는데, 개발자는 필터에서도 스프링 빈을 사용하고 싶을 것이다.

 

스프링에서 관리하는 필터를 사용하기 위해

     SpringSecurityFilterChain 를 가지고 있는 FilterCainProxy 라는 빈 클래스에게

     자신이 요청 받은 요청 객체를 delegate request 로 위임해주는 서블릿 필터이다.

 

2. SpringSecurityFilterChain

: 스프링에서 서블릿 필터로 구현한 빈.

해당 빈은 DelegatingProxyChain 을 통해 해당 필터 (스프링 빈)은 요청을 위임 받는다.

3. FilterChainProxy

: springSecurityFilterChain 라는 이름의 Bean 을 가진 Bean Class.

 

⇒ DelegatingFilterProxy로 부터 요청을 위임 받고 각 필터들을 순서대로 호출하며 인증/인가처리 및 각종 요청에 대한 실제 보안 처리를 수행

 

  1. 클라이언트 user 요청
  2. Servlet Container 의 필터들이 처리. 그 필터 중 DelegatingFilterProxy 이 요청 받게 될 때, delegate 로 springSecurityFilterChain 필터에게 자신의 요청을 위임한다.
  3. 해당 필터를 가지고 있는 빈 FilterChainProxy 는 자신이 가진 각각의 필터들을 차례대로 수행하며 인증 및 인가 보안 처리를 수행한다.
  4. 보안 처리가 완료 되면 최종 자원에 요청을 전달하여 다음 로직이 수행된다.

4. 필터 초기화 설정 및 다중 보안 설정

https://gngsn.tistory.com/160

 

Spring Security에서는 인증, 인가에 대한 처리를 여러개의 필터를 연쇄적으로 실행하여 수행하는데, 필요한 필터가 있고 필요 없는 필터에 대하여 설정을 해줘야 한다.

 

그리고 WebSecurityConfigurerAdapter를 구현한 설정 파일의 내용을 기반으로 해당되는 필터들을 생성한다.

이때, 실제 필터를 생성하는 클래스가 바로 HttpSecurity 이다.

 

스프링 시큐리티는 보안 설정을 여러 설정을 만들어 동시에 사용 가능하다.

설정 클래스(securityConfig) 별로 RequestMatcher 를 다르게 설정하여 보안 기능(필터)이 각각 작동하게 한다.

 

FilterChainProxy 에서 요청을 받아 요청을 처리를 필터를 선택하는데, 이때, 요청에 따라 해당 RequestMatcher 와 매칭되는 필터가 작동되게 되는 것이다.

 

이렇게 설정 파일 별로 필터 목록을 갖게 된 후, 이 필터들은 WebSecurity 클래스에게 전달되게 된다.

WebSecurity는 각각 설정 클래스로 부터 필터 목록들을 전달받고, 다시 FilterChainProxy를 생성자의 인자로 전달한다.

 

=> FilterChainProxy는 각각의 설정 클래스 별(SecurityConfig1, SecurityConfig2)로 필터 목록들을 갖고 있는 형태가 된다.

 

2. 인증과 인가 그리고 인증 객체

1. 인증 Authentication

: 요청하는 사용자가 누구인지 증명하는 행위

2. 인가 Authorization

: 권한부여, 허가. 인증 된 사용자가 특정 자원에 접근하고자 할 때 접근 할 자격이 되는지 증명하는 것.****

  • 권한 : 인증된 주체가 애플리케이션의 동작을 수행할 수 있도록 특정 자원에 접근할 수 있게 허락되는 권한
  • 사용자가 특정 자원에 접근 요청(Request)을 할 때, 그 사용자가 인증을 받았는지, 인증을 받은 사용자라면 해당 자원에 접근할 수 있는 권한이 있는지 확인한다.

⇒ FilterSecurityInterceptor - 인가 처리 담당 필터

3. 인증 객체 Authentication

: 인증 완료된 사용자의 인증 정보/권한 정보를 저장하는 객체.

  • 인증 시, 로그인 과정의 유저 아이디와 비밀번호를 담고 인증 검증을 위해 전달되어 사용된다.
  • 인증 후 최종 인증 결과 (User 객체, 권한 정보) 를 담고 SecutrityContext 에 저장되어 전역적으로 참조한다.

⇒ 여러 필터 처리를 통해 생성되고 저장되고 사용된다.

 

1. Authentication 객체의 구조

  • principal: User객체 (보호된 대상에 접근하는 유저)
    • userDetails
      • 보통, 사용자 이메일, 패스워드, 회원 타입 user 및 admin 정보를 담음.
      • loadUserByUsername 으로 조회함.
      • User(implements UserDetails, CredentialsContainer) 을 상속받음.
  • credentials: 사용자 비밀번호
  • authorities: 인증된 사용자의 권한 목록 (userDetails.getAuthorities())
  • details: 인증 부가 정보
  • Authenticated: 인증 여부(Bool)

2. SecurityContext

: Authentication 객체가 담기는 클래스

  • ThreadLocal에 저장되어 Thread마다 할당된 고유 공간이다. 즉, 공유가 아니기에 다른 Thread 로부터 안전하다.
  • get, set, remove API 있음.
  • 인증 완료되면 HttpSession에 저장되기에 어플리케이션 전반에 걸쳐 전역적으로 참조 가능한 것이다.

3. SecurityContextHolder

: SecurityContext 객체를 저장하고 감싸고 있는 wrapper 클래스

  • ThreadLocal이 SecurityContextHolder를 담고 있는 것
  • 저장 방식
    • MODE_THREADLOCA : 디폴트로 스레드 당, 객체를 할당
    • MODE_INHERITABLETHREADLOCAL : 메인 스레드와 자식 스레드에서 동일한 SecurityContext 를 가지도록
    • MODE_GLOBAL : 응용 프로그램에서 즉, 메모리에서 단 하나의 SecurityContext 를 가짐.
  • 최종 인증 결과 즉, Authentication 인증 객체 를 SecurityContext에 저장
SecurityContextHolder.getContext().setAuthentication(authentication);
  • 저장한 인증 객체를 전역적으로 참조 가능
Authentication authentication = SecurityContextHolder.getContext().getAuthentication()

 

  • SecurityContext기본 정보 초기화 메서드
SecurityContextholder.clearContext()

 

[참고]
https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0
https://blog.naver.com/PostView.naver?blogId=qjawnswkd&logNo=222093198685&categoryNo=33&parentCategoryNo=0&viewDate=¤tPage=1&postListTopCurrentPage=&from=postList&userTopListOpen=true&userTopListCount=10&userTopListManageOpen=false&userTopListCurrentPage=1
https://ojt90902.tistory.com/828