스터디-Spring

[스프링 시큐리티] AccessDecisionManager

일태우 2022. 1. 13. 19:41
public interface AccessDecisionManager {
    void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException;

    boolean supports(ConfigAttribute attribute);

    boolean supports(Class<?> clazz);
}

Authorization(인가)를 위한, Access Control 결정을 내리는 인터페이스, 구현체 3가지를 기본으로 제공한다.

  • AffirmativeBased: 여러 Voter중에 한명이라도 허용하면 허용, 기본 전략.
  • ConsensusBased: 다수결
  • UnanimousBased: 만장일치

AccessDecisionVoter

  • 해당 Authentication이 특정한 Object에 접근할때 필요한 ConfigAttributes를 만족하는지 확인한다.
  • WebExpressionVoter: 웹 시큐리티에서 사용하는 기본 구현체, ROLE_XXXX가 매치하는지 확인
  • RoleHierarchyVoter: 계층형 ROLE 지원. admin -> manager -> user 

ConfigAttributes

WebSecurityConfigurerAdapter 구현 클래스에서 설정한 정보들

.mvcMatchers("/", "/info", "/account/**").permitAll()
.mvcMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()

 

계층 ROLE 설정

1. AccessDecisionManager 커스터마이징

public AccessDecisionManager accessDecisionManager() {
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");

    DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
    handler.setRoleHierarchy(roleHierarchy);

    WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
    webExpressionVoter.setExpressionHandler(handler);
    List<AccessDecisionVoter<? extends Object>> voters = Arrays.asList(webExpressionVoter);

    return new AffirmativeBased(voters);
}

 

2. ExpressionHandler 커스터마이징(AccessDecisionManager의 voter의 handler만 커스터마이징)

    public SecurityExpressionHandler expressionHandler() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");

        DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
        handler.setRoleHierarchy(roleHierarchy);
        return handler;
    }