@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		long _start = System.currentTimeMillis();
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse rep = (HttpServletResponse) response;
		SecurityServletContext context = new SecurityServletContext(req, rep);
		
		String url = context.getRequestUrl();
		try {
			// 排除全局的不拦截路径
			if(securityApplicaionContext.matchExcludeUrl(url)) {
				if(logger.isDebugEnabled()) {
					logger.debug("{} execute[exclude]: {}ms", url, System.currentTimeMillis() - _start);
				}
				chain.doFilter(request, response);
				return;
			}
			for(SecurityDomainConfiguration config : securityApplicaionContext.getSecurityDomainConfigurations()) {
				if(config.matchUrl(url)) {
					// get UserDetails, May be null
					UserDetails userDetails = config.getUserDetailsHelper().loadUserDetails(context, config);
					// invoke Interceptors
					config.getInterceptorChainInstance().doFilter(context, userDetails, config);
					
					if(config.isShortCircuit()) { // 短路
						break;
					}
				}
			}
			if(logger.isDebugEnabled()) {
				logger.debug("{} execute[pass]: {}ms", url, System.currentTimeMillis() - _start);
			}
			chain.doFilter(request, response);
			return;
		} catch (SecuritySuspendException e) {
			// Suspend chain.doFilter(request, response);
			if(logger.isDebugEnabled()) {
				logger.debug("{} execute[fail]: {}ms", url, System.currentTimeMillis() - _start);
			}
		} catch (SecurityRuntimeException e) {
			logger.error("websecurity 运行时异常");
			throw new ServletException("SecurityFilterChain doFilter SecurityRuntimeException", e);
		}
	}