지난 포스팅에서 사용자가 누구인지, 인증 처리 하는 방법을 알아보았다.

사용자가 인증되었다면 이제 유저에 대한 권한을 확인하고 접근을 허가하는 인가 처리에 대해 알아보자.

 

 

출처: http://cjw-awdsd.tistory.com

 

각 컴포넌트를 설명하기 전에, 대략적인 구조는 위 그림과 같다.

 

SecurityInterceptor 는 Invocation 을 생성하여

ConfigAttribute 에 담아 AccessDecisionManager 에게 인가 처리를 위임한다.

 

DecisionManager 들은 해당 ConfigAttribute 를 가지고 DecisionVoter 들에게 이 조건을 처리해줄 수 있는지 질문한다.

답은 Voter 내의 supprots() 메서드에서 리턴받을 수 있으며, 처리가 가능하다면 vote() 메서드에서 승인 여부를 반환한다.

 

 

이제 각 컴포넌트들에 대해서 자세히 알아보자.

 

 

인가(Authorization) 처리 핵심 컴포넌트

 

AccessDecisionManager

 

인증 된 사용자의 보호 리소스 접근 여부를 판단한다.

여러 개의 Voter 를 가지고 허용 여부를 결정하며 구현체 3가지를 제공한다.

 

  • AffirmativeBased - 접근을 승인하는 voter가 1개 이상 (주로 사용)
  • ConsensusBased - 다수결
  • UnanimousBased - 만장일치

 

public interface AccessDecisionManager {

   // 여기서 인가처리 구현
   void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
         throws AccessDeniedException, InsufficientAuthenticationException;

   boolean supports(ConfigAttribute attribute);

   boolean supports(Class<?> clazz);

}

 

 

 

AccessDecisionVoter

 

AccessDecisionManager 는 다수의 AccessDecisionVoter 로 구성된다.

각각의 Voter 는 주어진 정보를 기반으로 승인(ACCESS_GRANTED), 거절(ACCESS_DENIED), 보류(ACCESS_ABSTAIN) 를 반환한다.

 

public interface AccessDecisionVoter<S> {
    int ACCESS_GRANTED = 1;
    int ACCESS_ABSTAIN = 0;
    int ACCESS_DENIED = -1;

    boolean supports(ConfigAttribute var1);

    boolean supports(Class<?> var1);

    int vote(Authentication var1, S var2, Collection<ConfigAttribute> var3);
}

 

Security 설정 파일에서 아래와 같이 커스텀 voter 를 추가할 수도 있다.

 

    @Bean
    public AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
        // WebExpressionVoter: 시큐리티에서 사용하는 기본 구현체로 hasRole(ROLE_XXXX) 판단
        decisionVoters.add(new WebExpressionVoter());
        // voter 목록에 내가 만든 커스텀 voter(connectionBasedVoter) 를 추가함
        decisionVoters.add(connectionBasedVoter());
        // UnanimousBased: 모든 voter 가 승인해야함
        return new UnanimousBased(decisionVoters);
    }

 

 

 

 

참고

 

https://catchdream.tistory.com/198

https://escapefromcoding.tistory.com/490

복사했습니다!