升级Spring Boot 2.7.5后WebSecurity配置失效求助
Spring Boot 2.7.5升级后SecurityFilterChain未生效问题
升级Spring Boot到2.7.5版本时,WebSecurityConfigurerAdapter被弃用,按照文档修改为SecurityFilterChain Bean后,自定义的filterChain方法未被调用,原本仅验证请求头Bearer Token的逻辑失效,系统自动启用了用户名/密码认证。
修改前代码(Spring Boot 2.2.3)
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) class SecurityConfiguration : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { val tokenTypes: List<TokenType> = mapper.readValue(jsonTokenTypes, Array<TokenType>::class.java).toList() http.csrf().disable() .authorizeRequests() .antMatchers("/graphql").permitAll() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore( AuthFilter.create(keySet, tokenTypes), RequestHeaderAuthenticationFilter::class.java ) } }
修改后代码(Spring Boot 2.7.5)
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) class SecurityConfiguration() { @Value("${vehicle.op.jwk.key-set}") private lateinit var keySet: List<String> @Value("${vehicle.op.jwt.token-types}") private lateinit var jsonTokenTypes: String protected val mapper = jacksonObjectMapper() @Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { val tokenTypes: List<TokenType> = mapper.readValue(jsonTokenTypes, Array<TokenType>::class.java).toList() http.csrf().disable() .authorizeRequests() .antMatchers("/graphql").permitAll() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore( AuthFilter.create(keySet, tokenTypes), RequestHeaderAuthenticationFilter::class.java ) return http.build() } }
应用启动日志
13:22:33: Executing 'bootRun -Dspring.profiles.active=homolog'... > Task :checkApolloVersions UP-TO-DATE > Task :generateMainServiceApolloSources NO-SOURCE > Task :compileKotlin UP-TO-DATE > Task :compileJava NO-SOURCE > Task :processResources UP-TO-DATE > Task :classes UP-TO-DATE > Task :bootRunMainClassName UP-TO-DATE > Task :bootRun __ __ _ _ ___________ | \/ | ___ | |__ (_)___ \ \ \ \ | |\/| |/ _ \| '_ \| | / / \ \ \ \ | | | | (_) | |_) | | / / ) ) ) ) |_| |_|\___/|_.__/|_|/_/ / / / / ===========================/_/_/_/ :: my_application :: (vlatest) 2022-12-06 13:22:37.312 INFO 29076 --- [ main] i.company.op.vehicle.VehicleApplicationKt : Starting VehicleApplicationKt using Java 11.0.16 on DESKTOP-07SSK0A with PID 29076 (C:\company\GitHub\my_application\build\classes\kotlin\main started by admin in C:\company\GitHub\my_application) 2022-12-06 13:22:37.316 INFO 29076 --- [ main] i.company.op.vehicle.VehicleApplicationKt : No active profile set, falling back to 1 default profile: "default" 2022-12-06 13:22:37.816 INFO 29076 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2022-12-06 13:22:37.883 INFO 29076 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 62 ms. Found 4 JPA repository interfaces. 2022-12-06 13:22:38.065 INFO 29076 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=c811da27-aff3-39ab-b4ee-d6bb20987e72 2022-12-06 13:22:38.602 INFO 29076 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9090 (http) 2022-12-06 13:22:38.611 INFO 29076 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-12-06 13:22:38.612 INFO 29076 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.68] 2022-12-06 13:22:38.718 INFO 29076 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-12-06 13:22:38.719 INFO 29076 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1351 ms 2022-12-06 13:22:38.872 INFO 29076 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2022-12-06 13:22:39.037 INFO 29076 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2022-12-06 13:22:39.507 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT COUNT(*) FROM public.liq_db_changelog_lock 2022-12-06 13:22:39.519 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT COUNT(*) FROM public.liq_db_changelog_lock 2022-12-06 13:22:39.520 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT LOCKED FROM public.liq_db_changelog_lock WHERE ID=1 2022-12-06 13:22:39.533 INFO 29076 --- [ main] l.lockservice.StandardLockService : Successfully acquired change log lock 2022-12-06 13:22:39.545 INFO 29076 --- [ main] liquibase.changelog.DatabaseChangeLog : Reading resource: db/changelog/202210050955-changelog.sql 2022-12-06 13:22:39.552 INFO 29076 --- [ main] liquibase.changelog.DatabaseChangeLog : Reading resource: db/changelog/202210051005-changelog.sql 2022-12-06 13:22:39.561 INFO 29076 --- [ main] liquibase.changelog.DatabaseChangeLog : Reading resource: db/changelog/202210141724-changelog.sql 2022-12-06 13:22:39.569 INFO 29076 --- [ main] liquibase.changelog.DatabaseChangeLog : Reading resource: db/changelog/202210310837-changelog.sql 2022-12-06 13:22:39.653 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT MD5SUM FROM public.liq_db_changelog WHERE MD5SUM IS NOT NULL LIMIT 1 2022-12-06 13:22:39.657 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT COUNT(*) FROM public.liq_db_changelog 2022-12-06 13:22:39.659 INFO 29076 --- [ main] l.c.StandardChangeLogHistoryService : Reading from public.liq_db_changelog 2022-12-06 13:22:39.659 INFO 29076 --- [ main] liquibase.executor.jvm.JdbcExecutor : SELECT * FROM public.liq_db_changelog ORDER BY DATEEXECUTED ASC, ORDEREXECUTED ASC 2022-12-06 13:22:39.683 INFO 29076 --- [ main] l.lockservice.StandardLockService : Successfully released change log lock 2022-12-06 13:22:39.831 INFO 29076 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2022-12-06 13:22:39.911 INFO 29076 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.12.Final 2022-12-06 13:22:40.122 INFO 29076 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2022-12-06 13:22:40.242 INFO 29076 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL9Dialect 2022-12-06 13:22:40.651 INFO 29076 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2022-12-06 13:22:40.658 INFO 29076 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2022-12-06 13:22:42.695 INFO 29076 --- [ main] s.b.a.g.s.GraphQlWebMvcAutoConfiguration : GraphQL endpoint HTTP POST /graphql 2022-12-06 13:22:43.217 WARN 29076 --- [ main] .s.s.UserDetailsServiceAutoConfiguration : Using generated security password: 6e231318-c400-4c42-bb52-079a429bd04a This generated password is for development use only. Your security configuration must be updated before running your application in production. 2022-12-06 13:22:43.411 INFO 29076 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@4e92c6c2, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@71a18feb, org.springframework.security.web.context.SecurityContextPersistenceFilter@26aecf31, org.springframework.security.web.header.HeaderWriterFilter@693f9ab5, org.springframework.security.web.csrf.CsrfFilter@197d6cc9, org.springframework.security.web.authentication.logout.LogoutFilter@286f8e90, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@327fd5c9, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@3d1b6816, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@66032b8d, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@70a9f4b7, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1abacff3, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4a3d4cd2, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@7c1a5092, org.springframework.security.web.session.SessionManagementFilter@3f04847e, org.springframework.security.web.access.ExceptionTranslationFilter@76e56b17, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@169f4152] 2022-12-06 13:22:43.478 INFO 29076 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9090 (http) with context path '' 2022-12-06 13:22:43.488 INFO 29076 --- [ main] i.company.op.vehicle.VehicleApplicationKt : Started VehicleApplicationKt in 6.557 seconds (JVM running for 6.906)
问题原因及解决方案
从日志可见,Spring自动生成了默认安全密码并加载了默认SecurityFilterChain,说明自定义Bean未被正确识别加载,可从以下几点排查修复:
确保配置类被扫描:确认
SecurityConfiguration所在包在Spring组件扫描范围内,若不在主应用类同级/子包,需添加@ComponentScan指定路径。完善授权规则:原代码仅配置
/graphql允许匿名,未明确其他请求的授权逻辑,导致Spring启用默认认证。补充规则:http.authorizeRequests() .antMatchers("/graphql").permitAll() .anyRequest().authenticated()调整过滤器顺序:将自定义
AuthFilter放在UsernamePasswordAuthenticationFilter之前,确保Token验证优先执行:.addFilterBefore( AuthFilter.create(keySet, tokenTypes), UsernamePasswordAuthenticationFilter::class.java )检查Bean定义:确认
filterChain方法的@Bean注解正确,若存在多个SecurityFilterChainBean,需用@Order指定优先级。
修改后的完整配置示例:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) class SecurityConfiguration { @Value("${vehicle.op.jwk.key-set}") private lateinit var keySet: List<String> @Value("${vehicle.op.jwt.token-types}") private lateinit var jsonTokenTypes: String private val mapper = jacksonObjectMapper() @Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { val tokenTypes: List<TokenType> = mapper.readValue(jsonTokenTypes, Array<TokenType>::class.java).toList() http.csrf().disable() .authorizeRequests() .antMatchers("/graphql").permitAll() .anyRequest().authenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore( AuthFilter.create(keySet, tokenTypes), UsernamePasswordAuthenticationFilter::class.java ) return http.build() } }
内容的提问来源于stack exchange,提问作者George Alves
相关产品推荐
相关产品推荐

