Spring Security
Spring Security는 Spring 기반 애플리케이션에서 `보안` 기능을 쉽게 통합할 수 있도록 도와줍니다. 주로 `인증`과 `인가`를 처리하며 사용자의 신원 확인과 권한 부여를 담당합니다.
Spring Security의 기능들을 나열하자면 다음과 같습니다.
- 인증(Authentication)
사용자의 신원을 확인(증명)하고 인증하는 기능을 제공합니다. 사용자가 제공한 자격 증명(아이디/비밀번호 등)을 검증하고, 인증된 사용자에게 접근 권한을 부여합니다. 다양한 인증 방식을 지원하며, 사용자 정의 인증 프로세스를 구현할 수 있습니다. - 인가(Authorization)
인증된 사용자에 대한 권한 부여 및 접근 제어를 처리합니다. 사용자의 역할, 권한, 리소스에 대한 접근 권한을 관리하고 보호합니다. 선언적인 방식으로 권한 제어를 구성할 수 있으며, 사용자 정의 권한 검사를 수행할 수 있습니다. - 세션 관리
Spring Security는 세션 관리를 처리하는 기능을 제공합니다. 세션 생성, 세션 타임아웃, 세션 공유 등을 구성할 수 있습니다. - CSRF (Cross-Site Request Forgery) 방어
Spring Security는 CSRF 공격으로부터 애플리케이션을 보호하기 위한 기능을 제공합니다. CSRF 토큰을 사용하여 요청의 유효성을 검증하고, 애플리케이션에서 올바른 요청인지 확인합니다. - 다양한 인증 방식
Spring Security는 다양한 인증 방식을 지원합니다. 폼 인증, 기본 인증, OAuth, OpenID 등의 인증 방식을 사용하여 사용자 인증을 처리할 수 있습니다. - etc...
Spring Security 흐름
- 클라이언트가 보호된 애플리케이션에 요청을 보냅니다.
- 요청은 Spring Security의`Security Filter Chain`을 통과합니다. `Security Filter Chain`은 여러 개의 필터로 구성되어 있으며, 각 필터는 특정한 보안 작업을 수행합니다. 가장 중요한 필터 중 하나는 `UsernamePasswordAuthenticationFilter`입니다. 이 필터는 `인증`을 처리합니다. 클라이언트로부터 받은 인증 정보(일반적으로 아이디와 비밀번호)를 가지고 `UsernamePasswordAuthenticationToken` 객체를 생성합니다. `UsernamePasswordAuthenticationToken`은 클라이언트가 제공한 인증 정보를 담고 있습니다.
- 생성된 `UsernamePasswordAuthenticationToken`은`AuthenticationManager`에 전달됩니다.
- `AuthenticationManager`는 실제 인증 작업을 수행합니다. 인증은 `AuthenticationProvider`를 통해 이루어집니다.
- `AuthenticationProvider`는 사용자 인증을 수행하고, 인증 결과를 `Authentication` 객체로 반환합니다.
`Authentication` 객체는 `UserDetailsService`에 의해 생성된 `UserDetails` 객체를 포함하고 있습니다.- `UserDetailsService`는 사용자의 인증 정보를 로드하는 역할을 합니다. 주로 DB나 외부 인증 소스와 연동하여 사용자 정보를 가져옵니다. `UserDetailsService`는 `loadUserByUsername` 메서드를 구현해야 합니다. 이 메서드는 사용자 아이디를 입력받아 해당 사용자의 `UserDetails` 객체를 반환합니다. 밑에 추가로 설명하도록 하겠습니다.
- `UserDetails` 인터페이스는 사용자의 인증 정보와 권한 정보를 정의하는 메서드를 포함하고 있습니다.
- `UserDetails`는 Spring Security에서 제공하는 인터페이스로, 인증된 사용자의 정보를 담고 있는 객체입니다.
- `UserDetails`는 사용자의 아이디, 비밀번호, 권한 정보 등을 반환하는 메서드를 제공합니다.
- `Authentication` 객체는 `SecurityContextHolder`에 저장됩니다. `SecurityContextHolder`는 현재 실행 중인 사용자의 보안 컨텍스트를 저장하고 제공하는 클래스입니다.
- 인증이 완료된 후, `인가(Authorization)` 과정이 진행됩니다. 인가는 인증된 사용자가 보호된 자원에 접근할 수 있는지 권한 여부를 결정하는 과정입니다. 이 과정에서 사용자의 권한과 요청된 리소스의 접근 권한을 비교합니다.
필터 체인을 모두 통과한 후, 요청에 대한 응답이 클라이언트로 전송됩니다.
Filter(필터)
Spring Security 내부에 여러 개의 필터가 각자 특정 책임을 갖고 Request와 Response에 대한 보안 처리를 담당합니다. Spring Security는 `필터 체인(Filter Chain)`이라는 구조를 갖습니다. Filter는 확장 설정하여 다양한 처리가 가능하며 Filter 사이에 종속성이 있어 순서가 중요합니다.
- UsernamePasswordAuthenticationFilter
사용자의 아이디와 비밀번호를 입력받아 인증을 처리하는 필터입니다. 클라이언트로부터 받은 인증 정보를 기반으로 Authentication 객체를 생성하여 인증 작업을 수행합니다. - ExceptionTranslationFilter
인증과 관련된 예외 처리를 담당하는 필터입니다. 인증이 필요한 리소스에 접근할 때 인증되지 않은 경우, 예외를 던지고 해당 예외를 처리합니다. - FilterSecurityInterceptor
인가(Authorization) 처리를 담당하는 필터입니다. 보호된 리소스에 접근할 때, 현재 사용자의 권한을 확인하여 접근을 허용하거나 거부합니다.
Authentication Manager
Spring Security에서 `인증`을 담당하는 핵심적인 역할을 합니다.
Filter에서 받은 request를 받아 인증 관련된 정보인 UsernamePasswordAuthenticationToken이라는 객체를 생성하고 Authentication Manager에게 인증을 처리하게 합니다.
인증을 처리할 때, 내장된 메모리 상에서 처리할 것인지, 아니면 DB를 이용해 인증을 처리할 것인지 등에 따라 방법이 달라지기 때문에 다양한 방법들을 처리하기 위해 `AuthenticationManager`는 하나 이상의 `AuthenticationProvider`를 가지고 있습니다.
`AuthenticationProvider`들은 실제로 인증 작업을 수행하고, `Authentication` 객체를 반환합니다.
`AuthenticationManager`는 등록된 `AuthenticationProvider` 들을 순차적으로 확인하여 인증을 시도합니다. 인증이 성공하면 `AuthenticationManager`가 반환한 `Authentication` 객체를 반환합니다. (만약 인증을 실패하면 예외를 던집니다.)
UserDetailsService
`Provider Manager`가 관리하는 `AuthenticationProvider`가 인증 작업을 진행할 때, 내부적으로 `UserDetailsService`를 이용하여 실제 인증을 하기 위한 데이터를 가져와 처리 합니다.
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
주어진 사용자명을 기반으로 사용자 정보를 로드합니다. 이 메서드는 `UserDetails` 객체를 반환합니다.
일반적으로 DB와 연동한 서비스들은 `UserDetailsService`를 구현한 클래스의 내부에 `UserRepository`를 주입 받아 DB와 연결하여 처리합니다.
`UserDetailsService`는 보통 커스텀 구현체를 만들어 사용자 정보를 DB, 외부 API 등에서 로드합니다. 로드한 정보를 `UserDetails` 객체로 변환하여 반환하고 `AuthenticationProvider`에서 인증 작업에 사용됩니다.
UserDetails
Spring Security에서 사용자 정보를 담는 인터페이스입니다. 이를 통해 사용자의 신원과 권한 정보를 제공합니다.
- getAuthorities(): 사용자의 권한 목록을 반환
- getUsername(): 사용자명을 반환
- getPassword(): 사용자의 암호를 반환
- isAccountNonExpired(): 사용자 계정의 만료 여부를 반환
- isAccountNonLocked(): 사용자 계정이 잠겨 있는지 여부를 반환
- isCredentialsNonExpired(): 사용자의 인증 정보가 만료되지 않았는지 여부를 반환
- isEnabled(): 사용자 계정이 활성화되어 있는지 여부를 반환
SecurityContextHolder
`Spring Security`에서 현재 실행 중인 사용자의 보안 컨텍스트를 저장하고 제공하는 클래스입니다.
SecurityContextHolder
ㄴ--SecurityContext
ㄴ--Authentication 객체
`SecurityContextHolder`는 `SecurityContext`를 관리하고, `SecurityContext`는 `Authentication` 객체를 포함하고 있으며, 이 객체는 현재 인증된 사용자의 정보를 담고 있습니다.
`SecurityContextHolder`를 사용하여 현재 사용자의 보안 컨텍스트를 얻을 수 있습니다. 이를 통해 현재 사용자의 인증 정보 및 권한을 확인하고, 필요한 보안 작업을 수행할 수 있습니다. 예) 현재 사용자의 이름, 권한 목록 등을 가져와서 인가 로직을 구현하거나 로깅 작업을 수행할 수 있습니다.
'Spring Security' 카테고리의 다른 글
WebSecurityConfigurerAdapter Deprecated (0) | 2022.10.14 |
---|---|
Spring Security 프로젝트 시작 (0) | 2022.10.14 |
Spring Security @PreAuthorize, @PostAuthorize, @Secured (0) | 2022.10.02 |
Spring Security Session을 이용한 구현 예제 (0) | 2022.09.29 |
Spring Security 스프링 시큐리티 설정 (0) | 2022.09.09 |