如何配置Spring-Security(Spring 6),使其不在不安全的路由上执行过滤?

fkaflof6  于 2023-01-05  发布在  Spring
关注(0)|答案(1)|浏览(188)

与此另一个堆栈溢出topic有些相关,它既没有给予正确的解决方案,也不适用于Spring 6(Sping Boot 3)。
我提出了一个基本的spring-boot app来证明我的观点。
有一个控制器有两个端点,其中一个必须是安全的,另一个是可访问的。

@RestController
public class TestController {

    @GetMapping("/secured-api")
    public String securedApi() {
        return "secured";
    }

    @GetMapping("/public/open-api")
    public String openApi() {
        return "open";
    }

}

安全上下文如下所示,假设MyFilter正在执行一些花哨的操作,例如:验证JWT令牌,如果令牌无效/过期,则触发异常。

@Configuration
public class ComponentSecurityContext {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        return http
            .addFilterAt(new MyFilter(), BasicAuthenticationFilter.class)
            .authorizeHttpRequests(customizer -> customizer
                .requestMatchers(new AntPathRequestMatcher("/public/**"))
                .permitAll()
                .anyRequest()
                .authenticated())
            .build();
    }

    public static class MyFilter extends OncePerRequestFilter {

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

            System.out.println("Filter is called for uri: " + request.getRequestURI());

            // performs some authentication

            filterChain.doFilter(request, response);
        }
    }

}

在服务器上执行以下两个curl

curl http://localhost:9003/public/open-api
curl http://localhost:9003/secured-api

正在触发MyFilter

Filter is called for uri: /public/open-api
Filter is called for uri: /secured-api

对于安全端点,我希望MyFilter被称为only,我不关心是否使用过期令牌访问不受保护的端点。
有什么建议,如何适当的电线Spring安全,以实现这一点?

3bygqnnd

3bygqnnd1#

筛选器由securityMatcher确定作用域的工作解决方案:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

    return http
        .securityMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/public/**")))
        .addFilterAt(new MyFilter(), BasicAuthenticationFilter.class)
        .authorizeHttpRequests((requests) -> requests.anyRequest().authenticated())
        .build();
}

相关问题