Spring/Spring Security

[Spring Security] 액세스 제한과 권한

꾸준함. 2024. 10. 7. 14:48

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 응답 반환

 

https://medium.com/@greekykhs/springsecurity-part-3-spring-security-flow-7da9cc3624ab

 

2. GrantedAuthority

  • GrantedAuthority를 활용하여 권한 부여 기능 적용 가능
    • 적용 시 사용자마다 다른 권한을 가지게 되며 권한에 따라 특정 작업만 수행할 수 있음

 

  • 사용자, 권한, 기능은 서로 엮여 있기 때문에 GrantedAuthority 뿐만 아니라 UserDetails 등도 다 함께 연결되어 있음
  • 사용자는 하나 이상의 권한을 가질 수 있으며 UserDetailsService를 통해 사용자에 대한 정보를 취득할 수 있음
    • UserDetails는 하나 이상의 GrantedAuthority를 가질 수 있음

 

https://livebook.manning.com/concept/spring/userdetails-contract

 

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

 

반응형