首页 > 解决方案 > Spring 安全配置 - addFilterBefore 不适用于 PUT、PATCH 和 DELETE

问题描述

Spring security我已经为API通话准备了配置。它应该验证JWT请求中提供的令牌。

http.csrf().disable().authorizeRequests()
                    .antMatchers("/v2/api/**/*").authenticated().and()
                    .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

和我的控制器方法

    @PreAuthorize("hasAuthority('ROLE_USER')")
    @PutMapping(value = "/v2/api/dashboard/projects")
    public List<Projects> getProjects(Principal principal) {
        return dashboardService.getProjects();
    }

通过执行请求我得到

已解决 [org.springframework.web.HttpRequestMethodNotSupportedException:不支持请求方法“PUT”]

当我将其更改为GetMapping请求时正在正确处理。

在设置日志之后,logging.level.org.springframework.web=DEBUG我可以看到PUT不支持不是从“/forbidden”返回,/v2/api/dashboard/projects而是从“/forbidden”返回,出于明显的原因,它不支持此类方法。

进一步的调试调查jwtRequestFilter表明过滤器甚至没有在PUT,PATCHDELETE方法上执行。

它的代码:

@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    private static final Logger log = LoggerFactory.getLogger(JwtRequestFilter.class);

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;
    @Autowired
    private JwtUtils jwtTokenUtil;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String requestTokenHeader = "";
        try{
            requestTokenHeader = WebUtils.getCookie(request, "token").getValue();
        } catch (NullPointerException ex ){}
        String username = null;
        String jwtToken = null;
        if (requestTokenHeader != null && requestTokenHeader.contains(".")) {
            jwtToken = requestTokenHeader;
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                log.error("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                log.error("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not look like token");
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}

谁能给我一个提示如何使它起作用,PUT并且PATCH方法将被给定的类过滤?

标签: javaspring-bootspring-security

解决方案


推荐阅读