[Spring Security] 권한 부여 처리 흐름 및 구성 요소

정윤호·2023년 3월 18일
0

Spring Security의 권한 부여 처리 흐름

<Spring Security 권한 부여(Authorization) 흐름도(출처 : 코드스테이츠)>


✋ Authorization관련 안내
위 Spring Security 권한 부여(Authorization) 흐름은 UsernamePasswordAuthenticationFilter를 통해 SecurityContextHolder의 SecurityContext에 저장된 Authentication을 획득하여 Authorization 처리절차를 진행함.

  1. AuthorizationFilter는 SecurityContextHolder로부터 Authentication을 획득

  2. 획득한 Authentication과 HttpServletRequest를 AuthorizationManager에게 전달

    • HttpServletRequest : 클라이언트 쪽에서 넘어오는 요청에 대한 모든 정보(Request header, RequestBody)가 포함되어 있는 컴포넌트
    • AuthorizationManager : 권한 부여(Authorization) 처리를 총괄하는 매니저 역할을 하는 인터페이스
    • RequestMatcherDelegatingAuthorizationManager : AuthorizationManager를 구현한 구현체 중 하나
  3. RequestMatcherDelegatingAuthorizationManager는 RequestMatcher 평가식을 기반으로 평가식에 매치되는 가장 적합한 AuthorizationManager 구현 클래스에게 위임하여 적절한 권한을 가지고 있는지 검증

    • AuthorizationManager 구현 클래스 : AuthorizationManager 구현 클래스의 구성을 통해 권한 부여 결정이 투표되어 짐.

    <AuthorizationManager 구현체 목록(출처 : spring.io)>


  1. 적절한 권한이라면 클라이언트가 요청한 다음 프로세스를 진행
  2. 적절한 권한이 아니라면 AccessDeniedException이 throw되고 ExceptionTranslationFilter가 처리

Spring Security의 권한 부여 컴포넌트

  • AuthorizationFilter : Spring Security Filter Chain 중 AuthorizationFilter는 URL을 통해 사용자의 액세스를 제한하거나 허용하는 권한 부여 Filter(SpringSecurity 5.5버전부터 FilterSecurityInterceptor를 대체)
  • AuthorizationManager : 권한 부여 처리를 총괄하는 매니저 역할을 하는 인터페이스
  • RequestMatcherDelegatingAuthorizationManager : AuthorizationManager의 구현 클래스 중 하나, 직접 권한 부여 처리를 수행하지 않고, RequestMatcher를 통해 매치되는 Authorization 구현 클래스에게 권한 부여 처리를 위임함

접근 제어 표현식

  • Spring Security에서는 웹 및 메서드 보안을 위해 표현식(Spring Expression Language, SpEL)을 사용할 수 있으며, 다음과 같은 표현식을 지원함.
  • SpEL은 @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter, @Secured, @RolesAllowed 등의 애네테이션에서 사용( 예. @PreAuthorize(”hasRole(’admin’)”)
    • @PreAuthorize : 메소드가 호출되기 전에 SpEL 표현식을 사용하여 권한을 검사. 이때, SpEL은 루트 객체를 사용하여 표현식을 평가

    • @PostAuthorize : 메소드가 호출된 후에 SpEL 표현식을 사용하여 권한을 검사. 이때, SpEL은 루트 객체를 사용하여 표현식을 평가

    • @PreFilter : 메소드가 호출되기 전에 컬렉션에 대한 필터링을 수행. 이때, SpEL을 사용하여 필터링 조건을 지정할 수 있음.

    • @PostFilter : 메소드가 호출된 후에 컬렉션에 대한 필터링을 수행. 이때, SpEL을 사용하여 필터링 조건을 지정할 수 있음.

    • @Secured : 메소드에 대한 보안 권한을 지정. 이때, 권한은 문자열 배열로 지정할 수 있음.

    • @RolesAllowed : 메소드에 대한 보안 권한을 지정. 이때, 권한은 문자열 배열로 지정할 수 있음.

      @Secured vs @RolesAllowed
      두 애너테이션 모두 메소드에 대한 보안 권한을 지정하는데 사용하지만, @Secured는 Spring Security에서 지원하는 애너테이션이며, @RolesAllowed는 JSR-250에서 지원하는 애너테이션임. 따라서 @Secured는 Spring Security에서만 사용가능한 애너테이션

표현식설명
hasRole(String Role)- 현재 보안 주체(Principal)가 지정된 역할을 가지고 있는지 여부를 확인하고 가지고 있다면 true를 리턴
- hasRole(’admin’)처럼 파라미터로 넘긴 role이 ‘ROLE_’로 시작하지 않으면 기본적으로 추가함(DefaultWebSecurityExpressionHandler의 defaultRolePrefix를 수정하면 커스텀할 수 있다.)
hasAnyRole(String… roles)- 현재 보안 주체가 지정한 역할 중 1개라도 가지고 있으면 true를 리턴한다.(문자열 리스트를 콤마로 구분해서 전달한다.)- ex) hasAnyRole(’admin’, ‘user’)
hasAuthority(String authority)- 현재 보안 주체가 지정한 권한을 갖고 있는지 여부를 확인하고 가지고 있다면 true를 리턴한다.- ex) hasAuthority(’read’)
hasAnyAuthority(String… authorities)- 현재 보안 주체가 지정한 권한 중 하나라도 있으면 true를 리턴한다.- ex) hasAnyAuthority(’read’, ‘write’)
principal- 현재 사용자를 나타내는 principal 객체에 직접 접근할 수 있다.
authentication- SecurityContext로 조회할 수 있는 현재 Authentication 객체에 직접 접근할 수 있다.
permitAll- 항상 true로 평가한다.
denyAll- 항상 false로 평가한다.
isAnonymous()- 현재 보안 주체가 익명 사용자면 true를 리턴한다.
isRememberMe()- 현재 보안 주체가 remember-me 사용자면 true를 리턴한다.
isAuthenticated()- 사용자가 익명이 아닌 경우 true를 리턴한다.
isFullyAuthenticated()- 사용자가 익명 사용자나 remember-me 사용자가 아니면 true를 리턴한다.
hasPermission(Object target, Object permission)- 사용자가 target에 해당 permission 권한이 있으면 true를 리턴한다.ex) hasPermission(domainObject, ‘read’)
hasPermission(Object targetId, String targetType, Object permission)- 사용자가 target에 해당 permission 권한이 있으면 true를 리턴한다.ex) hasPermission(1, ‘com.example.domain.Message’, ‘read’)
profile
오늘 하루도 최선을 다하자!!

0개의 댓글