Spring Security (3) - Authorization 1

spaghetti·2024년 8월 19일

Spring Security

목록 보기
4/7

인증(login)이 완료되면 인가처리(permission)가 시작된다. 인가에서 알아볼 키워드는 아래와 같다

  • AuthorizationManager
  • Hierarchical Roles
  • AuthorizationFilter

Authorization Architecture

이전에 Authentication 객체에 대해서 설명했는데, 다시 한번 살펴보자.

해당 객체에서 Authorities가 존재하는데 이는 GrantedAutority 라는 인터페이스의 목록이다. 이 객체는 AuthorizationManager 에 의해 삽입되고, 나중에 권한 부여 결정을 내릴때 사용된다.
GrantedAutority에서는 문자열을 반환하는 getAuthority() 메서드만 존재하는데, AuthorizationManager에서 사용된다.
스프링 시큐리티는 기본적으로 SimpleGrantedAuthority 구현체를 사용한다. 기본적으로 롤 기반 권한의 경우 ROLE_ 이라는 접두사를 붙이는데 권한에 관한 특별한 커스텀을 거치지 않는 한 디버깅해보면 ROLE_접두사가 붙어있는 것을 볼 수 있다.

시큐리티는 클라이언트에서 http 요청시에 가로챈다음 인가처리를 해야하는지 확인한다. 이러한 확인은 AuthorizationManager에서 이루어진다.

AuthorizationManager

AuthorizationManager는 인터페이스로 여러 구현체들이 존재한다.

많은 구현체들이 존재하지만 가장 널리 쓰이는 것은 AuthorityAuthorizationManager 클래스다. 직접 클래스를 들여다보면 AuthorizationManager의 check 메서드를 오버라이드해서 권한이 있는지 확인하고 AuthorizationDecision 객체를 반환하는데 이때 boolean값인 granted를 담는다

기본적으로 사용되는 구현체말고도 내가 커스텀하여 구현체를 만들어 줄 수 있다. 보통 동적으로 권한을 구현해야할때(url 기반으로 권한을 제어하는경우) 커스텀하여 구현하게 된다.
구현 예제를 찾아보면 AccessDecisionManagerAccessDecisionVoters 사용하는 예제들을 많이 접할 수 있는데, 최근 시큐리티에서는 이 클래스들은 AuthorizationManager 로 모두 대체되었다. 처음에 나도 적용해보려다가 최근 시큐리티와 맞지 않는 코드인 것 같아서 꽤 오랜 시간을 허비했는데, 후에 어떤식으로 적용했는지 서술하겠다. (역시 공식문서를 잘 읽어야한다..)

Hirerchical Roles

흔히 역할을 설정할때 우리는 "관리자"와 "사용자" 역할의 개념을 사용하는데, 보통은 "관리자" 역할은 "사용자"가 할 수 있는 모든 것을 할 수 있어야한다는 것을 당연하게 여길 것이다. "관리자" 역할을 더 우위에 생각하고 있기 때문인데, 만약 역할들이 늘어난다면 관리자 역할에 사용자 역할을 계속 넣어주는 것보다 자동으로 포함시킬 수 있다면 훨씬 효율적일 것이다. 스프링 시큐리티에서는 이러한 기능을 지원하고 있다.
밑은 스프링 시큐리티 공식문서에서 적혀있는 예시로, 간단하게 적용하고자 한다면 RoleHierarchyImpl.withDefaultRolePrefix() 메서드를 이용해서 위계를 설정해줄 수 있다. (이 메서드는 최신버전에서만 사용가능한 듯하다. 버전 확인 필요)

//roleHierarchy 설정
@Bean
static RoleHierarchy roleHierarchy() {
    return RoleHierarchyImpl.withDefaultRolePrefix()
        .role("ADMIN").implies("STAFF")
        .role("STAFF").implies("USER")
        .role("USER").implies("GUEST")
        .build();
}

// 메서드 기반 인증을 사용한다면 해당 빈에서 객체 주입
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
	DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
	expressionHandler.setRoleHierarchy(roleHierarchy);
	return expressionHandler;
}
profile
개발 그렇게 하는거 아닌데의 그렇게를 맡고있습니다

0개의 댓글