@@ -12,19 +12,22 @@
 import nextstep.security.authorization.access.MvcRequestMatcher;
 import nextstep.security.authorization.access.RequestMatcherEntry;
 import nextstep.security.authorization.manager.AuthenticatedAuthorizationManager;
+import nextstep.security.authorization.manager.AuthorizationManager;
 import nextstep.security.authorization.manager.DenyAllAuthorizationManager;
 import nextstep.security.authorization.manager.HasAuthorityAuthorizationManager;
-import nextstep.security.authorization.manager.AuthorizationManager;
 import nextstep.security.authorization.manager.PermitAllAuthorizationManager;
 import nextstep.security.authorization.manager.RequestMatcherDelegatingAuthorizationManager;
 import nextstep.security.authorization.manager.SecuredAuthorizationManager;
+import nextstep.security.authorization.role.RoleHierarchy;
+import nextstep.security.authorization.role.RoleHierarchyImpl;
 import nextstep.security.config.DefaultSecurityFilterChain;
 import nextstep.security.config.DelegatingFilterProxy;
 import nextstep.security.config.FilterChainProxy;
 import nextstep.security.config.SecurityFilterChain;
 import nextstep.security.context.SecurityContextHolderFilter;
 import nextstep.security.userdetails.UserDetails;
 import nextstep.security.userdetails.UserDetailsService;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.EnableAspectJAutoProxy;
@@ -34,8 +37,8 @@
 import java.util.List;
 import java.util.Set;
 
-@EnableAspectJAutoProxy
 @Configuration
+@EnableAspectJAutoProxy
 public class SecurityConfig {
 
     private final MemberRepository memberRepository;
@@ -45,8 +48,8 @@ public SecurityConfig(MemberRepository memberRepository) {
     }
 
     @Bean
-    public DelegatingFilterProxy delegatingFilterProxy() {
-        return new DelegatingFilterProxy(filterChainProxy(List.of(securityFilterChain())));
+    public DelegatingFilterProxy delegatingFilterProxy(RequestMatcherDelegatingAuthorizationManager requestAuthorizationManager) {
+        return new DelegatingFilterProxy(filterChainProxy(List.of(securityFilterChain(requestAuthorizationManager))));
     }
 
     @Bean
@@ -55,13 +58,13 @@ public FilterChainProxy filterChainProxy(List<SecurityFilterChain> securityFilte
     }
 
     @Bean
-    public SecurityFilterChain securityFilterChain() {
+    public SecurityFilterChain securityFilterChain(RequestMatcherDelegatingAuthorizationManager requestAuthorizationManager) {
         return new DefaultSecurityFilterChain(
                 List.of(
                         new SecurityContextHolderFilter(),
                         new UsernamePasswordAuthenticationFilter(userDetailsService()),
                         new BasicAuthenticationFilter(userDetailsService()),
-                        new AuthorizationFilter(requestAuthorizationManager())
+                        new AuthorizationFilter(requestAuthorizationManager)
                 )
         );
     }
@@ -92,13 +95,7 @@ public Set<String> getAuthorities() {
     }
 
     @Bean
-    public SecuredMethodInterceptor securedMethodInterceptor() {
-        return new SecuredMethodInterceptor(
-                new SecuredAuthorizationManager()
-        );
-    }
-
-    @Bean
+    @ConditionalOnMissingBean(RequestMatcherDelegatingAuthorizationManager.class)
     public RequestMatcherDelegatingAuthorizationManager requestAuthorizationManager() {
         List<RequestMatcherEntry<AuthorizationManager<HttpServletRequest>>> mappings = new ArrayList<>();
 
@@ -108,17 +105,34 @@ public RequestMatcherDelegatingAuthorizationManager requestAuthorizationManager(
         );
         mappings.add(new RequestMatcherEntry<>(
                 new MvcRequestMatcher(HttpMethod.GET, "/members"),
-                new HasAuthorityAuthorizationManager<>("ADMIN"))
+                new HasAuthorityAuthorizationManager<>(roleHierarchy(), "ADMIN"))
         );
         mappings.add(new RequestMatcherEntry<>(
                 new MvcRequestMatcher(HttpMethod.GET, "/search"),
                 new PermitAllAuthorizationManager<>())
         );
+
         mappings.add(new RequestMatcherEntry<>(
                 new AnyRequestMatcher(),
                 new DenyAllAuthorizationManager<>())
         );
 
         return new RequestMatcherDelegatingAuthorizationManager(mappings);
     }
+
+    @Bean
+    @ConditionalOnMissingBean(RoleHierarchy.class)
+    public RoleHierarchy roleHierarchy() {
+        return RoleHierarchyImpl.with()
+                .role("ADMIN").implies("USER")
+                .build();
+    }
+
+    @Bean
+    public SecuredMethodInterceptor securedMethodInterceptor(RoleHierarchy roleHierarchy) {
+        return new SecuredMethodInterceptor(
+                new SecuredAuthorizationManager(roleHierarchy)
+        );
+    }
+
 }

리뷰: 테스트와 분리되니 코드가 명확하네요 👍