스프링에서 제공하는 공식 문서 ➡️ https://spring.io/projects/spring-security
스프링 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크
한줄 설명에서 인증, 인가 라는 말이 나오는데 이거 두개가 동일한게 아닌가 ? 라는 생각이 들 수 있다. 사실 나도 그랬다
그렇기 때문에 스프링 시큐리티에 대해 본격적인 정리를 들어가기 전에 먼저 보안 관련 단어들을 정리하고 들어가자
이름 | 설명 |
---|---|
인증 (Authenticate) | 접근하려는 유저가 누구인지 확인하는 절차 EX) 회원가입하고 로그인 |
인가 (Authorization) | 인증된 사용자에 대해서 권한을 확인하고 허락하는 것 |
접근 주체 (Principal) | 보호된 대상에 접근하는 유저 |
비밀번호 (Credential) | 대상에 접근하는 유저의 비밀번호 |
인증과 인가에 대해서 예시를 들어보자면
한 사용자가 velog 에 글을 작성하기 위해서 로그인을 했다 ➡️ 인증
로그인 한 사용자가 신나게 글을 썼다. 그리고 다른 사람 글을 수정하기 위해서 권한을 확인해봤지만 수정할 수 없었다 ➡️ 인가
그니깐 간단하게 생각해서 사이트에 대해서 유효한 사용자인지 확인하는 것이 인증 이고, 인증된 사용자가 사용할 수 있는 기능인지 확인하는게 인가 라고 생각하면 된다 그렇기 때문에 인증이 먼저 이루어 지고 인가가 이뤄져야 한다.
Spring Security 에서는 이러한 인증, 인가를 위해 Principal 을 아이디로 Credential 을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.
출처 : https://limdevbasic.tistory.com/19
스프링 시큐리티는 서블릿의 필터를 기반으로 동작한다.
사용자의 요청이 서블릿에 전달되기 전, 스프링 시큐리티는 필터의 생명주기를 이용해서 인증과 권한 작업을 수행 하지만, 서블릿 컨테이너는 스프링 컨테이너에 등록된 빈을 인식할 수 없다.
그렇기 때문에 스프링 시큐리티에서는 DelegatingFilterProxy 라는 서블릿 필터의 구현체를 제공한다. DelegatingFilterProxy 는 서블릿 매커니즘으로 서블릿의 필터로 등록될 수 있으며, 스프링에 등록된 빈을 가져와서 의존성을 주입할 수도 있다. 결론적으로 서블릿 컨테이너의 생명주기와 스프링의 ApplicationContext 사이를 연결하는 다리 역할을 하게된다.
DelegatingFilterProxy 를 통해 받은 요청과 응답을 스프링 시큐리티 필터체인에 전달하고 작업을 위임하는 역할을 한다.
🤔 DelegatingFilterProxy 에서 바로 SecurityFilterChain 을 실행시킬 수 있지만 중간에 FilterChainProxy 를 둔 이유 ?
➡️ 서블릿을 지원하는 시작점 역할을 하기 위함이다. 이를 통해 서블릿에서 문제가 발생하는 경우 FilterChainProxy 의 문제라는 걸 알 수 있다.
또한, FilterChainProxy 에서 어떤 체인에게 작업을 위임할지도 결정할 수 있음
인증을 처리하는 여러 개의 시큐리티 필터를 담는 필터 체인
여러 개의 SecurityFilterChain 을 구성하여 매칭되는 URL 에 따라 다른 SecurityFilterChain 이 사용되도록 할 수 있다
요청을 스프링 시큐리티 매커니즘에 따라 처리하는 필터
SecurityFilters 에는 순서가 존재함
Username and Password 방식의 아키텍처는 다음과 같다.
spring security 는 기본적으로 세션-쿠키 방식으로 인증한다
UsernamePasswordAuthenticationToken(Object principal, Object credentials)
: 인증 전의 객체를 생성UsernamePasswordAuthenticationToken(Object principal, Object credentials,Collection<? extends GrantedAuthority> authorities)
: 인증 완료된 객체를 생성 loadUserByUsername()
메소드를 통해서 DB 에서 유저 정보를 가져온다. 기본 오버라이드 메소드 ⬇️
메소드 | 설명 |
---|---|
getAuthorities() | 계정의 권한 목록을 리턴 |
getPassword() | 계정의 비밀번호 리턴 |
getUsername() | 계정의 고유한 값 리턴 |
isAccountNonExpired() | 계정의 만료 여부 리턴 |
isAccountNonLocked() | 계정의 잠김 여부 리턴 |
isCredentialsNonExpired() | 비밀번호 만료 여부 리턴 |
isEnabled() | 계정의 활성화 여부 리턴 |
ThreadLocal
이라고 함. SecurityContextHolder.getContext()
를 통해 얻을 수 있음 AuthenticationManager.authenticate(Authentication)
에 의해 인증된 principal 혹은 token이름 | 설명 |
---|---|
Principal | 사용자 정보 |
authorities | 사용자에게 부여된 권한 EX) ROLE_ADMIN |
credentials | 자격 증명 |
감사합니다 정말 잘 봤습니다 OTL,