1. 스프링 시큐리티 인증, 인가 흐름
- 인증(Authentication)은 사용자가 누구인지 확인하는 과정
- 인가(Authorization)는 그 사용자가 어떤 리소스에 접근할 수 있는지 결정하는 과정
1.1 인증 흐름
- 클라이언트가 ID와 비밀번호와 같은 자격 증명을 입력하여 로그인 요청을 보내고 이는 Authentication 객체로 변환됨
- AuthenticationManager가 인증 요청을 처리하는데 AuthenticationManager는 여러 개의 AuthenticationProvider에게 인증 처리를 위임
- 각각의 AuthenticaitonProvider는 DB 기반 인증, LDAP 기반 인증 등과 같은 특정 인증 방식에 대해 인증 시도
- 기본적으로 DaoAuthenticaitonProvider가 많이 사용되며 이는 사용자 정보를 UserDetailsService에서 조회하고 사용자의 패스워드를 검증
- AuthenticcationProvider는 사용자의 자격 증명을 확인하기 위해 UserDetailsService를 호출하여 사용자 정보를 가져오고 이때 UserDetailsService는 사용자 이름에 해당하는 UserDetails 객체를 반환
- UserDetails 객체에 담긴 사용자 정보와 클라이언트가 입력한 자격증명을 비교하는데 패스워드는 일반적으로 PasswordEncoder를 사용해 해시된 값과 비교
- 사용자가 유효한 자격 증명을 제공한 경우 AuthenticationManager는 인증이 성공했다고 판단하고 Authentication 객체를 SecurityContext에 저장하며 이때 인증된 Authentication 객체는 인증된 사용자의 세부 정보를 포함
- 인증 성공했을 경우 Spring Security는 인증된 사용자 정보를 SecurityContextHolder에 저장하고 애플리케이션의 흐름을 계속 진행시킴
- 인증 실패 시 AuthenticationException 예외가 발생하며 인증 실패 페이지로 리다이렉트 됨
1.2 인가 흐름
인증이 완료된 후, 사용자가 애플리케이션 내의 리소스에 접근할 때 인가가 이루어지며 인가는 앞서 언급했다시피 해당 사용자가 요청한 리소스에 접근할 수 있는 권한이 있는지를 확인하는 과정입니다.
- 사용자가 특정 URL에 접근을 시도하면 Spring Security의 필터 체인이 이를 가로채고 적절한 인가 검사를 수행
- 일반적으로 SecurityFilterChain에 등록된 여러 필터가 존재하며 인가는 주로 FilterSecurityInterceptor에 의해 처리됨
- FilterSecurityInterceptor는 요청에 대한 인가 결정을 내리기 위해 AccessDecisionManager를 호출하며 해당 리소스에 대한 접근을 허용할지 여부를 결정
- FilterSecurityInterceptor는 요청 URl, 메서드 등과 같은 요청 정보에 매핑된 ConfigAttributes를 확인하며 해당 리소스에 접근 가능한 권한 목록을 얻음
- AccessDecisionManager는 인증된 Authentication의 권한과 ConfigAttributes에 정의된 접근 조건을 비교하여 접근 여부를 결정
- 사용자에게 적절한 권한이 부여된 경우 요청이 통과되어 리소스에 접근을 허용
- 사용자가 리소스에 대한 권한 없을 경우 AccessDeniedException 예외가 발생하고 403 Forbidden 응답 반환
2. GrantedAuthority
- GrantedAuthority를 활용하여 권한 부여 기능 적용 가능
- 적용 시 사용자마다 다른 권한을 가지게 되며 권한에 따라 특정 작업만 수행할 수 있음
- 사용자, 권한, 기능은 서로 엮여 있기 때문에 GrantedAuthority 뿐만 아니라 UserDetails 등도 다 함께 연결되어 있음
- 사용자는 하나 이상의 권한을 가질 수 있으며 UserDetailsService를 통해 사용자에 대한 정보를 취득할 수 있음
- UserDetails는 하나 이상의 GrantedAuthority를 가질 수 있음
3. 엔드 포인트 접근 제한
- 스프링 시큐리티에서 제공하는 다음 메서드를 활용하면 사용자마다 특정 엔드 포인트에 접근을 제한할 수 있음
- hasAuthority()
- hasAnyAuthority()
- access()
3.1 hasAuthority()
- 제한을 구성하는 하나의 권한을 파라미터로 전달받고 해당 권한이 있는 사용자는 엔드포인트로 접근할 수 있음
3.2 hasAnyAuthority()
- 제한을 구성하는 하나 이상의 권한을 파라미터로 전달받을 수 있으며 이 중 하나라도 있을 때 허용
3.3 Spring Security 5 버전, SpringBoot 2.X 버전의 access().*
- 정규 표현식처럼 스프링에서도 SpEL 표현식을 제공하며 이를 활용해서 권한 부여 규칙을 정의
- 자율성을 극대화하는 장점도 존재하지만 가독성이 떨어지고 디버깅이 어려운 단점이 존재
3.4 Spring Security 6 버전, SpringBoot 3.X 버전의 access().*
- 커스텀 AuthorizationManager를 만들어 활용
3.5 denyAll
- denyAll 활용 시 모든 요청을 기본적으로 거부하며 특정 요청만 허용하고 싶을 때 활용 가능
부연 설명
- 커스텀 AuthorizationManager를 만들어 READ 권한이 있는 계정에 대해서는 403 Forbidden을 반환하도록 SecurityConfig를 설정했으므로 READ 권한이 있는 jaimemin 계정으로 로그인 시도 시 403 Forbidden 반환
4. RequestMatchers
- 특정한 요청 그룹에 권한 부여 제약 조건을 적용하기 위해 Matcher 활용 가능
- Spring Security 5 버전까지는 mvcMatcher, antMatcher, regexMatcher를 활용했지만
- Spring Security 6 버전부터는 기본적으로 requestMatcher를 활용
- Spring Security 6에서 RequestMatchers는 요청 URL, HTTP 메서드, 헤더 등 다양한 요청 조건에 따라 보안 정책을 세밀하게 설정할 수 있는 기능을 제공
- 이전 버전에서 사용되던 antMatchers(), mvcMatchers()와 같은 메서드가 사라지고, 더 유연하고 통일된 방식으로 보안 규칙을 정의할 수 있도록 requestMatchers()가 도입
- 단순히 URL 패턴뿐만 아니라 HTTP 메서드, 헤더, 매개변수 등을 기준으로 요청을 구분할 수 있음
- requestMatchers() 메서드는 요청 매칭을 처리하는 데 사용되며 authorizeHttpRequests()와 함께 사용하여 특정 요청에 대해 인가 규칙을 설정 가능
비고
1. 역할(ROLE) vs 권한(Authority)
1.1 역할
- 사용자의 직책이나 기능에 따른 권한의 집합
- 여러 권한을 그룹화하여 역할로 정의하고 이를 사용해 보다 간단하게 인가 처리 가능
- 스프링 시큐리티에서는 역할을 항상 `ROLE_`이라는 prefix와 함께 사용
- ex) hasRole("ADMIN"과 같은 방식으로 사용자의 역할을 검사할 경우 Spring Security는 내부적으로 `ROLE_ADMIN`이라는 권한을 찾아 검사
- 역할은 다수의 권한을 묶어서 처리하거나 사용자 그룹별로 리소스에 대한 접근을 관리하는 데 사용
1.2 권한
- 특정 작업을 수행할 수 있는 능력을 나타내며 사용자가 시스템 내에서 어떤 행동을 수행할 수 있는지에 대한 세밀한 권한을 정의하는 개념
- 권한은 특정 리소스에 대한 구체적인 접근 권한을 부여하는 데 사용됨
- 권한은 문자열로 표현되며 특정 작업이나 리소스에 대한 접근 권한을 나타냄
- ex) `READ`, `WRITE`, `DELETE`와 같은 권한이 있음
- 단, 권한에는 `ROLE_` 접두어가 붙지 않으며, 이를 통해 역할과 구분됨
참고
https://fastcampus.co.kr/classroom/240071
반응형
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security] CSRF & CORS (0) | 2024.10.08 |
---|---|
[Spring Security] 필터 체인과 커스텀 필터 (0) | 2024.10.08 |
[Spring Security] 아키텍처 간단 정리 (0) | 2024.09.13 |
[Spring Security] OAuth 2.0 개요 (0) | 2023.12.21 |
[Spring Security] Remember-me를 통해 로그인 유지하기 (0) | 2022.03.27 |