如何修改java过滤器链

在开发中遇到一个场景,当需要提供接口给其他系统,并需要鉴权时,我当时的处理方案是用过滤器拦截进行个性化鉴权,如果鉴权通过则还是需要经过安全测试、转码等filter,但是不走后面的鉴权过滤器,不通过则跳转到错误页面。

这里就需要去掉过滤器链中的某一个过滤器,下面介绍下我的方案:通过反射修改过滤器链:

 /**
     * 
     * 通过反射修改过滤器链
     * @param chain   
     */
    private void skipFilter(FilterChain chain) {
        try {
            //排除的过滤器数组
            Object[] filterArr=new Object[]{InterfaceConstants.UN_AUTH_FILTER};
            Field field = chain.getClass().getDeclaredField("filters");
            field.setAccessible(true);
            FilterConfig[] filters = (FilterConfig[]) field.get(chain);
            int k = 0;
            for (int i = 0; i < filters.length; i++) {
                if (filters[i] != null) {
                    Field field2 = filters[i].getClass().getDeclaredField("filterDef");
                    field2.setAccessible(true);
                    Field field3 = field2.get(filters[i]).getClass().getDeclaredField("filterClass");
                    field3.setAccessible(true);
                    String filterClass = (String) field3.get(field2.get(filters[i]));
                    int loc = Arrays.binarySearch(filterArr, filterClass);
                    if (loc >= 0) {
                        //将过滤器重置为null
                        filters[i] = null;
                        k++;
                    }
                    field3.setAccessible(false);
                    field2.setAccessible(false);
                }
            }
            int index = 0;
            for (int i = 0; i < filters.length; i++) {
                if (index == 0 && filters[i] == null) {
                    index = i;
                } else if (index != 0 && filters[i] != null) {
                    filters[index] = filters[i];
                    filters[i] = null;
                    i = index;
                    index = 0;
                }
            }
            field.setAccessible(false);
            Field n=null;
            try {
                n = chain.getClass().getDeclaredField("n");
                logger.info("tomcat容器中filter的n属性");
            } catch (Exception e) {
                n = chain.getClass().getDeclaredField("filterCount");
                logger.info("jboss容器中filterCount属性");
            }
            if(n!=null){
                n.setAccessible(true);
                n.set(chain, n.getInt(chain) - k);
                n.setAccessible(false);
            }
        } catch (Exception e) {
            logger.error("通过反射修改过滤器链出错",e);
        }
        
    }

猜你喜欢

转载自lipengjavablog.iteye.com/blog/2290762