본문 바로가기

Spring

Spring Webflux Filter 적용 (Webfilter)

728x90

Webflux를 사용해보면서 Interceptor를 적용해보고 싶었는데 기존 MVC 구조에서 사용하던 interceptor, 엄밀히 말하면 톰캣을 위해 사용하던 인터셉터는 사용할 수 없었다. 약간 찾아본 결과 Webfilter 사용을 많이 하는듯 보여서 적용해봤다.

 

적용은 매우 간단하다. Webfilter 인터페이스를 구현한 클래스를 하나 생성해서 @Component만 적용해주면 끝.

그래서 나는 Webfilter를 구현한 AclFilter라는 클래스를 생성했다.

 

AclFilter

import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import reactor.core.publisher.Mono;

@Component
public class AclFilter implements WebFilter{
	
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		...
		return chain.filter(exchange);
	}

}

이런 식으로 사용해주면 된다.

ServerWebExchange를 통해 Request, Response, Session등을 얻을 수 있다.

 

아래는 내가 사용한 예제코드다.

@Component
public class AclFilter implements WebFilter{
	private Logger log = LoggerFactory.getLogger(AclFilter.class);
	
	private String ACL_ID;
	private String ACL_PASSWD;
	
	public AclFilter() {
		PropertiesUtil propsUtil;
		try {
			propsUtil = new PropertiesUtil();
			this.ACL_ID = propsUtil.getProperty("ACL_ID");
			this.ACL_PASSWD = propsUtil.getProperty("ACL_PASSWD");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
		log.info("Web filter");
		
		// check ACL_ID, ACL_PASSWD Init
		if(ACL_ID == null || ACL_PASSWD == null) {
			log.error("Init ACL_ID or ACL_PASSWD ERROR");
			throw new CustomException(ErrorCode.INIT_SERVER_ERROR);
		}
		
		ServerHttpRequest request = exchange.getRequest();
		
		String id = request.getHeaders().getFirst("ACL-ID");
		String password = request.getHeaders().getFirst("ACL-PASSWD");
		
		//check ACL Essential Headers
		if(id == null || password == null) {
			log.error("ACL ID OR PASSWORD VALUE IS NULL");
			throw new CustomException(ErrorCode.HEADER_NOT_FOUND);
		}
		
		if(!id.equals(this.ACL_ID) || !password.equals(this.ACL_PASSWD)) {
			log.error("ID OR PASSWORD IS NOT MATCH");
			throw new CustomException(ErrorCode.HANDLE_ACCESS_DENIED); 
		}
		
		return chain.filter(exchange);
	}

}

CustomException은 이전글에 있으니 참고

728x90