Spring Security

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

  • 인증과 권한에 대한 부분을 Filter 흐름에 따라 처리
    • 인증(Authentication) : 해당 사용자가 본인이 맞는지 확인
    • 인가(Authorization) : 인증된 사용자가 요청한 자원에 접근 가능한지 확인
  • 보안과 관련해서 체계적으로 많은 옵션을 제공
    -> 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다는 장점


참고) Filter와 Interceptor! - 적용시기의 차이

  • Filter : Dispatcher Servlet으로 가기 전에 적용
    -> 가장 먼저 URL 요청 받음
    • WebApplication에 등록(web.xml)
    • Spring 과는 무관하게 Servlet 자원
    • Security의 인증 절차는 Filter chain을 거쳐 dispatcherservlet으로 가기전에 적용
      -> Filter chain 통해 걸러진 request 요청을 Interceptor 이용해서 전후 처리
  • Interceptor : Dispatcher와 Controller사이에 위치
    • Spring의 Bean으로 관리되면서 Spring Context 내에 속함
    • 시큐리티 나오기 전 인증, 권한 체크 로직 많이 쓰였음


Credential 기반의 인증방식

Principal(접근주체) : 접근하는 대상(아이디)
Credential(비밀번호) : 접근하는 대상의 비밀번호


Spring Security 모듈

qwe

SecurityContextHolder

현재 보안 컨텍스트에 대한 세부 정보가 저장

SecurityContext

Authentication을 보관하는 역할

Authentication

현재 접근하는 주체의 정보와 권한을 담는 인터페이스

  • Authentication 객체는 Security Context에 저장
    • SecurityContextHolder를 통해 SecurityContext에 접근
    • SecurityContext를 통해 Authentication에 접근

aa

UsernamePasswordAuthenticationToken

User의 id와 password를 기반으로 AuthenticationFilter에서 UsernamePasswordAuthenticationToken 생성
User의 id가 Principal 역할을 하고, password가 Credential의 역할

AuthenticationManager

인증이 성공한(isAuthenticated=true) Authentication 객체를 생성하여 Security Context에 저장
인증 상태를 유지하기 위해 세션에 보관하며, 인증이 실패한 경우에는 AuthenticationException를 발생

UserDetails

인증에 성공하여 생성된 UserDetails 객체

  • 시큐리티세션에 저장되는 유저정보는 User Object type이 아닌 UserDetails type이여야함
    • UserDetails 인터페이스의 경우 직접 개발한 UserVO 모델에 UserDetails를 implements
    • UserDetailsVO에 UserDetails를 implements하여 처리

UserDetailsService

UserDetails 객체를 반환하는 메소드를 가짐
일반적으로 이를 구현한 클래스의 내부에 UserRepository를 주입받아 DB와 연결하여 처리

Password Encoding

AuthenticationManagerBuilder.userDetailsService().passwordEncoder() 를 통해 패스워드 암호화에 사용될 PasswordEncoder 구현체를 지정

GrantedAuthority

현재 사용자(principal)가 가지고 있는 권한
ROLE_*의 형태로(ROLE_ADMIN, ROLE_USER) 사용


Security 인증절차

qwe

  1. 사용자가 id, password 로 로그인요청
  2. AuthenticationFilter에서 id와 password를 기반으로 UsernamePasswordAuthenticationToken 생성
  3. AuthenticationManage가 UsernamePasswordAuthenticationToken을 받아서 UserDetailService로 보내서 id가 DB에 있는값과 일치하는지 체크
  4. 있으면) AuthenticationManager가 password를 BCrypt를 이용해 인코딩 후 DB값과 일치하는지 체크
  5. 일치하면) 인증이 성공한(isAuthenticated=true) 객체 Authentication을 생성 + Security Context에 저장
  6. 인증 상태를 유지하기 위해 UserDetails 타입으로 세션에 보관 (인증이 실패한 경우에는 AuthenticationException를 발생)


Reference
https://waynestalk.com/en/spring-security-architecture-explained-en/
https://getinthere.tistory.com/29?category=884180 https://mangkyu.tistory.com/76
https://blog.naver.com/PostView.naver?blogId=h850415&logNo=222755455272&parentCategoryNo=&categoryNo=37&viewDate=&isShowPopularPosts=true&from=search

업데이트: