如何仅在安全端点上应用弹簧安全过滤器?

Bra*_*avo 19 java security spring spring-mvc spring-security

我有以下Spring Security配置:

    httpSecurity
            .csrf()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/api/**").fullyAuthenticated()
            .and()
            .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
Run Code Online (Sandbox Code Playgroud)

authenticationTokenFilterBean()甚至在不匹配的终端应用/api/**表现.我还尝试添加以下配置代码

@Override
public void configure(WebSecurity webSecurity) {
    webSecurity.ignoring().antMatchers("/some_endpoint");
}
Run Code Online (Sandbox Code Playgroud)

但这仍然没有解决我的问题.如何告诉spring security仅在与安全URI表达式匹配的端点上应用过滤器?谢谢

Fra*_*eth 26

我有一个具有相同要求的应用程序并解决它我基本上将Spring Security限制为给定的蚂蚁匹配模式(使用antMatcher),如下所示:

http.antMatcher("/api/**").authorizeRequests() //
        .anyRequest().authenticated() //
        .and()
        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式阅读:http仅在与/api/**授权any requestauthenticated用户的ant模式匹配的请求上调用这些配置and add filter authenticationTokenFilterBean() before UsernamePasswordAuthenticationFilter.对于所有其他请求,此配置无效.

  • 也不适合我,过滤器是针对例如 /internal 上的请求执行的 (5认同)
  • 对于评论的更多读者:答案是**正确**。所有说它不起作用的人都做错了(例如,他们将“authenticationTokenFilterBean()”方法定义为“@Bean”,在这种情况下,即使没有这种安全性,spring-boot也会自动扫描它并将其添加为通用过滤器配置,如果您只想将此过滤器添加到安全过滤器链中,这显然是错误的)。 (5认同)
  • 它对我不起作用,除/ api之外,过滤器被请求请求 (4认同)
  • 配置不正确。不按预期工作。 (4认同)
  • 如果我想允许/ api / login即完全绕过/ api / login怎么办。即使我做了一个allowAll(),过滤器仍然会被调用。请提出建议。 (3认同)
  • **@Everyone:** 确保您使用的是 `antMatcher(..)` 而不是 `antMatchers(..)` (如解决方案中所示)。另请注意,路径匹配调用的顺序很重要。 (3认同)
  • 这不是真的......`authenticationTokenFilterBean`将在它与匿名一起使用的每个请求上运行. (2认同)

小智 6

我的要求是排除匹配 /api/auth/** 的端点,为了实现相同的目的,我配置了我的 WebSecurityConfig spring 配置组件,如下所示:

/**
 * The purpose of this method is to exclude the URL's specific to Login, Swagger UI and static files.
 * Any URL that should be excluded from the Spring security chain should be added to the ignore list in this
 * method only
 */
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/auth/**","/v2/api-docs", 
            "/configuration/ui", 
            "/swagger-resources", 
            "/configuration/security",
            "/swagger-ui.html", 
            "/webjars/**",
            "/favicon.ico",
            "/**/*.png",
            "/**/*.gif",
            "/**/*.svg",
            "/**/*.jpg",
            "/**/*.html",
            "/**/*.css",
            "/**/*.js");
}


   /**
     * The purpose of this method is to define the HTTP configuration that defines how an HTTP request is 
     * going to be treated by the Spring Security chain. All the request URL's (excluding the URL's added
     * in WebSecurity configuration ignore list) matching this configuration have to pass through the
     * custom Spring security filter defined in this method
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
        .cors().disable()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(unauthorizedHandler)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
    }

/**
 * The purpose of this method is to create a new instance of JWTAuthenticationFilter
 * and return the same from the method body. It must be ensured that this filter should
 * not be configured as a Spring bean or registered into the Spring Application context
 * failing which the below filter shall be registered as a default web filter, and thus
 * all the URL's even the excluded ones shall be intercepted by the below filter
 */
public JWTAuthenticationFilter authenticationTokenFilterBean() {
    return new JWTAuthenticationFilter();
}
Run Code Online (Sandbox Code Playgroud)


Art*_*nko 6

我们最近更新到 Spring Boot 3.0.0,它使用 Spring Security 6.0.0,并且在将过滤器应用于所有请求时遇到了类似的问题,尽管authorizeHttpRequests()使用了定义的特定路径。

事实证明,如果你想为特定路径配置,你需要在开始时HttpSecurity使用。securityMatcher()

所以它会是这样的:

private SecurityFilterChain configureFilterChain(HttpSecurity http, String pattern, String... roles) throws Exception {
    return http
               .securityMatcher(pattern)
               .authorizeHttpRequests(auth -> auth.requestMatchers(AntPathRequestMatcher.antMatcher(pattern)).hasAnyRole(roles))
               .addFilterBefore(new TokenFilter(), UsernamePasswordAuthenticationFilter.class)
               .sessionManagement()
                   .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                   .and()
               .exceptionHandling()
                   .authenticationEntryPoint(new AuthenticationEntryPointImpl())
                   .accessDeniedHandler(new AccessDeniedHandlerImpl())
                   .and()
               .csrf().disable()
               .build();
}
Run Code Online (Sandbox Code Playgroud)

因此在这种情况下,TokenFilter将仅应用于具有 this 的请求pattern


Saš*_*jak 5

GenericFilterBean 有以下方法:

/**
     * Can be overridden in subclasses for custom filtering control,
     * returning {@code true} to avoid filtering of the given request.
     * <p>The default implementation always returns {@code false}.
     * @param request current HTTP request
     * @return whether the given request should <i>not</i> be filtered
     * @throws ServletException in case of errors
     */
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

因此,在扩展的过滤器中,GenericFilterBean您可以覆盖该方法并实现逻辑以仅在您想要的路由上运行过滤器。

  • 我似乎在 javadoc 中找不到这个。你确定这个存在吗?编辑:我发现它已移至“OncePerRequestFilter”,但感谢您指出正确的方向 (3认同)