BYTECODES

Java Spring过滤器在实际项目中的运用

Java Spring boot中过滤器通常用来处理日志或者做安全验证。最近项目有个场景,用户在查看数据时,有部分数据是敏感数据,如果没有权限查看的话,需要把数据置空或用横线代替。如果一个一个接口修改,无疑是一项巨大的劳动。所以我们就可以借用filter,在数据返回前进行数据清理。


在重置response时,还有个乱码问题需要注意的。

@WebFilter(urlPatterns = "/api/*")
@Order(-1)
public class SensitiveInfoFilter implements Filter {
    @Resource
    private TUserInfoService tUserInfoService;
    @Resource
    private TAdminSystemRoleService tAdminSystemRoleService;
    private final Map<String, List<String>> sensitiveData = new HashMap<String,List<String>>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //设置过滤路径及相应的数据
        sensitiveData.put("/api/menu_id/list",
                Arrays.asList(new String[]{
                        "data.list.consumerName"+"."+ RightsEnum.CONSUMER.getRights()
                })
        );
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String newToken = request.getHeader("newToken");
        if (null != newToken){
            Integer userId = JwtTokenUtil.getInfoByToken(TokenKeyEnum.USER_ID.value(), newToken);
            if (null!=userId){
                TUserInfo userInfo = tUserInfoService.findBy("id", userId);
                if (null != userInfo){
                    int roleId = userInfo.getRoleId();
                    TAdminSystemRole role = tAdminSystemRoleService.findBy("id", roleId);
                    String rights = role.getRights();
                    List<String> uris = sensitiveData.get(request.getRequestURI());
                    ContentCachingResponseWrapper wrapper = new ContentCachingResponseWrapper(response);
                    wrapper.setCharacterEncoding(StandardCharsets.UTF_8.toString());
                    filterChain.doFilter(request, wrapper);
                    if (uris != null) {
                        byte[] bytes = wrapper.getContentAsByteArray();
                        String content = new String(bytes, StandardCharsets.UTF_8);

                        Object jsonObject = JSONObject.parse(content);
                        if (jsonObject != null) {
                            for (int i = 0; i < uris.size(); i++) {
                                String[] attrs = uris.get(i).split("\\.");
                                if (!rights.contains(attrs[attrs.length-1])){
                                    filter(jsonObject, attrs, 0);
                                }
                            }
                            wrapper.resetBuffer();
                            wrapper.getWriter().write(((JSONObject) jsonObject).toJSONString());
                        }
                    }
                    wrapper.copyBodyToResponse();
                }else{
                    filterChain.doFilter(request, response);
                }
            }else{
                filterChain.doFilter(request, response);
            }
        }else{
            filterChain.doFilter(request, response);
        }
    }

    private void filter(Object object, String[] attrs, int current) {
        if (current == attrs.length - 2) {
            setNull(object, attrs[current]);
        } else {
            if (object instanceof JSONObject) {
                Object subObject = ((JSONObject) object).get(attrs[current]);
                filter(subObject, attrs, current + 1);
            } else if (object instanceof JSONArray) {
                for (Object item : (JSONArray) object) {
                    Object subObject = ((JSONObject) item).get(attrs[current]);
                    filter(subObject, attrs, current + 1);
                }
            }
        }
    }

    private void setNull(Object object, String key) {
        if (object instanceof JSONObject) {
            ((JSONObject) object).put(key, null);
        } else if (object instanceof JSONArray) {
            for (Object item : (JSONArray) object) {
                ((JSONObject) item).put(key, null);
            }
        }
    }

}