[spring] Spring Security Authorization

Nakjoo·2023년 3월 17일
0

[SEB_BE_43]

목록 보기
28/29

사용자 인증에 성공했다고 모든 리소스에 마음대로 접근할 수 있는 것은 아니다. 리소스마다 어떤 권한이 부여되어야만 해당 리소스에 접근할 수 있는 것이다.

Spring Security의 권한 부여 처리 흐름

  • 사용자의 액세스를 제한하는 권한 부여 Filter가 AuthorizationFilter이다.
  • AuthorizationFilterSecurityContextHolder로 부터 Authentication을 획득한다.
  • 그리고 HttpServletRequest를 획득한 Authentication과 함께 AuthorizationManager에 전달한다.
  • AuthorizationManager의 구현체 중 하나인 RequestMatcherDelegatingAuthorizationManager 내부에서 매치되는 AuthorizationManager 구현 클래스가 있다면 해당 AuthorizationManager 구현 클래스가 사용자의 권한을 체크한다.
  • 적절한 권한이면 다음 요청 프로세스를 계속 이어간다.
  • 적절한 권한이 아니라면 AccessDeniedException이 throw되고 ExceptionTranslationFilterAccessDeniedException을 처리하게 된다.

Spring Security의 권한 부여 컴포넌트

✅ AuthorizationFilter

AuthorizationFilter는 URL을 통해 사용자의 액세스를 제한하는 권한 부여 Filter이며, Spring Security 5.5 버전부터 FilterSecurityInterceptor를 대체한다.

AuthorizationFilter 객체가 생성될 때, AuthorizationManager를 DI 받고, DI 받은 AuthorizationManager를 통해 권한 부여 처리를 진행한다.

URL 기반으로 권한 부여 처리를 하는 AuthorizationFilterAuthorizationManager의 구현 클래스로 RequestMatcherDelegatingAuthorizationManager를 사용한다.

✅ AuthorizationManager

이름 그대로 권한 부여 처리를 총괄하는 매니저 역할을 하는 인터페이스이다.

AuthorizationManager 인터페이스는 check() 메서드 하나만 정의되어 있으며, Supplier와 제너릭 타입의 객체를 파라미터로 가진다.

✅ RequestMatcherDelegatingAuthorizationManager

AuthorizationManager의 구현 클래스 중 하나이며, 권한 부여 처리를 직접 수행하지 않고 RequestMatcher를 통해 매치되는 AuthorizationManager 구현 클래스에게 권한 부여 처리를 위임한다.

RequestMatcherSecurityConfiguration에서 .antMatchers("/orders/\**").hasRole("ADMIN") 와 같은 메서드 체인 정보를 기반으로 생성된다.

접근 제어 표현식

표현식설명
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) hasAnyAuthority('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 targerId, String targetType, Object permission)- 사용자가 targer에 해당 permission 권한이 있으면 true를 리턴한다.
ex) hasPermission(1, 'com.example.domain.Message', 'read')

0개의 댓글