본문 바로가기

Language/Spring Security

AOP 메서드 보안 구현 - MethodInterceptor, Pointcut, Advisor

728x90
  • MethodInterceptor, Pointcut, Advisor, AuthorizationManager 등을 커스텀하게 생성하여 AOP 메서드 보안을 구현 가능

AOP 요소 이해

  • Advisor
    • AOP Advice와 Advice 적용 가능성을 결정하는 포인트컷을 가진 기본 인터페이스
  • MethodInterceptor(Advice)
    • 대상 객체를 호출하기 전과 후에 추가 작업을 수행하기 위한 인터페이스로서 수행 이후 **실제 대상 객체의 조인포인트 호출(메서드 호출)**을 위해 Joinpoint.proceed()를 호출
  • Pointcut
    • AOP 에서 Advice 가 적용될 메소드나 클래스를 정의하는 것으로서 어드바이스가 실행되어야 하는 '적용 지점'이나 '조건' 지정
    • ClassFilter 와 MethodMatcher를 사용해서 어떤 클래스 및 어떤 메서드에 Advice를 적용할 것인지 결정

AOP 초기화

AOP 적용 순서

  1. CustomMethodInterceptor를 생성하고 메소드 보안 검사를 수행할 AuthorizationManager를 CustomMethodInterceptor에 전달
  2. CustomPointcut을 생성하고 프록시 대상 클래스와 대상 메서드를 결정할 수 있도록 포인트컷 표현식을 정의
  3. DefaultPointcutAdvisor를 생성하고 CustomMethodInterceptor와 CustomPointcut을 DefaultPointcutAdvisor에 전달
  4. 서비스를 호출하면 Pointcut으로부터 대상 클래스와 대상 메서드에 등록된 MethodInterceptor를 탐색하고 결정되면 이를 호출하여 AOP를 수행

 

구현 예제

public class CustomMethodInterceptor implements MethodInterceptor {
	private final AuthorizationManager<MethodInvocation> authorizationManager;
	
	public CustomMethodInterceptor(AuthorizationManager<MethodInvocation> authorizationManager) {
		this.authorizationManager = authorizationManager; //메서드 보안 검사를 수행 할 인가 관리자를 전달
	}
	
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		
		if(authorizationManager.check(()->authentication, invocation).isGranted()) {
			return invocation.proceed(); // 실제 대상 객체를 호출
		} else {
			throw new AccessDeniedException("Access Denied");
		}
	}
}

@Bean
public MethodInterceptor customMethodInterceptor() {
	AuthorizationManager<MethodInvocation> authorizationManager = AuthenticatedAuthorizationManager.authenticated();
	return new CustomMethodInterceptor(authorizationManager); // AOP 어라운드 어드바이스를 선언
}
@Bean
public Pointcut servicePointcut() {
	AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
	pointcut.setExpression("execution(* io.security.Myservice.*(..))"); // AOP 수행 대상 클래스와 대상 메소드를 지정
	return pointcut;
}
@Bean
public Advisor serviceAdvisor(MethodInterceptor customMethodInterceptor, Pointcut servicePointcut) { // 초기화 시 Advisor 목록에 포함된다
	return new DefaultPointcutAdvisor(servicePointcut, customMethodInterceptor);
}
728x90