当使用Jetty作为服务器时,当JWT Filter在Spring Security中阻止未经身份验证的用户时,如何返回一个明确的json 401错误?

pxyaymoc  于 2022-11-24  发布在  Spring
关注(0)|答案(1)|浏览(134)

我有我的Spring Security bean,它在阻止未经授权的请求方面做得很好,当使用Tomcat时,错误响应是一个干净的消息异常,但使用Jetty时,即使在postman中也会返回一个text/html,如下所示。x1c 0d1x我的doFilterInternal JWT过滤器如下所示。

public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private JWTUtility jwtUtility;

    @Autowired
    private UserServiceImpl userService;
    private final ObjectMapper mapper;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String authorization = httpServletRequest.getHeader("Authorization");
        String token = null;
        String userName = null;

        if(null != authorization && authorization.startsWith("Bearer ")) {
            token = authorization.substring(7);
            userName = jwtUtility.getUsernameFromToken(token);
        }

        if(null != userName && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails
                    = userService.loadUserByUsername(userName);
            try {
                if (jwtUtility.validateToken(token, userDetails)) {
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                            = new UsernamePasswordAuthenticationToken(userDetails,
                            null, userDetails.getAuthorities());

                    usernamePasswordAuthenticationToken.setDetails(
                            new WebAuthenticationDetailsSource().buildDetails(httpServletRequest)
                    );

                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            } catch (Exception e){
//                System.out.println("Hello world");
                Map<String, Object> errorDetails = new HashMap<>();
                errorDetails.put("ACCESS_DENIED", e.getMessage());
                httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
                httpServletResponse.setContentType(String.valueOf(MediaType.APPLICATION_JSON));
                mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
                return;
            }

        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

使用Tomcat作为我的服务器时,一切都按预期工作,但我已经转移到Jetty服务器,我如何才能最好地替换下面的代码,使其在Jetty中也能工作?

Map<String, Object> errorDetails = new HashMap<>();
                errorDetails.put("ACCESS_DENIED", e.getMessage());
                httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
                httpServletResponse.setContentType(String.valueOf(MediaType.APPLICATION_JSON));
                mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
                return;

当用户没有发送他们的jwt时,我的预期响应如下:-

HTTP 401 Unauthorized
{
    "ACCESS_DENIED": "Some error message here",
}

否则,请求应该通过,因此筛选器不应返回任何内容。
注意:请随时编辑此问题,使它更好,因为我有更多的朋友试图解决同一问题。

omhiaaxx

omhiaaxx1#

您看到的响应是默认的Servlet ERROR调度处理(请参阅DispatcherType.ERROR)
使用标准Servlet错误页Map指定您自己的自定义Map以处理错误。Map可以基于状态代码、可抛出对象等(请参阅Servlet描述符和<error-page>Map)

相关问题