spring-projects / spring-projects/spring-session
custom filter response writer print data disappear with spring session
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.9k
- Forks
- 1.2k
- Avg merge
- 4h 27m
- Merged PRs (30d)
- 55
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the custom filter's doFilterInternal method and the FilterRegistrationBean configuration, then trace how Spring Session processes the response after the filter writes the 401 body. Reproduce the behavior with the shown authentication-failure paths and verify that the status, headers, and JSON response body are all preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring-boot
- Domain
- authentication, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100