• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

서버 기동 후 루트 접근 시 `/` AccessDeniedException 질문입니다

21.08.11 18:21 작성 조회수 417

0

예제에서는 DB 리소스 설정 이후에도
루트접근이 가능해 보이는데, 저의경우는 접근이 불가능합니다

아래 이미지는 서버 기동 직후, 브라우저를 통해 루트 접근시
차단이 되는 부분에 BreakPoint 를 잡아 캡쳐했습니다.

익명 사용자의 경우에 허용되어야 할 `/` 웹 루트 경로가
Denied 되는 것은 어느 부분이 문제일까요..

DB 연동은 잘 처리가 되었으나 이부분에서 막힙니다.
특별히 설정을 바꾼것이 없는데
DB 연동 처리 이후, 계속 여기서 부터 막힙니다.
어느 부분부터 살펴봐야 해결이 될까요..?

혹시 정상인가요?
( 지난 강의 돌려보다가 문뜩 생각이 듭니다)

혹제 제가 놓친부분에 대해 조언을 구합니다.
읽어주셔서 감사드립니다.

답변 5

·

답변을 작성해보세요.

1

아 네 축하드립니다^^

덕분에 저도 좋은 해결책을 알게 된 것 같습니다

끝까지 문제해결을 위한 도전에 박수를 보내드립니다~

1

네 소스는 잘 검토해 보았습니다.

원인은 다음과 같습니다. 다만 정확한 해결책은 조금 더 살펴 보아야 할 것 같습니다.

아래 를 보시면 현재 필터 리스트 중에서 맨 마지막에 위치하는 권한 필터가 customFilterSecurityInterceptor() 로 적용되지 않고 있습니다.

즉 

@EventListener(ContextRefreshedEvent.class)
@Transactional
public void onContextRefreshedEvent() throws Exception {
getHttp()
.addFilterBefore(customFilterSecurityInterceptor(), FilterSecurityInterceptor.class);

}

위 구문이 시큐리티 초기화 시 필터를 구성할 때 포함되지 않는 것 같습니다

예상컨대 

@Override
protected void configure(final HttpSecurity http) throws Exception {

http.addFilterBefore(customFilterSecurityInterceptor(), FilterSecurityInterceptor.class)

}

위 구문 안에서 처리해야 필터가 정상적으로 등록되는 것 같습니다.

아래에 보시면 FilterSecurityInterceptor 가 12번째와 13번째에 있습니다.

12번째가 직접 구현한 구현체입니다.

그렇기 때문에 아래에 보시면 FilterSecurityInterceptor 클래스인데요
SecurityMetadataSource 구현체가 UrlFilterInvocationSecurityMetadataSource 가 아닌 ExpressionBasedFilterInvocationSecurityMetadataSource 로 되어 있고 권한 설정이 any request / authenticated 라고 되어 있기 때문에 즉, 어떠한 요청에도 인증을 받아야만 모든 리소스에 접근이 가능하도록 설정이 되어 있습니다. 시큐리티의 기본설정입니다

구성은 잘 하신 것 같은데 필터를 적용하는 순서 혹은 시점이 문제가 되는 것 같습니다.

이 부분은 좀 더 디버거를 상세하게 보셔야 할 것 같습니다.

저도 정확한 원인이 무엇인지 조금 더 살펴 보도록 하겠습니다.

Truestar님의 프로필

Truestar

질문자

2021.08.14

그렇군요.. 저도 다시 살펴보겠습니다!!

Truestar님의 프로필

Truestar

질문자

2021.08.14

맞습니다. 그 부분 protected void configure(final HttpSecurity http) 내에서
MetadataSource 등록을 하게되면

루트 `/` 접근이 막히는건 해제가 되지만, Url 인가 적용이 불가능하게 되버려서 
이 상황에 시도해 본것이, DB 데이터 초기화가 끝나고 처리 하려다 보니
@이벤트리스너 에서 초기화 코드를 넣게 되었네요..

