春季安全工作仅适用于最高优先级的订单

Bib*_*kya 2 java spring spring-security spring-boot

我正在尝试将 spring mvc 集成到现有的 spring rest 项目中。春季休息的安全性工作正常。当我尝试以最低优先级顺序为 spring mvc 实现安全性时,它仅适用于 rest api。如果我为 spring mvc 设置了高优先级,那么它将适用于 spring mvc,但对于 rest api,它将重定向到登录页面。

这是我的代码片段

//base class for spring security config
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig 
Run Code Online (Sandbox Code Playgroud)

我有两个静态类

用于弹簧 mvc

@Configuration
@EnableWebSecurity
@Order(1)
public static class SecurityConfig extends WebSecurityConfigurerAdapter
Run Code Online (Sandbox Code Playgroud)

用于休息 api

@Configuration
@EnableWebSecurity
@Order(2)
public static class ApiSecurity extends WebSecurityConfigurerAdapter
Run Code Online (Sandbox Code Playgroud)

对于 spring mvc 配置

@Override
protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/admin/login")
                .defaultSuccessUrl("/admin/home",true)

                .permitAll()
                .and()
                .logout()
                .permitAll();
}
Run Code Online (Sandbox Code Playgroud)

对于 Rest api 配置

@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .cors()
                .and()
                // we don't need CSRF because our token is invulnerable
                .csrf().disable()

                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

                // don't create session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

                .authorizeRequests()

                // Un-secure H2 Database
                .antMatchers("/h2-console/**/**").permitAll()

                .antMatchers("/auth/**").permitAll()
                .antMatchers("/refresh/**").permitAll()

                .antMatchers("/facebook/**").permitAll()
                .antMatchers("/admin/**").permitAll()
                .antMatchers("/v2/api-docs",
                        "/configuration/ui",
                        "/swagger-resources",
                        "/configuration/security",
                        "/swagger-ui.html").permitAll()
                .anyRequest().authenticated();

        // Custom JWT based security filter
        JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
        httpSecurity
                .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        // disable page caching
        httpSecurity
                .headers()
                .frameOptions().sameOrigin()  // required to set for H2 else H2 Console will be blank.
                .cacheControl();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // AuthenticationTokenFilter will ignore the below paths
        web
                .ignoring()
                .antMatchers(
                        HttpMethod.POST,
                        authenticationPath)
                .antMatchers(HttpMethod.POST,
                        refresh)
                // allow anonymous resource requests
                .and()
                .ignoring()
                .antMatchers(
                        HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/*.js",
                        "/*.*.*",
                        "/**/**/*.*",
                        "/favicon.ico",
                        "/v2/api-docs",
                        "/configuration/ui",
                        "/swagger-resources",
                        "/configuration/security",
                        "/swagger-ui.html",
                        "/resources/**",
                        "/static/**"
                )

                // Un-secure H2 Database (for testing purposes, H2 console shouldn't be unprotected in production)
                .and()
                .ignoring()
                .antMatchers("/h2-console/**/**");
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
        configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
}
Run Code Online (Sandbox Code Playgroud)

Ken*_*han 6

每个WebSecurityConfigurerAdapter基本上配置一个SecurityFilterChain默认情况下将处理所有 HTTP 请求。

当有多个 时SecurityFilterChain,它会SecurityFilterChain按照优先级顺序逐个检查,并使用第一个可以处理请求的。

由于两者SecurityFilterChain都配置为处理所有 HTTP 请求,因此SecurityFilterChain始终使用具有较高优先级的顺序。

因此,只需SecurityFilterChain将 API更改为具有更高的优先级,并将其配置为处理以 API 端点开头的 URL:

@Configuration
@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class ApiSecurity extends WebSecurityConfigurerAdapter{

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**");
            //continue configure http ......
        }

}
Run Code Online (Sandbox Code Playgroud)