Spring Security
- 애플리케이션의 보안을 담당하는 스프링 하위 프레임 워크
- '인증', '권한'에 대한 부분을 Filter 흐름에 따라 처리
- Filter 는 Dispatcher Servlet 으로 가기 전에 적용되므로, 가장 먼저 URL 요청을 받지만, Interceptor는 Dispatcher, Controller 사이에 위치한다는 점에서 적용 시기의 차이가 있다
Spring Securiy 아키텍처
인증 관련 Architecture

1.User 가 form 에 아이디, 패스워드 입력하면 HTTPServletRequest 에 아이디, 비밀번호 정보가 전달
- AuthenticationFilter가 넘어온 아이디와 비밀번호의 유효성 검사를 실시
2.유효성 검사 후 실제 구현체인 UsernamePasswordAuthenticationToken 을 만들어 넘겨줌
3.인증용 객체인 UsernamePasswordAuthenticationToken 을 AuthenticationManager 에게 전달
4.UsernamePasswordAuthenticatonToken 을 AuthenticationProvider 에게 전달
5.사용자의 아이디를 UserDetailsService 로 보냄
- UserDetailService 는 사용자 아이디로 찾은 사용자의 정보를 UserDetails 객체로 만들어 AuthenticationProvider 에게 전달
6.DB에 있는 사용자 정보를 가져옴
7. 입력 정보와 UserDeatils 의 정보를 비교해 실제 인증 처리 진행
8. ~10까지 인증이 완료되면 SecurityContextHolder 에 Authentication저장
- 인증 성공여부에 따라 AuthenticationSuccessHandler , 실패 시 AuthenticationFailureHandler 핸들러 실행
인증 (Authorization) 과 인가(Authentication)
- 인증 : 해당 사용자가 본인이 맞는지 확인하는 절차
- 인가 : 인증된 사용자가 요청한 자원에 접근 가능한지 결정하는 절차

- 인증 절차를 거친 후 인가 절차 진행
- 인가 과정에서 해당 리소스에 대한 접근 권한이 있는지 확인
- Spring Security 는 인증,인가를 위해 Principal 를 아이디로, Credential 을 비밀번호로 사용하는 Credentail 기반의 인증방식 사용
- Pricipal : 보호받는 Resource 에 접근하는 대상
- Credential : Resource에 접근하는 대상의 비밀번호
Spring Securiy 모듈
SecurityContextHolder
- 보안 주체의 세부 정보를 포함하여 응용 프로그램의 현재 보안 컨텐스트에 대한 세부 정보 저장
- SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 방법과SecurityContextHolder.MODE_THREADLOCAL 방법을 제공
SecurityContext
- Authentication을 보관하는 역할을 하며, SecurityContext를 통해 Authentication 객체를 꺼내올 수 있다.
Authentication
- 현재 접근하는 주체의 정보와 권한을 담는 인터페이스
- Authentication 객체는 Security Context에 저장
- SecurityContextHolder 를 통해 SecurityContext 에 접근
- SecurityContext 를 통해 Authentication 에 접근
UsernamePasswordAuthenticationToken
- Authentication 을 implement 한 AbstractAuthenticationToken의 하위 클래스
- User ID 가 Pricipal 역할을 하고, Password 가 Credential 역할을 한다
- 첫번째 생성자는 인증전의 객체를 생성하고, 두번째 생성자는 인증이 완료된 객체 생성
AuthenticationProvider
- 실제 인증에 대한 부분을 처리, 인증전의 Authenticaion 객체를 받아서 인증이 완료된 객체 반환
- AuthenticationProvider 인터페이스를 구현해서 Custom한 AuthenticationProvider을 작성해서 AuthenticationManager에 등록
Authentication Manager
- 인증에 대한 부분은 SpringSecurity 의 AuthenticationManager 를 통해서 처리
- 실질적으로 AuthenticationManager에 등록된 AuthenticationProvider에 의해 처리
- 인증이 성공하면 2번째 생성자를 이용해 인증이 성공한 객체를 생성하여 Security Context에 저장
- 인증 상태를 유지하기 위해 세션에 보관, 실패한 경우 AuthenticationException를 발생
UserDetails
- 인증에 성공하여 생성된 UserDetails 는 Authentication 객체를 구현한 UsernamePasswordAuthenticationToken을 생성하기 위해 사용
- UserDetails 인터페이스의 경우 직접 개발한 UserVO 모델에 UserDetails를 implements하여 이를 처리하거나 UserDetailsVO에 UserDetails를 implements하여 처리
UserDetailService
- UserDetails 객체를 반환하는 단 메서드를 가지고 있느데
- 클래스 내부에서 UserRepository 를 주입받아 DB와 연결되어 처리
Password Encoding
- AuthenticationManagerBuilder.userDetailsService().passwordEncoder() 를 통해 패스워드 암호화에 사용될 PasswordEncoder 구현체를 지정
GrantedAuthority
- 현재 사용자(principal)가 가지고 있는 권한
- ROLEADMIN나 ROLE_USER와 같이 ROLE*의 형태로 사용
- GrantedAuthority 객체는 UserDetailsService에 의해 불러올 수 있고, 특정 자원에 대한 권한이 있는지를 검사하여 접근 허용 여부를 결정
출처: https://mangkyu.tistory.com/76 [MangKyu's Diary:티스토리]