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 모듈
SecurityContextHolder
현재 보안 컨텍스트에 대한 세부 정보가 저장
SecurityContext
Authentication을 보관하는 역할
Authentication
현재 접근하는 주체의 정보와 권한을 담는 인터페이스
- Authentication 객체는 Security Context에 저장
- SecurityContextHolder를 통해 SecurityContext에 접근
- SecurityContext를 통해 Authentication에 접근
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 인증절차
- 사용자가 id, password 로 로그인요청
AuthenticationFilter
에서 id와 password를 기반으로UsernamePasswordAuthenticationToken
생성AuthenticationManage
가 UsernamePasswordAuthenticationToken을 받아서 UserDetailService로 보내서 id가 DB에 있는값과 일치하는지 체크- 있으면) AuthenticationManager가 password를 BCrypt를 이용해 인코딩 후 DB값과 일치하는지 체크
- 일치하면) 인증이 성공한(isAuthenticated=true) 객체
Authentication을 생성
+Security Context에 저장
- 인증 상태를 유지하기 위해 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