Spring Boot 在Sping Boot v3.0.4下,显式将requireExplicitAuthenticationStrategy设置为true但隐式要求它的配置无效

ogq8wdun  于 2023-05-06  发布在  Spring
关注(0)|答案(1)|浏览(132)

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沿着使用)?
最好的问候

xqkwcwgp

xqkwcwgp1#

我的项目也有同样的问题
我从spring文档中了解到的是,我们必须在更改上下文时显式地保存它。
你可以看到这个问题的答案Auto login after registration Spring Boot 3/Spring security 6,看看如何保存它。我在我的项目上测试过,效果很好

相关问题