인프런 커뮤니티 질문&답변

Truestar님의 프로필 이미지
Truestar

작성한 질문수

스프링 시큐리티

5) 웹 기반 인가처리 DB 연동 - FilterInvocationSecurityMetadataSource (2)

Custom `FilterSecurityInterceptor` 초기화 시점 변경에 대한 질문입니다

작성

·

155

0

저의 테스트 환경이 DB 데이터가 구동시점에 초기화가 되도록 설정한 상태입니다. 이 때문에 아래와 같은 이슈가 있습니다.

  • DB 데이터 초기화가 되지 않아 RequestMap 에 URL Resource  를 불러오지 못해서
    `인가`처리가 불가능합니다

이것은,
src/main/resources/data.sql 또는
SetupDataLoader.java 를 통해 데이터를 설정하다 보니
초기화 순위에 밀려 Resource 설정이 안되는 상태를 볼 수 있었는데요,

Reousrce 데이터가 입력되는 시점은

  1. Table 이 만들어 진 직후,
  2. SecurityMetadataSource 에서 Resource 목록을 불러오고,
    (row = 0)
  3. Resource INSERT 문이 실행됩니다



질문입니다

  1. 이를 해결하기 위해서는,
    DB 인서트 쿼리를 SecurityConfig 보다 우선으로 실행하거나,
    customFilterSecurityInterceptor 가 @Bean 으로 등록되는 시점을 늦춰야 되는데,
    혹시 , SecurityConfig 자체가 초기화 되는 시점을 늦출 수는 없을까요?
    (리소스 세팅 이후.. 실행)

  2. Spring 이벤트로 처리가 가능하다면 Spring 이벤트중 적절한 시점의 이벤트는 어떤게 있을까요?
    ( DB 데이터 입력이 ContextRefreshedEvent 보다 먼저 되어야 하는데, 방법을 모르겠습니다)

  3. 외람되지만, JPA 관련 이벤트나 @Pre, Post Persist 로도 가능할까요?

어떤식으로 해결해는것이 좋을까요?
읽어주셔서 감사드립니다.


답변 2

0

Truestar님의 프로필 이미지
Truestar
질문자

강사님! 답변감사드립니다.

강사님의 말씀처럼 저 역시 운영환경이나, 테스트환경에서도
Admin 을 통해 리소스 관리가 되어야 된다고 생각합니다. 단지, 저의 예제 형태가 응용을 거친상태이고,
Postgress 없이 메모리 DB를 활용한 예제인 상황탓에
무리없는 진행을 위해 질문하게 되었습니다

알려주신 방법에 난이도가 있는것 같아서 제가 해결을 보지 못했습니다. 이유가..
BeanPostProcessor 의 Overriding 메서드 postProcessAfterInitialization 는
Bean 등록이 끝나면 실행되는것은 맞습니다만, 여전히 Resource DB 등록(JPA 쿼리 실행) 이전에 실행이 되는탓에
resourceMap 초기화 안되고 있는 상황이었습니다. (size=0)
그래서 천신만고 끝에 다른방법으로 해결을 보았는데요,

아래 두가지 절차로 해결이 되긴 했습니다.
( 예제를 함부로 변형하는걸 지양하는 습성이 있어서, 이걸 알아내느라 고생이 많았습니다...ㅠㅠ )

SecurityConfig.java

  1.  @Bean 주석처리
    //  @Bean
    public FilterSecurityInterceptor customFilterSecurityInterceptor() {...}
    // @Bean
    public FilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource(){...}
  2. ContextRefeshedEvent 발생 시점에 커스텀필터 before 등록 및 기존 설정 주석
    @EventListener(ContextRefreshedEvent.class)
    @Transactional
    public void onContextRefreshedEvent() throws Exception {
    getHttp().addFilterBefore(customFilterSecurityInterceptor(),
    FilterSecurityInterceptor.class);
    }

이 시점에 한가지 질문이 있습니다

혹시, 예제에서 두 @Bean 이 POJO 가 되면 안되는 이유가 있을까요?
만약 POJO 인 상태로, 앞으로 남은 예제 진행 상태에 무리가 있다면,
전 아직 해결을 본상황이 아니라서 그렇습니다.

읽어주셔서 감사합니다.

0

정수원님의 프로필 이미지
정수원
지식공유자

일반적으로 리소스를 DB 에 세팅하는 순서가 그렇게 중요하다고 생각하지는 않습니다.

실제 운영에서 관리한다면 아마 수동으로 리소스를 입력하지 않을까 합니다.

다만 서버가 구동되고 스프링 배치가 초기화 되는 시점에 모든 리소스가 자동으로 배치되도록 하는 방법을 쓰야 한다면 스프링의 빈이 초기화 될 때 BeanPostProcessor 인터페이스를 구현한 클래스를 호출하는 시점이 있는데 CustomFilterSecurityInterceptor 가 빈으로 생성되도록 했다면 BeanPostProcessor 는 customFilterSecurityInterceptor 가 빈으로 최종 생성되기 전에 호출되기 때문에 BeanPostProcessor 인터페이스 안에서 리소스를 초기화 하는 구문을 작성하면 가능할지도 모르겠습니다.

그러나 저의 판단으로는 강의에서는 테스트를 위한 목적으로 리소스를 구동시점에 초기화 하고 있지만 실제 운영에서는 수동으로 직접 리소스를 관리하고 추가적인 리소스를 등록할 경우에 어드민에서 등록 화면을 제공해서 운영하는 것이 좋지 않을까 생각해 봅니다. 

Truestar님의 프로필 이미지
Truestar

작성한 질문수

질문하기