[ 2022.11.08 TIL-Spring Security ]

Coosla·2022년 11월 8일
0

TIL

목록 보기
12/29
post-thumbnail

Spring Security

✏️ Spring Security 란?

  • Spring 기반 애플리케이션의 보안을 담당하는 스프링 하위 프레임워크
  • 서블릿 필터와 이들로 구성된 필터 체인을 통해 웹 요청에 대한 보안 관련 처리를 수행

✏️ Spring Security 특징

  • 보안과 관련하여 체계적으로 많은 옵션을 제공하여 편리하게 사용 가능
  • Filter 기반으로 동작하여 MVC와 분리하여 관리 및 동작
  • 어노테이션을 통한 간단한 설정
  • Spring Security는 기본적으로 세션과 쿠키방식으로 인증
  • 인증관리자와 접근결정관리자를 통해 사용자의 리소스 접근을 관리

✏️ 보안관련 기본 용어

  • 접근 주체(Principal)
    • 보호된 리소스에 접근하는 대상
  • 인증(Authentication)
    • 보호된 리소스에 접근한 대상을 확인하는 과정
  • 인가(Authorize)
    • 해당 리소스에 대한 권한을 확인하는 과정
  • 권한
    • 인가 과정에서 해당 리소스에 대한 권한을 가졌는지 확인

✏️ Spring Security Architecture 이해하기

  • Spring Security Architecture 구성요소

    • Filters
    • DelegatingFilterProxy
    • FilterChainProxy
    • SecurityFilterChain
    • Security Filters
    • Handling Security Exceptions
  • Filters

    • 스프링 시큐리티는 Servlet Filters를 기반으로 서블릿 지원
    • 요청이 들어올 때 컨테이너는 Filter와 Servlet으로 구성된 FilterChain을 구성
    • Filter는 두개 이상의 필터를 사용 가능, 하나의 Servlet은 하나의 요청과 응답을 처리 가능
    • Filter 메소드
      public interface Filter{
      	// 필터 객체 초기화 및 서비스 추가하기 위한 메소드
      	// 웹 컨테이너가 처음에 init 메소드를 호출, 이후부터는 doFilter를 통해 처리
      	public default void init(FilterConfig filterConfig) throws ServletException;
      
      	// url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기전 웹 컨테이너에 의해 실행되는 메소드
      	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      		throws IOException, ServletException;
      
      	// 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드
      	public default void destroy();
      }
    • Filter는 다운스트림의 Filter/Servlet이 실행하는 것을 막을 수 있고, 요청과 응답을 수정할 수 있음.
    • Filter와 Servlet에 영향을 많이줘서 사용할 때 순서에 유의해야함
  • DelegatingFilterProxy

    • 서블릿 컨테이너의 라이프 사이클과 ApplicationContext를 연결할 수 있는 스프링이 제공하는 Filter의 구현체인 DelegatingFilterProxy를 제공
    • 서블릿 컨테이너에서 Filter를 등록하더라도 스프링에서는 해당 필터를 빈 객체로 인식되지 않아 관리를 하지 못하는 문제를 해결
    • Filter를 스프링 빈으로 등록시켜 스프링의 관리를 받게 하면서 필터의 기능과 스프링의 빈 의존성에 따른 이점을 누림
    • DelegatingFilterProxy는 Filter 인터페이스를 상속받은 스프링빈을 연결하는 중간다리 역할
  • FilterChainProxy

    • FilterChainProxy는 스프링 시큐리티에서 제공하는 특수 필터
    • SecurityFilterChain을 통해 많은 필터 인스턴스를 위임 가능
    • FilterChainProxy는 스프링 빈이여서 DelegatingFilterProxy로 감싸져 있음
    • DelegatingFilterProxy와 마찬가지로 요청을 넘겨주는 위임자 역할을 수행
    • 스프링 시큐리티는 FilterChainProxy를 통해 서블릿을 지원
  • SecurityFilterChain

    • FilterChaniProxy가 요청에 따라 어떤 필터 체인을 실행시켜야할지 파악

    • SecurityFilterChain 안의 SecurityFilter는 스프링 빈

    • SecurityFilter는 DelegatingFilterProxy가 아닌 FilterChainProxy에 등록됨

    • SecurityFilter를 FilterChainProxy에 등록하는 이유

      1. 스프링 시큐리티에서 동작하는 모든 서블릿의 시작점
      2. 스프링 시큐리티의 핵심이며, 보이지 않는 작업을 수행
      3. SecurityFilterChain의 호출 시기 결정에 유연성을 높여줌
    • 여러 SecurityFilterChain이 있을 경우

      • FilterChainProxy에 등록된 SecurityFilterChain의 패턴을 매칭시켜 해당 패턴과 일치하는 SecurityFilterChain을 실행
      • SecurityFilterChain 패턴과 일치하는 패턴이 없을 경우 모든 패턴에 해당하는 '/**' 패턴인 SecurityFilterChainn을 실행
  • SecurityFilters

  • Handling Security Exception

    • ExcetionTranslationFilter는 AccessDeniedException과 AuthenticationException을 HTTP응답으로 변환해줌
    • 예외 처리 흐름
      • 인증되지 않은 유저이거나 AuthenticationException인 경우 인증을 시작
        • SecurityContextHolder를 비움
        • RequestCache에 HttpServletRequest를 저장
          (성공적으로 인증할 경우 RequestCache로 원래 요청으로 돌아감)
        • AuthenticationEntryPoint는 유저에게 자격 증명을 요청할 때 사용
      • 인증 되지 않을 경우, AccessDeniedException이 발생(AccessDeniedHandler가 실행되 접근을 제한)
    • AccessDeniedException 혹은 AuthenticationException을 던지지 않는 경우, ExceptionTranslationFilter는 아무일도 하지않는 것

