英文:
How to configure custom security filters to trigger only for specific endpoints in a Spring Boot application with Spring Security?
问题
以下是您提供的内容的翻译:
我有一个使用Spring Boot 3和Spring Security 6的应用程序,我很难理解安全过滤器是如何工作的。
我目前有3个公开的端点/endpoint1
,/endpoint2
和/endpoint3
。我还有两个过滤器Filter1.java
和Filter2.java
。
我想要配置我的安全性,以便仅在调用/endpoint1
时触发Filter1
,仅在调用/endpoint2
时触发Filter2
,而对于/endpoint3
则不触发任何过滤器。
我得到的结果是,在调用任何端点时,两个过滤器都被触发。
这是我的SecurityFilterChain
配置方法:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoin3/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/error/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoint1/**"))
.authenticated()
.requestMatchers(new AntPathRequestMatcher("/endpoint2/**"))
.authenticated()
.anyRequest()
.denyAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(
new Filter1(),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(
new Filter2(),
UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
return http.build();
}
我尝试了以下方法,但没有任何差异:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoin3/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/error/**"))
.permitAll()
.and()
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/endpoint1/**"))
.authenticated()
.and()
.addFilterBefore(
new Filter1(),
UsernamePasswordAuthenticationFilter.class))
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/endpoint2/**"))
.authenticated()
.and()
.addFilterBefore(
new Filter2(),
UsernamePasswordAuthenticationFilter.class))
.authorizeHttpRequests()
.anyRequest()
.denyAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout()
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
return http.build();
}
我尝试搜索解决此问题的答案,但只找到了针对Spring Boot 2
使用antMatchers()
方法的解决方案,但由于Spring Security 6
的原因,它在Spring Boot 3
中已被弃用。
我还尝试使用@Bean
和@Order
注解在多个SecurityFilterChain
上创建多个过滤器,但过滤器停止在所有端点上触发。
请让我知道如果您需要更多的帮助或有其他问题。
英文:
I have a spring boot 3 application with spring security 6. I am having a hard time to understand how security filters work.
I have for the moment 3 exposed endpoint /endpoint1
, /endpoint2
and /endpoint3
. I also have 2 filters Filter1.java
and Filter2.java
.
I want to configure my Security in a way that Filter1
only gets triggered when /endpoint1
is called, Filter2
only when /endpoint2
gets called, and for /endpoint3
no filter at all.
The outcome I am getting is that both filters are getting triggered when calling any of the endpoints.
This is my SecurityFilterChain
configure method:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoin3/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/error/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoint1/**"))
.authenticated()
.requestMatchers(new AntPathRequestMatcher("/endpoint2/**"))
.authenticated()
.anyRequest()
.denyAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(
new Filter1(),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(
new Filter2(),
UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
return http.build();
}
I tried to do the following but it did make any difference:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/endpoin3/**"))
.permitAll()
.requestMatchers(new AntPathRequestMatcher("/error/**"))
.permitAll()
.and()
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/endpoint1/**"))
.authenticated()
.and()
.addFilterBefore(
new Filter1(),
UsernamePasswordAuthenticationFilter.class))
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/endpoint2/**"))
.authenticated()
.and()
.addFilterBefore(
new Filter2(),
UsernamePasswordAuthenticationFilter.class))
.authorizeHttpRequests()
.anyRequest()
.denyAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout()
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
return http.build();
}
}
I have searched to find an answer to my issue but only found found solutions for Spring boot 2
using antMatchers()
methods but it is depricated in Spring Boot 3
because of Spring security 6
.
I also tried to create multiple SecurityFilterChain
s with @Bean
and @Order
annotations on top of them but the filters stoped being triggered on all endpoints.
答案1
得分: 1
这是正确的。antMatchers()
方法已被弃用。您可以尝试创建两个自定义请求匹配器(用于端点1和2)。然后,您可以在两个单独的配置类中(可以自己选择类名),使用这些匹配器来定义每个端点的具体性。这可能有助于触发适用于正确端点的过滤器。
// 自定义请求匹配器用于端点路径
private static final RequestMatcher ENDPOINT_1_MATCHER = new AntPathRequestMatcher("/endpoint1/**");
private static final RequestMatcher ENDPOINT_2_MATCHER = new AntPathRequestMatcher("/endpoint2/**");
// 端点1的配置
@Configuration
public static class Endpoint1SecurityFilter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.requestMatcher(ENDPOINT_1_MATCHER)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
// 端点2的配置
@Configuration
public static class Endpoint2SecurityFilter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.requestMatcher(ENDPOINT_2_MATCHER)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
PS:对于端点3,我真的不认为需要明确配置过滤器的缺失,因为它不需要任何过滤器。欢迎更好的建议!
英文:
That is true. antMatchers()
method is deprecated. Could you try creating two custom request matchers(for endpoint 1 and 2). You can then use those matchers in two separate configuration classes(any class name of choice) where you’d define your specificity for each endpoint. This might help you trigger your filters for the right endpoints.
// Custom request matchers for endpoint paths
private static final RequestMatcher ENDPOINT_1_MATCHER = new AntPathRequestMatcher("/endpoint1/**");
private static final RequestMatcher ENDPOINT_2_MATCHER = new AntPathRequestMatcher("/endpoint2/**");
// Configuration for endpoint 1
@Configuration
public static class Endpoint1SecurityFilter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.requestMatcher(ENDPOINT_1_MATCHER)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
// endpoint 2 configuration
@Configuration
public static class Endpoint2SecurityFilter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.requestMatcher(ENDPOINT_2_MATCHER)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
} ```
PS: I honestly don’t feel it is necessary to explicitly configure the absence of filters for endpoint3 since it doesn’t require any filters.
Open to better suggestions here!
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论