[Spring Security] 16. AuthorizationFilter

조성우·2024년 8월 25일

Spring Security

목록 보기
16/16
post-thumbnail

DefaultSecurityFilterChain에 기본적으로 등록되는 필터로 마지막에 위치하는 AuthorizationFilter에 대해 알아보자.


목적

SecurityFilterChain의 authorizeHttpRequests()를 통해 인가 작업을 진행한 값에 따라 최종적으로 인가를 수행하는 역할을 한다.

커스텀 SecurityFilterChain에도 기본적으로 등록되며 인가를 설정하는 방법은 아래와 같다.

http
        .authorizeHttpRequests((auth) -> auth
                .requestMatchers("/").permitAll()
                .anyRequest().permitAll());


AuthorizationFilter 클래스

public class AuthorizationFilter extends GenericFilterBean {

	...
    
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws ServletException, IOException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 특정 설정이 enable이고 이 필터가 이번 요청에서 이미 사용 되었다면 건너 뜀
        if (this.observeOncePerRequest && isApplied(request)) {
            chain.doFilter(request, response);
            return;
        }

        // 비동기 요청과 같은 특정 상황에서 인가 작업을 건너 뛸지 결정
        if (skipDispatch(request)) {
            chain.doFilter(request, response);
            return;
        }

        // 현재 필터가 이미 사용되었다면 값을 추가
        String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
        request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);

        // 인가 작업 수행
        try {
            // 인가 매니저를 통해 인가 확인
            AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
            this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);

            if (decision != null && !decision.isGranted()) {
                // 인가 권한이 안맞다면 예외 발생
                throw new AccessDeniedException("Access Denied");
            }
            chain.doFilter(request, response);
        }
        finally {
            // 최종적으로 모든 작업 처리 후 사용 기록 삭제
            request.removeAttribute(alreadyFilteredAttributeName);
        }
    }
    
    ...
    
}

0개의 댓글