Spring Security란?
스프링 기반의 어플리케이션의 보안(인증과 권한)을 담당하는 프레임워크임
만약 Spring Security를 사용하지 않는다면, 자체적으로 세션 체크를하고 Redirect 등을 해야할 것임
스프링 시큐리티는 보안과 관련해서 체계적으로 많은 옵션들을 지원해줌
filter 기반으로 동작하기 때문에 Spring MVC와 분리되어 관리 및 동작함
참고로 security 3.2 부터는 XML로 설정하지 않고도 자바 bean 설정으로 간단하게 설정할 수 있도록 지원함
먼저, 본안관련 용어 정리를 해보자
- 접근 주체 (Principal) : 보호된 대상에 접근하는 유저
- 인증 (Authenticate) : 현재 유저가 누구인지 확인 (Ex: 로그인)
- 어플리케이션의 작업을 수행할 수 있게 인식된 주체임을 증명
- 인가 (Authorize) : 현재 유저가 어떤 서비스, 페이지에 접근할 수 있는 권한이 있는지 검사
- 권한 : 인증된 주체가 어플리케이션의 동작을 수행할 수 있도록 허락되있는지를 결정
- 권한 승인이 필요한 부분으로 접근하려면 인증 과정을 통해 주체가 증명 되어야함
- 권한 부여에도 두가지 영역이 존재하는데 웹 요청 권한, 메소드 호출 및 도메인 인스턴스에 대한 접근 권한 부여
Spring Security 구조
- 인증 관련 Architecture
- Security의 Filter들
- Authentication
- AuthenticationManager
- 기타...
2-1. 인증 관련 Architecture
기본적으로 Spring Security는 세션-쿠키 방식으로 인증이 실행됨 (디폴트 설정은 JWT 기반 토큰이 아님)
- 사용자 로그인을 하면 id, password가 Request에 담아져 보내진다.
- AuthenticationFilter에서 request가 보낸 id, password를 가로채 인증용 객체(UsernamePasswordAuthenticationToken)로 만든다.
- 인증을 담당할 AuthenticationManager 인터페이스(구현체 - ProviderManager)에게 인증용 객체를 준다.
- 실제 인증을 할 AuthenticationProvider에게 다시 인증용 객체를 전달한다.
- 인증 절차가 시작되면 AuthenticationProvider 인터페이스가 실행 -> DB에 있는 이용자의 정보와 화면에서 입력한 로그인 정보 비교
- AuthenticationProvider 인터페이스에서는 authenticate() 메소드를 오버라이딩 하게 되는데 이 메소드의 파라미터인 Authentication으로 화면에서 입력한 로그인 정보를 가져올 수 있다.
- AuthenticationProvider 인터페이스에서 DB에 있는 이용자의 정보를 가져오려면, UserDetailsService 인터페이스를 사용.
- UserDetailsService 인터페이스는 화면에서 입력한 이용자의 id(username)를 가지고 loadUserByUsername() 메소드를 호출하여 DB에 있는 이용자의 정보를 UserDetails 형으로 가져온다. 만약 이용자가 존재하지 않으면 예외를 던진다. (UserDetails를 User와 Authentication 사이를 채워주는 Adaptor라고 생각하자)
- 5,6,7을 통해 가져온 정보(DB를 통해 가져온 이용자정보, 화면에서 입력한 이용자 정보)를 비교하고, 일치하면 Authentication 참조를 리턴하고, 일치 하지 않으면 예외를 던진다.
- -> 인증이 완료되면 사용자 정보를 가진 Authentication 객체를 SecurityContextHolder에 담은 이후 AuthenticationSuccessHandler을 실행.(실패시 AuthenticationFailureHandler 실행)
2-2. Security의 Filter들
- SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 저장하는 역할을 한다. (SecurityContext는 밑에)
- LogoutFilter : 설정된 로그아웃 URL로 오는 요청을 감시하며, 해당 유저를 로그아웃 처리
- (UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리
- AuthenticationManager를 통한 인증 실행
- 인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행
- 인증 실패 시, AuthenticationFailureHandler 실행
- DefaultLoginPageGeneratingFilter : 인증을 위한 로그인폼 URL을 감시한다.
- BasicAuthenticationFilter : HTTP 기본 인증 헤더를 감시하여 처리한다.
- RequestCacheAwareFilter : 로그인 성공 후, 원래 요청 정보를 재구성하기 위해 사용된다.
- SecurityContextHolderAwareRequestFilter : HttpServletRequestWrapper를 상속한 SecurityContextHolderAwareRequestWapper 클래스로 HttpServletRequest 정보를 감싼다. SecurityContextHolderAwareRequestWrapper 클래스는 필터 체인상의 다음 필터들에게 부가정보를 제공한다.
- AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 인증토큰에 사용자가 익명 사용자로 나타난다.
- SessionManagementFilter : 이 필터는 인증된 사용자와 관련된 모든 세션을 추적한다.
- ExceptionTranslationFilter : 이 필터는 보호된 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달하는 역할을 한다.
- FilterSecurityInterceptor : 이 필터는 AccessDecisionManager 로 권한부여 처리를 위임함으로써 접근 제어 결정을 쉽게해준다.
2-3. Authentication
모든 접근 주체(=User)는 Authentication을 생성함
이것은 SecurityContext에 보관되고 사용됨
즉 Security의 세션들은 내부 메모리 (SecurityContextHolder)에 쌓고 꺼내쓰는 것임
참고로 Authentication 인터페이스는 자주 쓰이니 알아둬야함
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities(); // Authentication 저장소에 의해 인증된 사용자의 권한 목록
Object getCredentials(); // 주로 비밀번호
Object getDetails(); // 사용자 상세정보
Object getPrincipal(); // 주로 ID
boolean isAuthenticated(); //인증 여부
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
2-4. AuthenticationManager
유저의 요청 내에 담긴 Authentication을 AuthenticationManager에 넘겨주고, AuthenticationManager를 구현한 ProviderManager가 처리함
정확히는 ProviderManager는 private List<AuthenticationProvider> providers;로 여러 AuthenticationProvider를 가질 수 있는데, 이 친구들이 처리를 해서 Authentication을 반환해줌 (실패하면 예외처리)
- AuthenticationManager : 인증요청을 받고 Authentication를 채운다.
- AuthenticationProvider : 실제 인증이 일어나며, 성공하면 Authentication.isAuthenticated = true 를 한다.
참고
https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/reference/htmlsingle/#getting-started
spring security 파헤치기 (구조, 인증과정, 설정, 핸들러 및 암호화 예제, @Secured, @AuthenticationPrincipal,
참조문서 https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/reference/htmlsingle/#getting-started http://springsource.tistory.com/80 https://okky.kr/article/382738 1. 스프링 시큐리티란? 스프링 시큐리티는 스프링 기반의
xzio.tistory.com
https://parkmuhyeun.github.io/study/spring%20security/2022-01-29-Spring-Security(1)/
Spring Security 과정을 이해해보자
Spring Security 과정을 이해해보자 29 Jan 2022 in study / Spring security Spring Security 이해 인터넷을 보고 프로젝트에 Spring Security를 적용시켜봐도 UserDetails, Principal, AuthenticationProvider 등등.. 이게 도대체 무
parkmuhyeun.github.io
https://mangkyu.tistory.com/77
[SpringBoot] Spring Security 처리 과정 및 구현 예제
이번에는 Spring Security가 어떤 과정으로 Authentication 처리를 하는지, 그리고 실제로 어떻게 구현하는지 알아보도록 하자. 1. Spring Security 처리 과정 Spring Security 아키텍쳐는 위와 같으며 각각의 처리
mangkyu.tistory.com
https://catsbi.oopy.io/c0a4f395-24b2-44e5-8eeb-275d19e2a536
스프링 시큐리티 기본 API및 Filter 이해
목차
catsbi.oopy.io
위 참고 사이트 중요!
'Spring' 카테고리의 다른 글
JPA에서 N+1 문제 (0) | 2023.06.14 |
---|---|
QueryDSL (0) | 2023.05.15 |
JPA의 Transactional (0) | 2023.05.15 |