我有以下代码:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authz) -> authz
.requestMatchers("/actuator/**").permitAll()
.requestMatchers("/h2-console/**").permitAll()
.anyRequest().authenticated()
);
http.csrf(AbstractHttpConfigurer::disable);
http.headers((headers) -> headers
.frameOptions((frame) -> frame
.disable()
)
);
return http.build();
}
字符串
但是当我尝试访问h2-console端点时,我收到一个403错误:
curl -v http://localhost:8080/h2-console
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
...
* Mark bundle as not supporting multiuse
< HTTP/1.1 403
型
如果我将authenticated修改为permitAll,即.anyRequest().permitAll()
,它的功能完全正常。
如何配置代码以限制对h2-console及其所有子路径的访问,但阻止对所有其他路径的访问?
更新
根据建议,我尝试了这个...
@Configuration
public class AppConfig {
private static RequestMatcher h2ConsoleRequestMatcher() {
return new RequestMatcher() {
@Override
public boolean matches(HttpServletRequest request) {
String path = request.getServletPath();
return path.startsWith("/h2-console");
}
};
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// TODO: 2021-10-13 - remove permitAll() and add proper security
http.authorizeHttpRequests((authz) -> authz
.requestMatchers("/actuator/**").permitAll()
.requestMatchers("/h2-console/**").permitAll()
.anyRequest().authenticated()
);
http.csrf((csrf) ->
csrf.ignoringRequestMatchers(h2ConsoleRequestMatcher())
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
http.headers((headers) -> headers
.frameOptions(
HeadersConfigurer.FrameOptionsConfig::disable
)
);
return http.build();
}
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowCredentials(true);
corsConfig.addAllowedOrigin("http://localhost:3000");
corsConfig.addAllowedHeader("*");
corsConfig.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
型
但我还是拿到了403...
curl http://localhost:8080/h2-console -v
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /h2-console HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.87.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403
型
感谢下面接受的答案这里是最终的工作版本
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authz) -> authz
.requestMatchers(new AntPathRequestMatcher("/actuator/**")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**")).permitAll()
.anyRequest().authenticated()
);
http.csrf((csrf) ->
csrf.ignoringRequestMatchers(new AntPathRequestMatcher("/h2-console/**"))
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
http.headers((headers) -> headers
.frameOptions(
HeadersConfigurer.FrameOptionsConfig::disable
)
);
return http.build();
}
型
2条答案
按热度按时间bcs8qyzn1#
默认情况下,
requestMatchers("a_string_path")
将Map到MvcRequestMatcher
如果HandlerMappingIntrospector在类路径中可用,则Map到不关心使用哪个HttpMethod的MvcRequestMatcher。这个匹配器将使用Spring MVC用于匹配的相同规则。例如,路径**"/path”的Map经常会匹配"/path”、“/path/"、"/path.html”**等。如果HandlerMappingIntrospector不可用,则Map到AntPathRequestMatcher。如果必须指定特定的RequestMatcher,请使用requestMatchers(RequestMatcher...)代替Params:模式-要匹配的模式。如果使用MvcRequestMatcher,则匹配规则由Spring MVC定义返回:创建RequestMatcher后链接的对象。自:5.8
因此,要使用自己的Servlet访问h2-console,需要使用AntPathRequestMatcher
这应该可以工作:
字符串
另一种方法是提供一个额外的WebSecurityCustomizer bean。
型
yquaqz182#
发生此行为是因为默认的Spring Security配置包括针对CSRF攻击的保护,并且/h2-console端点受此保护的影响。启用CSRF保护时,对/h2控制台端点的请求需要包含有效的CSRF令牌。
要解决此问题,您可以配置Spring Security以使/h2-console端点免受CSRF保护。
将其添加到SecurityFilterChain中以禁用csrf:
字符串