스프링 시큐리티 DelegatingFilterProxy 상속 받아 custom filter를 생성할 수 있는 방법이 있는가?
로그인 전 특정 url를 대한 별도 처리를 위해 DelegatingFilterProxy 확장하여 커스텀 필터를 하나 생성하였다.
import java.io.IOException;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.DelegatingFilterProxy;
public class CheckFilter extends DelegatingFilterProxy {
private Logger log = LoggerFactory.getLogger(this.getClass());
private List<String> excludeUrls;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
System.out.println("-- Called CheckFilter --");
HttpServletRequest req = (HttpServletRequest) request;
log.info("Request Info : " + req);
String path = ((HttpServletRequest) request).getServletPath();
if(excludeUrls.contains(path))
{
// 다음 필터 실행
filterChain.doFilter(request, response);
}
// String url = req.getRequestURI();
// if("/test/pop.do".equals(url)) {
// // 다음 필터 실행
//filterChain.doFilter(request, response);
// }else {
// // 부모 필터 실행
// super.doFilter(request, response, filterChain);
// }
super.doFilter(request, response, filterChain);
}
public boolean matches(HttpServletRequest request) {
if (request.getRequestURL().indexOf("verify") != -1)
return false;
else if (request.getRequestURL().indexOf("homePage") != -1)
return false;
return true;
}
}
[web.xml]
<filter>
<filter-name>checkFilter</filter-name>
<filter-class>com.test.filter.CheckURlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>checkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- spring security filter -->
<!--
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
스프링 시큐리티 관련 필터는 주석처리 하였다.
그러나 No bean named ” is defined 오류가 발생되었다.
스프링 시큐리티 자체 필터를 확장하여 생성한 필터여서 그런것인가?
[오류 내용]
심각: Exception starting filter checkFilter
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'checkFilter' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:577)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1131)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:323)
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4950)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5652)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1700)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1690)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
<filter-name>을 checkFilter에서 springSecurityFilterChain 로 변경 후 서버를 재기동하였더니 오류가 사라졌다.
하지만 아무런 동작을 하지 않았다. 결국 다른 방법으로 해결해야하는 상황에 노였다.
스프링시큐리티를 우회할 수 있는 방법을 찾아봐야 할 것 같다.
아래 방법으로도 해결이 될까?
<filter>
<filter-name>domainFilter</filter-name>
<filter-class>com.test.CheckDomainFilter</filter-class>
<init-param>
<param-name>excludedUrls</param-name>
<param-value>login.do,logout.do</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>domainFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
* Servlet Filter implementation class CheckDomainFilter
*/
@WebFilter("/CheckDomainFilter")
public class CheckDomainFilter implements Filter {
private Logger log = LoggerFactory.getLogger(this.getClass());
private List<String> excludeUrls;
private String filterName = "springSecurityFilterChain"; // web.xml 설정된 빈네임(filter-name)
/**
* Default constructor.
*/
public CheckDomainFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
String excludePattern = fConfig.getInitParameter("excludedUrls");
excludeUrls = Arrays.asList(excludePattern.split(","));
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
System.out.println("-- Called CheckDomainFilter --");
HttpServletRequest req = (HttpServletRequest) request;
log.info("Request Info : " + req);
String path = ((HttpServletRequest) request).getServletPath();
if(!excludeUrls.contains(path))
{
// 제외하지 않는 경우
// 로직을 타게 합니다.
DelegatingFilterProxy springSecurityFilterChain = new DelegatingFilterProxy();
springSecurityFilterChain.setTargetBeanName(filterName);
}
chain.doFilter(request, response);
// String url = req.getRequestURI();
// if("".equals(url)) {
//
// }else {
// // pass the request along the filter chain
// chain.doFilter(request, response);
// }
}
public boolean matches(HttpServletRequest request) {
if (request.getRequestURL().indexOf("verify") != -1)
return false;
else if (request.getRequestURL().indexOf("homePage") != -1)
return false;
return true;
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
}
따라하다가 작업을 중단하였다. 다른 방법으로 접근 시도 중이다.
[연관자료]
- https://codevang.tistory.com/275
- Java Code Examples for DelegatingFilterProxy | Tabnine
- Using Servlet Filter as a Spring bean with DelegatingFilterProxy (logicbig.com)
- [Spring Security] Login 시스템 개발을 위한 두 가지 방법 (tistory.com)
[REFERENCE]
- [Spring/스프링] filter mapping 시 특정 페이지(url) 제외(exclude) 시키기 : 네이버 블로그 (naver.com)
- https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/delegating-filter-proxy.html