Sping Boot Web应用程序
将其升级为以下设置:
- Java 17
- Sping Boot 3.0.4
- Spring Security 6.0.2
- Jetty 11服务器
当我启动应用程序时,我在控制台上看到这行:
Running with Spring Boot v3.0.4, Spring v6.0.6
我遇到了Spring安全配置的问题。
接下来是安全配置Java文件。
@Configuration
@Order(SecurityProperties.DEFAULT_FILTER_ORDER)
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSecurity
public class SecConfiguration {
private final HouseUserDetailsService customUserDetailsService;
private final HouseShiftConfiguration dashShiftConfig;
private final DBI dbi;
private final AuditLogService auditLogService;
@Autowired
private CustomSecurityconfiguration customSecurityConfiguration;
@Autowired
public SecConfiguration(HouseUserDetailsService customUserDetailsService, DBI dbi, HouseShiftConfiguration dashShiftConfig, AuditLogService auditLogService) {
this.customUserDetailsService = customUserDetailsService;
this.dbi = dbi;
this.dashShiftConfig = dashShiftConfig;
this.auditLogService = auditLogService;
}
@Bean
public HouseRedirectAuthenticationSuccessHandler houseRedirectAuthenticationSuccessHandler() {
return new HouseRedirectAuthenticationSuccessHandler(dbi);
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfiguration) throws Exception {
return authConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
requestCache.setMatchingRequestParameterName("continue");
CsrfTokenRequestAttributeHandler csrfRequestHandler = new CsrfTokenRequestAttributeHandler();
csrfRequestHandler.setCsrfRequestAttributeName("_csrf");// set the name of the attribute the CsrfToken will be populated on
XorCsrfTokenRequestAttributeHandler xorCsrfRequestHandler = new XorCsrfTokenRequestAttributeHandler();
xorCsrfRequestHandler.setCsrfRequestAttributeName("_csrf");// set the name of the attribute the CsrfToken will be populated on
//csrf white list, when you don't want to use csrf, put your url here.
String[] csrfWhiteList = {
"/emailSender/**"
};
http
.csrf((csrf) -> csrf.csrfTokenRequestHandler(csrfRequestHandler)).csrf((xorCsrf) -> xorCsrf.csrfTokenRequestHandler(xorCsrfRequestHandler)).csrf().ignoringRequestMatchers(csrfWhiteList)
.and()
.rememberMe().rememberMeServices(dashShiftConfig.tokenBasedRememberMeServicesCore())
.and()
.authorizeHttpRequests(auth -> auth.dispatcherTypeMatchers(DispatcherType.FORWARD/*, DispatcherType.INCLUDE, DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST*/).permitAll()
.requestMatchers("/accessDenied", "/security_check", "/img/*", "/js/*", "/css/*", "/?*", "/", "/login*").permitAll()
.anyRequest().permitAll())
.formLogin()
.loginPage("/")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/security_check")
.failureUrl("/?r=fail")
.failureHandler(HouseAuthFailureHandler())
.successHandler(HouseRedirectAuthenticationSuccessHandler())
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessHandler(customLogoutHandler())
.deleteCookies("JSESSIONID","rm")
.invalidateHttpSession(true)
.and()
.sessionManagement().invalidSessionUrl("/?r=invalidSessionUrlLogin")
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
http
.headers()
.frameOptions().disable()
.addHeaderWriter(new StaticHeadersWriter("X-FRAME-OPTIONS", "ALLOW-FROM https://www.secure-service.com"));
http
.headers()
.xssProtection(xssProtection -> xssProtection.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK))
.contentSecurityPolicy("form-action 'self'");
http.sessionManagement((sessions) -> sessions.requireExplicitAuthenticationStrategy(true /*it requires true */)).sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry()).expiredUrl("/?r=sessionExpiredDuplicateLogin");
return http.build();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(this.customUserDetailsService);
authProvider.setPasswordEncoder(customSecurityConfiguration.passwordEncoder());
return authProvider;
}
}
当我 Boot 应用程序时,我得到这个错误:
09/03/2023 16:07:37.344 [restartedMain] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization -
cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains'
parameter 0: Error creating bean with name 'filterChain' defined in class path resource [co/age/house/component/security/SecConfiguration.class]: Failed to
instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: Invalid configuration that explicitly
sets requireExplicitAuthenticationStrategy to true but implicitly requires it due to the following properties being set: [maximumSessions = 1, invalidSessionUrl = /?r=invalidSessionUrlLogin]
接下来是stacktrace:
09/03/2023 16:07:37.380 [restartedMain] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0: Error creating bean with name 'filterChain' defined in class path resource [co/age/house/component/security/SecConfiguration.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: Invalid configuration that explicitly sets requireExplicitAuthenticationStrategy to true but implicitly requires it due to the following properties being set: [maximumSessions = 1, invalidSessionUrl = /?r=invalidSessionUrlLogin]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:817)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:769)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'filterChain' defined in class path resource [co/age/house/component/security/SecConfiguration.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: Invalid configuration that explicitly sets requireExplicitAuthenticationStrategy to true but implicitly requires it due to the following properties being set: [maximumSessions = 1, invalidSessionUrl = /?r=invalidSessionUrlLogin]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:645)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
... 25 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: Invalid configuration that explicitly sets requireExplicitAuthenticationStrategy to true but implicitly requires it due to the following properties being set: [maximumSessions = 1, invalidSessionUrl = /?r=invalidSessionUrlLogin]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
... 41 common frames omitted
Caused by: java.lang.IllegalStateException: Invalid configuration that explicitly sets requireExplicitAuthenticationStrategy to true but implicitly requires it due to the following properties being set: [maximumSessions = 1, invalidSessionUrl = /?r=invalidSessionUrlLogin]
at org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer.shouldRequireExplicitAuthenticationStrategy(SessionManagementConfigurer.java:425)
at org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer.createSessionManagementFilter(SessionManagementConfigurer.java:435)
at org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer.configure(SessionManagementConfigurer.java:398)
at org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer.configure(SessionManagementConfigurer.java:107)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.configure(AbstractConfiguredSecurityBuilder.java:349)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:303)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:38)
此错误是由以下行引起的:
http.sessionManagement((sessions) -> sessions.requireExplicitAuthenticationStrategy(true /*it requires true */))
如果我将其设置回Spring Security 5.8 defaults,即为false:
http.sessionManagement((sessions) -> sessions.requireExplicitAuthenticationStrategy(false /*it requires true */))
我可以 Boot ,并运行网络应用程序就好了。
虽然我想坚持使用Spring Security v6配置,将其设置为true。
Spring文档是这样说的:
是否有解决方案(以便与Spring Security v6沿着使用)?
最好的问候
1条答案
按热度按时间xqkwcwgp1#
我的项目也有同样的问题
我从spring文档中了解到的是,我们必须在更改上下文时显式地保存它。
你可以看到这个问题的答案Auto login after registration Spring Boot 3/Spring security 6,看看如何保存它。我在我的项目上测试过,效果很好