이벤트 처리

enxnong·2024년 7월 20일
0

스프링 시큐리티

목록 보기
9/13

정수원님의 강의 스프링 시큐리티 완전 정복 [6.x 개정판] 보면서 공부한 내용입니다.

인증 이벤트

Authentication Events

  • 인증이 성공하거나 실패하게 되면 ApplicationEventPublisher 를 사용하거나 시큐리티에서 제공하는 AuthenticationEventPublisher 를 사용해서 AuthenticationSuccessEvent 또는 AuthenticationFailureEvent 를 발생시킨다
  • AuthenticationEventPublisher 의 구현체로 DefaultAuthenticationEventPublisher 가 제공된다

이벤트 발행 방법

  1. ApplicationEventPublisher.publishEvent(ApplicationEvent)
    → ApplicationEvent의 객체를 넣어준다
  2. AuthenticationEventPublisher.publishAuthenticationSuccess(Authentication)
    → 성공했을 당시의 인증 객체(Authentication)
  3. AuthenticationEventPublisher.publishAuthenticationFailure(AuthenticationException, Authentication)
    → 실패했을 당시의 인증 객체AuthenticationException, Authentication)

이벤트 수신 방법

@Component
public class AuthenticationEvents {
@EventListener // 이벤트를 수신하는 클래스가 된다는 의미의 어노테이션
public void onSuccess(AuthenticationSuccessEvent success) {
	// 발행된 이벤트를 적용해야지 수신이 가능함
}
@EventListener
public void onFailure(AbstractAuthenticationFailureEvent failures) {}
}

인증 이벤트 종류

  • 인증 성공 & 실패 이벤트 모두 포함해서 항상 수신되는 상위 클래스
    • AbstractAuthenticationEvent
  • 이벤트가 실패할 때마다 항상 수신되는 상위 클래스
    • AbstractAuthenticationFailureEvent
  • 인증 성공 이벤트
    • AuthenticationSuccessEvent
      • ProviderManager가 인증을 처리하는 과정에서 발생하는 이벤트를 수신
    • InteractiveAuthenticationSuccessEvent
      • UsernamePasswordAuthenticationFilter가 인증을 처리하는 필터가 인증을 성공하면 발생하는 이벤트를 수신
  • 인증 실패 이벤트
    • AuthenticationFailureBadCredentialsEvent
    • AuthenticationFailureDisalbedEvent
    • ...

AuthenticationEventPublisher 활용

  • 커스텀 예외 & 이벤트 추가
@Bean // ApplicationEventPublisher 객체 타입의 빈을 정의
public AuthenticationEventPublisher customAuthenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  
  Map<Class<? extends AuthenticationException>, Class<? extends AbstractAuthenticationFailureEvent>> mapping =
  Collections.singletonMap(CustomException.class, CustomAuthenticationFailureEvent.class);
  // CustomException.class 예외가 발생하면 CustomAuthenticationFailureEvent.class 이벤트가 발행된다
  
  // DefaultAuthenticationEventPublisher는 예외와 이벤트를 mapping하고 있음
  // 만약 A예외가 발생하면 A이벤트(실패 이벤트)가 발행하라
  // 즉, 모든 예외마다 각각의 이벤트를 맵핑하고 있음
  DefaultAuthenticationEventPublisher authenticationEventPublisher = new DefaultAuthenticationEventPublisher(applicationEventPublisher); 
  authenticationEventPublisher.setAdditionalExceptionMappings(mapping); // 이벤트 매핑 추가
  
  return authenticationEventPublisher;
  
}
  • 기본 이벤트 설정
  • 예외와 매핑된 이벤트가 없는 경우 AuthenticationFailureEvent(기본 이벤트)를 발행 및 수신할 수 있다
@Bean
public AuthenticationEventPublisher defaulAuthenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  DefaultAuthenticationEventPublisher authenticationEventPublisher 
  		= new DefaultAuthenticationEventPublisher(applicationEventPublisher);
        
  authenticationEventPublisher
  		.setDefaultAuthenticationFailureEvent(CustomDefaultAuthenticationFailureEvent.class); // 기본 이벤트 설정

Authorization Events

  • 권한 부여 이벤트 처리를 지원하며 권한이 부여되거나 거부된 경우에 발생하는 이벤트를 수신할 수 있다
  • 이벤트를 수신하려면 ApplicationEventPublisher 를 사용하거나 시큐리티에서 제공하는 AuthorizationEventPublisher 를 사용해서 발행해야 한다

이벤트 발행 방법

  1. ApplicationEventPublisher.publishEvent(ApplicationEvent)
  2. AuthorizationEventPublisher.publishAuthorizationEvent(Supplier<Authentication>, T, AuthorizationDecision)
    → Supplier<Authentication> : Authentication 인증 객체
    → T : T 타입의 객체
    → AuthorizationDecision : 인가 결정을 담고 있는 객체

이벤트 수신 방법

@Component
public class AuthorizationEvents {

@EventListener
public void onAuthorization(AuthorizationDeniedEvent failure){
	// AuthorizationDeniedEvent : 접근이 거부됐을 때 발생하는 이벤트
}

@EventListener
public void onAuthorization(AuthorizationGrantedEvent success){
	// AuthorizationGrantedEvent : 접근이 허용됐을 때 발생하는 이벤트
}
}

인가 이벤트 발행 & 수신

  • 인가 이벤트를 발행 하기 위해서는 SpringAuthorizationEventPublisher 를 빈으로 정의해야 한다
  • 인가 실패인 경우에만 이벤트가 발행
  • 인가 성공인 경우에도 이벤트를 발행하려면 커스텀 AuthorizationEventPublisher를 구현해야 한다
// 기본 AuthorizationEventPublisher 구현
@Bean
public AuthorizationEventPublisher authorizationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
	return new SpringAuthorizationEventPublisher(applicationEventPublisher);
}
profile
높은 곳을 향해서

0개의 댓글