Java 即使在允许的URL上也可以访问Jwt筛选器

Java 即使在允许的URL上也可以访问Jwt筛选器,java,spring,spring-boot,spring-security,jwt,Java,Spring,Spring Boot,Spring Security,Jwt,我正在开发一个spring引导应用程序,我在其中定义了要执行的过滤器,以管理令牌的获取和验证。因此,在我的Web安全类配置中,我设法做到了以下几点: @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity // we don't need CSRF because our token is invulnerab

我正在开发一个spring引导应用程序,我在其中定义了要执行的过滤器,以管理令牌的获取和验证。因此,在我的Web安全类配置中,我设法做到了以下几点:

@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // we don't need CSRF because our token is invulnerable
                .csrf().disable()

                // don't create session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

                .authorizeRequests()
                // .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

                // allow anonymous resource requests
                .antMatchers(HttpMethod.GET, "/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
                .antMatchers("/auth/**").permitAll()
                .antMatchers("/places/public").permitAll()

                .anyRequest().authenticated();

        // Custom JWT based security filter
        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

        // disable page caching
        httpSecurity.headers().cacheControl();
    }
authenticationTokenFilterBean是一个用@Bean注释的方法,它返回my filter的实例:

public class JwtFilter extends OncePerRequestFilter{

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtService jwtService;

    @Value("${jwt.header}")
    private String authorizationHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

        String token = httpServletRequest.getHeader(authorizationHeader);

        String username = jwtService.getUsernameFromToken(token);

        if(username!=null && SecurityContextHolder.getContext().getAuthentication() ==null){
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            if(jwtService.isTokenValid(token, userDetails)){
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

}
由于我正在扩展OncePerRequestFilter,因此每个请求只调用一次此筛选器,而GenericFilter则不同,它需要由servlet执行一次,使用Spring安全性执行另一次

我遇到的问题是,我的配置类中描述的ant matcher也被过滤器截获,即使我使用permitAll()方法允许它们,我尝试从WebSecurityConfigureAdapter重写配置(WebSecurity web)方法并忽略它们,但仍然不起作用

如何配置Spring安全性以跳过这些请求的筛选?我已经检查了这个问题,但没有解决办法


谢谢

我通过这种方式避免了这个问题,您可以参考:

@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
    if("/login".equals(req.getServletPath()) && "POST".equalsIgnoreCase(req.getMethod())){
        // ......
    }
    filterChain.doFilter(req, res);
}

更改您的WebSecurity配置类,它将如下所示:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            // we don't need CSRF because our token is invulnerable
            .csrf().disable()

            // don't create session
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

            .authorizeRequests()                

            .anyRequest().authenticated();

    // Custom JWT based security filter
    httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

    // disable page caching
    httpSecurity.headers().cacheControl();
}

 @Override
public void configure(WebSecurity web) throws Exception {
    // Ignore spring security in these paths
    web.ignoring().antMatchers("/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js","/auth/**","/places/public");
}

您必须从HttpSecurity配置方法中删除permitAll matchers,并将其放入WebSecurity配置方法。

仍在筛选器中处理,但方法更干净。 您可以覆盖
OncePerRequestFilter
shouldNotFilter(HttpServletRequest请求)
方法,并基于URL模式返回true以跳过筛选

private static List<String> skipFilterUrls = Arrays.asList("/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js");

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {

  return skipFilterUrls.stream().anyMatch(url -> new AntPathRequestMatcher(url).matches(request));
}
private static List skipFilterUrls=Arrays.asList(“/”、“/*.html”、“/favicon.ico”、“/***.html”、“/***.css”、“/***.js”);
@凌驾
受保护的布尔值shouldNotFilter(HttpServletRequest请求)引发ServletException{
返回skipFilterUrls.stream().anyMatch(url->new AntPathRequestMatcher(url).matches(请求));
}

这是在过滤器内部处理的,这是我想要避免的。无论如何,谢谢你,你可以在没有过滤的情况下为一些URL构建另一个/秒配置。你救了我的命!谢谢