Skip to content

custom filter response writer print data disappear with spring session #3474

@wuguowei19880907

Description

@wuguowei19880907

My project is built with Spring Boot 2.7.18 and Spring Session, without using Spring Security. I plan to implement authentication using a custom filter, and when authentication fails, return a 401 status code with error information in the response. My core business logic is as follows:

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        UrlPathHelper urlPathHelper = UrlPathHelper.defaultInstance;
        final String uri = urlPathHelper.getPathWithinApplication(request);
        // final String uri = request.getRequestURI();
        final String requestMethod = request.getMethod();
        // Step1: 放行公开资源
        if (isPublicUrl(uri, requestMethod)) {
            filterChain.doFilter(request, response);
            return;
        }

        // Step2: 检查会话是否存在
        HttpSession session = request.getSession(false);
        if (session == null) {
            return401(response, ECode.E100032);
            return;
        }

        Long userId = (Long) session.getAttribute(KEY_LOGIN_USER);
        if (userId == null) {
            return401(response, ECode.E100032);
            return;
        }

        // Step3: 验证细粒度权限
        List<String> permissionList = isPermissionRequiredUrl(uri, requestMethod);

        if (!permissionList.isEmpty()) {
            // 获取用户的权限列表 adminPermissions
            Set<String> adminPermissions = adminUserManager.getAdminPermissions(userId);
            // 判断,如果用户的权限包括接口要求的权限,则通过过滤器,否则报错。
            if (!adminPermissions.containsAll(permissionList)) {
                return401(response, ECode.E100020);
                return;
            }
        }
        filterChain.doFilter(request, response);
    }
................
    private void return401(HttpServletResponse response, ECode eCode) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        // 添加调试头信息
        response.setHeader("X-Auth-Debug", "401-returned");
        response.setHeader("X-Error-Code", String.valueOf(eCode.getNumber()));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", eCode.getNumber() + "");
        jsonObject.put("message", eCode.getMessage());
        try (PrintWriter writer = response.getWriter()) {
            writer.print(jsonObject.toJSONString());
            writer.flush();
        }
    }

However, I found that after authentication fails, the 401 status code is returned correctly, but the error information in the response body is missing.
The filter registration code is as follows:

    @Bean
    public FilterRegistrationBean<AuthFilter> authFilter() {
        FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
        registration.addUrlPatterns("/a/v2/*");
        registration.setOrder(Ordered.LOWEST_PRECEDENCE);
        return registration;
    }

I also tried using OutputStream to write the response body,

       OutputStream outputStream = response.getOutputStream();
        outputStream.write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
        outputStream.flush();

but it didn't work either.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions