Spring Boot Sping Boot 3安全性无法访问H2控制台- 403

e0bqpujr  于 2023-02-16  发布在  Spring
关注(0)|答案(1)|浏览(257)

我正在重新学习Sping Boot 3中的Spring安全性。事情发生了一些变化,由于某种原因,用于WebSecurityConfigurerAdapter的配置方法的相同设置在SecurityFilterChain中不起作用。
以下是以前设置中的一些代码-正在运行

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final AppUserService userService;
    private final PasswordEncoder bCryptPasswordEncoder;

    public SecurityConfig(AppUserService userService, PasswordEncoder bCryptPasswordEncoder) {
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    private static final String[] SWAGGER = {
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**",
            "/v3/api-docs/**",
            "/swagger-ui/**"
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.cors(c -> {
            CorsConfigurationSource cs = request -> {
                CorsConfiguration cc = new CorsConfiguration();
                cc.setAllowedOrigins(List.of("*"));
                cc.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
                cc.setAllowedHeaders(List.of("Origin", "Content-Type", "X-Auth-Token", "Access-Control-Expose-Header",
                        "Authorization"));
                cc.addExposedHeader("Authorization");
                cc.addExposedHeader("User-Name");
                return cc;
            };
            c.configurationSource(cs);
        });
        http.headers().frameOptions().disable();
        http.sessionManagement().sessionCreationPolicy(STATELESS);
        http.authorizeRequests().antMatchers("/login/**").permitAll();
        http.authorizeRequests().antMatchers("/h2-console/**").permitAll();
        http.authorizeRequests().antMatchers(SWAGGER).permitAll();
        http.authorizeRequests().antMatchers("/users/password-reset-request").permitAll();
        http.authorizeRequests().antMatchers("/users/password-change").permitAll();
        http.authorizeRequests().antMatchers("/users/**").hasAnyAuthority("ADMIN");
        http.authorizeRequests().antMatchers("/favorites/**").hasAnyAuthority("USER");
        http.authorizeRequests().antMatchers(GET).hasAnyAuthority("USER");
        http.authorizeRequests().antMatchers(POST).hasAnyAuthority("USER");
        http.authorizeRequests().antMatchers(PUT).hasAnyAuthority("USER");
        http.authorizeRequests().antMatchers(DELETE).hasAnyAuthority("MODERATOR");
        http.authorizeRequests().anyRequest().authenticated();
        http.addFilter(new CustomAuthenticationFilter(authenticationManager()));
        http.addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected UserDetailsService userDetailsService() {
        return userService;
    }
}

现在

WebSecurityConfigurerAdapter

不再可用:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.headers().frameOptions().disable();
        http.sessionManagement().sessionCreationPolicy(STATELESS);
        http.authorizeHttpRequests().requestMatchers("/h2-console/**").permitAll();
        http.authorizeHttpRequests().requestMatchers("/auth/**").permitAll();
        http.authorizeHttpRequests().anyRequest().authenticated();
        http.authenticationProvider(authenticationProvider);
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

长话短说-以前工作过

http.headers().frameOptions().disable();
http.authorizeRequests().antMatchers("/h2-console/**").permitAll();

不会作为

http.headers().frameOptions().disable();
http.authorizeHttpRequests().requestMatchers("/h2-console/**").permitAll();

Application.properties 数据库的www.example.com是完全相同的,复制的。我没有更改H2的默认URL。似乎是Spring Security挡了路。
请指点该怎么办。
您是否知道自上一次Sping Boot 以来H2设置是否发生了任何变化?
编辑:如果我只是简单的http.authorizeHttpRequests().anyRequest().permitAll();,控制台就可以工作了。它必须是安全相关的

hiz5n14c

hiz5n14c1#

H2的Web控制台使用H2ConsoleAutoConfiguration will registerServlet,因此,需要使用servletPath属性才能使用MvcRequestMatcher,如下所示:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) {
    // ...
    MvcRequestMatcher h2RequestMatcher = new MvcRequestMatcher(introspector, "/**");
    h2RequestMatcher.setServletPath("/h2-console");
    http.authorizeHttpRequests((authorize) -> authorize
        .requestMatchers(h2RequestMatcher).permitAll()
        // ...
    );
}

总之,我们允许h2-console servlet路径下的每个(/**)请求。
另一种选择是使用Sping Boot H2 Console文档中所示的PathRequest.toH2Console(),这反过来会为您创建一个AntPathRequestMatcher

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) {
    // ...
    http.authorizeHttpRequests((authorize) -> authorize
        .requestMatchers(PathRequest.toH2Console()).permitAll()
        // ...
    );
}

此问题也已在项目的存储库中得到解答

相关问题