제가 경험이 없다보니 이것 말고는 떠오르는게 없더라구요.. 혹시 방도가 있을까요?

한가지 시도할 방법이 또 있다면,

  • 초기화때 DB 에서 가져오지 못한 리소스(URL ) 를 다시 로딩
    : UrlFilterInvocationSecurityMetadataSource 에서 
    reload() 메서드 구현을 시도했었습니다

1

Truestar님의 프로필

Truestar

질문자

2021.08.12

강사님. 깃헙 공유했습니다
관련 프로젝트 모듈은 `2-core-spring-security` 입니다

그리고, 이번 문제는 아래 질문과도 연계가 됩니다.
여기에 두번째로 남긴 질문에서도 정보를 얻으실 수 있어요.
Custom `FilterSecurityInterceptor` 초기화 시점 변경에 대한 질문입니다

보시기 전에 참고하셔야 되는 부분은

      • DB 는 H2 TCP 서버 ( 메모리기반 ) 입니다
        : DB를 따로 설치하지 않기위해 설정을 해야 했습니다
        : config.DummyDataLoader 에 의해 Resource 가 초기화 됩니다

      • SecurityConfig 에서 커스텀 Bean 등록되는 부분의 @Bean 어노테이션을 주석처리 했습니다
        : 이유 는, 아래 @Bean 등록 전에 DB에 Resource 데이터 입력이 되어야 하는데
        @Bean 초기화 이후, DB로 데이터 입력이 되기 때문에
        아래 Bean 들은 DB에 없는 URL 인가정보를 를 불러들이기 때문입니다.(resourceMap size = 0)
        //  @Bean //> ContextRefreshedEvent 이벤트 발생 이후에 호출되기 위해 Bean 등록 지양
        public FilterSecurityInterceptor customFilterSecurityInterceptor() throws Exception {
        }

        // @Bean //> ContextRefreshedEvent 이벤트 발생 이후에 호출되기 위해 Bean 등록 지양
        public FilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource() throws Exception {
        }

살펴봐 주셔서 감사드립니다.

1

DB 와 연동해서 인가 처리를 구현했다면 리소스권한 테이블에 URL 정보와 권한정보가 설정되어 있는 정보만 인가처리 대상이 됩니다.

만약 루트(/) 정보와 권한정보를 별도로 테이블에 입력하지 않았다면 인가 처리 대상이 되지 않으므로 모든 사용자가 접근할 수 있게 됩니다.

캡처 이미지에서 접근거부예외로 떨어지는 것을 보면 분명 해당 URL 의 리소스에 인가설정이 되어 있다는 것인데 만약 그런설정을 하지 않았는데 위의 결과가 나타난 것이면 다른 이유가 있을 것 같습니다.

혹 github 소스 공유가 가능할까요?

0

Truestar님의 프로필

Truestar

질문자

2021.08.17

강사님. 해결되었습니다.

  1. MetadataSource 에서 reload 메서드 로 DB 데이터 로딩 기능 구현 후,
  2. SecurityConfig.java 에서 @ApplicationReadyEvent 리스너 에서
  3. event.getApplicationContext() .getBean() 으로 UrlFilter...MetadataSource 가져온 후
  4. .reload() 를 실행

이런 과정으로, 
java/resources/data.sql  과 DummyDataLoader 의 데이터 삽입 과정이 끝나고,
ApplicationReadyEvent 시점에 UrlFilter...MetadataSource 에서
리소스 리로딩 해주는 방식으로 해결을 봤습니다.

Bean 을 등록하는 부분 변경이나, DataSource 의 데이터 입력 시점을 변경하는 방법은
아무리 찾아도 방법이 없는것으로 보아, 제가 어려운 방법을 택한게 아닌가 싶습니다.

문제 해결을 위해 답글 남겨주셔서 많은 도움이 되었습니다.

정말 감사드립니다.