Spring security/01.Security

04. Servlet Authorization Architecture

  • -

이번 포스트에서는 Authorization Architecture에 대해 살펴보자.

 

Authorization Architecture

 

권한(Authorization)

사용자가 인증되면 Authorization 객체가 생성된다. 이 객체는 사용자가 가진 권한을 나타내는 GrantedAuthority 목록을 포함한다.  GrantedAuthority사용자(Principal)가 특정 작업을 수행할 수 있는지를 반환하는 역할을 한다.

GrantedAuthority 인터페이스의 getAuthority()는 권한을 문자열로 반환한다. 기본적으로 role 기반의 권한 부여 규칙에서는 접두사로 "ROLE_"를 붙인다. 따라서 getAuthority()는 "ROLE_USER", "ROLE_ADMIN" 등의 형태로 권한을 반환한다.

String getAuthority();

이 메서드는 AuthorizationManager에 의해 호출된다.

Role, Authority(=Privilege)가 정확히는 다르지만 Spring Security에서는 거의 유사하게 사용되고 있다. Authority 즉 권한은 개별적인 단위로 '쓰기 권한', '읽기 권한'등으로 표현된다. 반면 Role은 권한의 집합으로 "Manager role은 읽기 권한, '쓰기 권한'을 갖는다" 형태로 사용된다. Spring Security에서는 Authority가 일반적으로 ROLE로 간주된다.
그래서 getAuthority()를 호출하면 ROLE_를 붙여서 반환하고 hasRole("ADMIN")을 호출하면서는 ROLE_를 생략한다.
// 권한 확인
@PreAuthorize("hasRole('ADMIN')") // 내부적으로 "ROLE_ADMIN"과 비교@PreAuthorize("hasAuthority('ROLE_ADMIN')") // 직접 "ROLE_ADMIN" 지정

 

AuthorizationManager

Spring Security는 메서드 호출이나 웹 요청과 같은 보안 객체에 대한 요청을 가로챈다. 호출을 진행할 수 있는지 여부에 대한 호출 전 결정(@PreAuthorize)은 AuthorizationManager 인스턴스에 의해 이루어진다. 또한 주어진 값을 반환할 수 있는지에 대한 호출 후 결정(@PostAuthorize)도 AuthorizationManager 인스턴스가 내린다.

기존에는 AccessDecisionManager나 AccessDecisionVoters같은 객체가 처리했던 일을 하나가 처리하게 되니 훨씬 깔끔해진 느낌이다.

 

계층적 role(hierachical Roles)

Role을 설계하다보면 특정 role이 다른 role을 자동으로 포함해야 하는 경우가 많이 발생한다. 예를 들어 "admin" role을 가진 사용자가 "user" role이 할수 있는 일을 다 해야하는 경우가 있다.

기존에는 이를 처리하기 위해 모든 admin에게 user 역할을 추가로 부여하거나 'user' 역할이 필요한 부분에 'admin' 역할까지 체크하도록 처리했다.

이런 경우 계층적 role관리를 적용할 수 있다. 다음의 코드에서 ADMIN은 STAFF을, STAFF는 USER를, USER는 GUEST를 포함한다.

@Bean
static RoleHierarchy roleHierarchy() {
    return RoleHierarchyImpl.withDefaultRolePrefix()
        .role("ADMIN").implies("STAFF")
        .role("STAFF").implies("USER")
        .role("USER").implies("GUEST")
        .build();
}
/*
@Bean
static RoleHierarchy roleHierarchy() {
    return RoleHierarchyImpl.fromHierarchy("""
        ROLE_ADMIN > ROLE_STAFF
        ROLE_STAFF > ROLE_USER
        ROLE_USER > ROLE_GUEST
        """);
}
*/

계층적 role 관리를 위해 RoleHierarchy를 등록할 때는 static 빈으로 등록하기를 권한다. 이유는 RoleHierarchy는 다른 빈들에 의존하지 않고 독립적으로 정의될 수 있으며 보안 설정의 기초되는 컴포넌트로 가능한 빨리 초기화 되는 것이 좋기 때문이다.

static @Bean 메서드는 다른 빈을 주입 받을 수 없다.(단 메서드 파라미터로는 가능) 따라서 빈이 다른 빈에 의존적이라면 static으로 선언하면 안된다.

'Spring security > 01.Security' 카테고리의 다른 글

06. 사용자 및 경로 관리  (0) 2022.11.18
05. 프로젝트 구성과 초기 동작  (0) 2020.08.20
03. Servlet Authentication Architecture  (0) 2020.07.15
02. SecurityFilterChain  (0) 2020.06.02
01. Security 개요  (0) 2020.06.02
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.