✏️ Spring Security 주요 어노테이션

  • @Secured 어노테이션
    • 권한이 필요한 부분에 해당 어노테이션을 사용하여 적용 가능
    • 클래스나 메소드 단위까지 지정 가능
    • 예제 코드
      // 접근 가능한 권한이 하나일 때
      @Secured("ROLE_ADMIN")
      public String Method(String param){
      	return returnValue;
      }
      
      // 접근 가능한 권한이 여러개일 때
      @Secured({"ROLE_ADMIN", "ROLE_USER"})
      public String Method(String param){
      	return returnValue;
      }
  • @PreAuthorize 어노테이션과 @PostAuthorize 어노테이션
    • @PreAuthorize : 요청이 들어와 비즈니스 로직이 실행되기 전에 권한을 검사
    • @PostAuthorize : 비즈니스 로직이 실행된 후 응답하기 직전에 권한을 검사
    • 권한 확인관련 메소드
      • hasRole(권한) : 현재 사용자의 권한이 파라미터의 권한과 동일한 경우 true
      • hasAnyRole(권한1, 권한2, ...) : 현재 사용자의 권한이 파라미터의 권한 중 일치하는 것이 있는 경우 true
      • isAnonymous() : 현재 사용자가 익명인 상태인 경우 true
      • isRememberMe() : 현재 사용자가 RememberMe사용자라면 true
      • isAutenticated() : 현재 사용자가 로그인 상태라면 true
      • isFullyAuthenticated() : 현재 사용자가 익명이거나 RememberMe사용자가 아니라면 true
      • principal : 사용자를 증명하는 주요객체를 직접 접근
      • authentication : SecurityContext에 있는 authentication 객체에 접근
      • permitAll : 모든 접근 허용
      • denyAll : 모든 접근 비허요
    • 예제 코드
      @PreAuthorize("hasRole('권한')")
      @GetMapping("경로")
      public String ControllerMethod(Param){
      	...
      }
      
      @PostAuthorize("hasRole('권한')")
      @GetMapping("경로")
      public String ControllerMethod(Param){
      	...
      }
  • @EnableGlobalMethodSecurity 어노테이션
    • MethodSecurity를 따로 설정할 때 사용
    • MethodSecurity는 Security 설정 파일의 설정이 적용되자 않음
    • 속성
      • securedEnabled : @Secured 어노테이션 활성화 여부 선택
      • prePostEnabled : @PreAuthorize와 @PostAuthorize 어노테이션 활성화 여부 선택
  • @EnableWebSecurity 어노테이션
    • Spring Security를 활성화

참고

profile
프로그래밍 언어 공부 정리

0개의 댓글