
GrantedAuthority 객체는 AuthenticationManager에 의해 인증 개체에 Authentication 객체에 삽입되고 나중에 권한 부여 결정을 내릴 때 AccessDecisionManager 인스턴스에서 읽혀진다.
GrantedAuthority 인터페이스는 하나의 메서드만을 갖는다.
String getAuthority();
위 메서드는 AuthorizationManager 인스턴스에서 GrantedAuthority의 정확한 String 표현을 얻는 데 사용된다. String으로 반환하면 대부분의 AuthorizationManager 구현체에서 GrantAuthority를 쉽게 읽을 수 있다. 만약 String으로 정확하게 표현할 수 없는 경우 getAuthority() 메서드는 null을 반환해야 한다.
기본적으로 role-based 권한 부여 규칙에는 ROLE_이 접두사로 포함된다. 이는 "USER" 권한을 요청하는 security context가 있을 경우 기본적으로 "ROLE_USER"를 반환하는 GrantedAuthority#getAuthority를 찾아서 사용한다는 것을 의미한다.
만약 앞에 붙는 ROLE_을 커스텀하게 변경하고 싶다면 GrantedAuthorityDefaults를 사용하면 된다.
@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("MYPREFIX_");
}
Spring Security의 설정 파일은
@Configuration어노테이션으로 인해 Spring Bean으로 관리된다. Spring이 클래스를 초기화하고 관리하기 전에GrantedAuthorityDefaults가 먼저 존재해야 하기 때문에 static 메서드를 사용한다.
Spring Security는 메서드 호출이나 웹 요청과 같은 객체에 대한 접근을 제어하는 인터셉터를 제공한다. 객체에 접근이 허용되는지, 값 반환이 허용되는지 여부는 AuthorizationManager 인스턴스에 의해 이루어진다.
AuthorizationManager는 AccessDecisionManager와 AccessDecisionVoter를 대체하기 때문에 이 두 인터페이스는 AuthorizationManager로 변경하는 편이 좋다.
AuthorizationManager는 Spring Security의 request-based, method-based, message-based 인증 요소들에 의해 호출되며 접근 결정을 내리는 역할을 한다. 이 인터페이스는 두 가지 메서드를 포함한다.
AuthorizationDecision check(Supplier<Authentication> authentication, Object secureObject);
default AuthorizationDecision verify(Supplier<Authentication> authentication, Object secureObject)
throws AccessDeniedException {
// ...
}
위의 check() 메서드에는 인증에 대한 결정을 내리는데 필요한 모든 정보가 전달된다. 특히 보안 Object는 실제 보안 객체 호출에 포함된 argument를 검사할 수 있다. 구현체에서는 접근이 허용된 경우 긍정적인 AuthorizationDecision을 반환하고 접근이 거부된 경우 부정적인 AuthorizationDecision을 반환하며 결정을 내리지 않는 경우 null을 반환할 것이다.
호출을 확인하고 부정적인 AuthorizationDecision인 경우 AccessDeniedException을 반환한다.
사용자는 인증의 모든 측면을 제어하기 위한 자신만의 AuthorizationManager를 작성할 수 있다.
또한 Spring Security는 기본 AuthorizationManager와 협력하여 동작하는 AuthorizationManager를 작성할 수 있게 제공한다.
RequestMatcherDelegatingAuthorizationManager는 요청을 적절한 위임 AuthorizationManager와 일치시킨다. 메서드 보안을 위해 AuthorizationManagerBeforeMethodInterceptor 및 AuthorizationManagerAfterMethodInterceptor를 사용할 수 있다.

가장 일반적인 위임 AuthorizationManager이다.
인증에 구성된 권한이 포함되어 있으면 긍정적인 AuthorizationDecision을 반환한다. 그렇지 않으면 부정적인 AuthorizationDecision을 반환한다.
익명 사용자, 완전히 인증된 사용자, remember-me로 인증한 사용자를 구별할 수 있다.
많은 사이트에서 Remember-Me 인증을 한 사용자에게 특정 리소스에 대해서 접근을 허용하지만 전체 엑세스를 위해서는 로그인하도록 한다.
AuthorizationManager들 중에는 AuthorizationManager를 보다 정교한 표현식으로 구성하는 데 도움을 주는 정적 팩토리도 있다.
사용자가 정의한 AuthorizationManager를 구현할 수 도 있으며 원하는 접근 제어 논리를 추가할 수 있다.
AuthorizationManager 이전에는 및 AccessDecisionManager를 사용했다.AccessDecisionVoter
애플리케이션의 어떠한 Role이 다른 Role을 '포함' 해야 하는 것은 일반적인 요구 사항이다. 예를 들면 '관리자는 일반 사용자가 할 수 있는 모든 작업을 수행할 수 있게 해야한다.' 라는 요구사항이 있다면 관리자는 사용자의 Role도 가져야 한다.
Role Hierarchy를 사용하면 어떤 Role(혹은 권한)이 다른 Role을 포함하도록 구성할 수 있다.
RoleHierarchyVoter는 RoleHierarchy로 구성되어 Role의 계층구조를 지정할 수 있다.
@Bean
static RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF\n" +
"ROLE_STAFF > ROLE_USER\n" +
"ROLE_USER > ROLE_GUEST");
return hierarchy;
}
// 메서드 기반 인증을 적용하고 싶으면 다음 메서드도 작성
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy);
return expressionHandler;
}
위 코드에서 권한의 계층 구조는 다음과 같다.
ROLE_ADMIN>ROLE_STAFF>ROLE_USER>ROLE_GUEST
여기에서>기호는 포함을 의미한다고 생각하면 된다.