스프링 시큐리티/실전프로젝트 - 인가 프로세스 DB 연동 웹 계층 구현

ch07. 인가처리 허용 필터 - PermitAllFilter 구현

webmaster 2022. 1. 24. 13:26
728x90

동작과정

  • PermitAllFilter를 먼저 작성하여, 실제 권한 심사가 필요 없는 요청은 AbstractSecurityInterceptor에 인가를 요청하지 않도록 구현한다.
  • PermitAllFilter
    • public class PermitAllFilter extends FilterSecurityInterceptor {
      
          private static final String FILTER_APPLIED = "__spring_security_filterSecurityInterceptor_filterApplied";
          
          //RequestMatcher타입으로 List로 저장
          private List<RequestMatcher> permitAllRequestMatcher = new ArrayList<>();
      
          //생성자를 통해 PermitAll되는 자원을 입력받는다
          public PermitAllFilter(String... permitAllPattern) {
              createPermitAllPattern(permitAllPattern);
          }
          
          private void createPermitAllPattern(String... permitAllPattern) {
              for (String pattern : permitAllPattern) {
                  permitAllRequestMatcher.add(new AntPathRequestMatcher(pattern));
              }
      
          }
      
      
          @Override
          protected InterceptorStatusToken beforeInvocation(Object object) {
              boolean permitAll = false;
              HttpServletRequest request = ((FilterInvocation) object).getRequest(); //사용자 요청정보
              for (RequestMatcher requestMatcher : permitAllRequestMatcher) {
                  if (requestMatcher.matches(request)) { //사용자 정보 == request정보
                      permitAll = true; //인가 처리가 필요 없으므로 flag를 true
                      break;
                  }
              }
      
              if (permitAll) { //인가 처리가 필요 없는 상태
                  return null; //권한 체크를 하지 않는다.
              }
      
              return super.beforeInvocation(object);  //권한 처리가 필요한 것은 부모로 인가처리를 넘긴다.
          }
      
          @Override
          public void invoke(FilterInvocation fi) throws IOException, ServletException {
      
              if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
                      && super.isObserveOncePerRequest()) {
                  // filter already applied to this request and user wants us to observe
                  // once-per-request handling, so don't re-do security checking
                  fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
              } else {
                  // first time this request being called, so perform security checking
                  if (fi.getRequest() != null) {
                      fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
                  }
      
                  InterceptorStatusToken token = beforeInvocation(fi);
      
                  try {
                      fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
                  } finally {
                      super.finallyInvocation(token);
                  }
      
                  super.afterInvocation(token, null);
              }
          }
      
      
      }
      
  • SecurityConfig의 Filter를 내 Filter로 변경해 준다.
    • PermitAllFilter로 변경
    • 생성자로 넘겨줄 값
    • 생성자로 인증이 필요 없는 String 배열을 매개변수로 전달해 준다.
728x90