EmbeddedServletContainerFactory和TomcatEmbeddedServletContainerFactory创建defaultServletHandlerMapping错误

时间:2018-07-26 07:42:17

标签: spring security spring-boot

我有Spring Boot版本1.3.1。我在应用程序上配置了https,一切正常。但是现在我尝试将应用程序从http重定向到https。我使用我的SecurityConfig类。

@Configuration
@EnableWebSecurity
@ComponentScan("com.myApp.recproject.security")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {

private static final String ADMIN = "Admin";

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

@Autowired
private AuthSuccessHandler authSuccessHandler;

@Autowired
private AuthFailureHandler authFailureHandler;

@Autowired
private RestLogoutSuccessHandler restLogoutSuccessHandler;

@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
    return super.userDetailsServiceBean();
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Bean
public PasswordEncoder passwordencoder() {
    return new BCryptPasswordEncoder();
}

@Bean
public AuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService);
    authenticationProvider.setPasswordEncoder(passwordencoder());

    return authenticationProvider;
}

@Bean
public SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider());
}

@Bean
public DispatcherServlet dispatcherServlet() {
    DispatcherServlet servlet = new DispatcherServlet();
    servlet.setDispatchOptionsRequest(true);
    return servlet;
}

@Bean
@Primary
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
    TomcatEmbeddedServletContainerFactory tomcatContainerFactory  = new TomcatEmbeddedServletContainerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint constraint = new SecurityConstraint();
            constraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            constraint.addCollection(collection);
            context.addConstraint(constraint);
        }
    };
    tomcatContainerFactory.addAdditionalTomcatConnectors(createSslConnector());
    return tomcatContainerFactory;
}

private Connector createSslConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(8080);
    connector.setRedirectPort(8443);
    connector.setSecure(false);
    return connector;
}

public static ResponseEntity<Void> allows(HttpMethod... methods) {
    HttpHeaders headers = new HttpHeaders();
    Set<HttpMethod> allow = new HashSet<>();
    for (HttpMethod method : methods) {
        allow.add(method);
    }
    headers.setAllow(allow);

    return new ResponseEntity<>(headers, HttpStatus.NO_CONTENT);
}

@RequestMapping(method = RequestMethod.OPTIONS)
ResponseEntity<Void> getProposalsOptions() {
    return allows(HttpMethod.GET, HttpMethod.POST);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().csrfTokenRepository(csrfTokenRepository()).and()
            .authenticationProvider(authenticationProvider())
            .exceptionHandling()
            .authenticationEntryPoint(restAuthenticationEntryPoint)
            .and()
            .formLogin()
            .successHandler(authSuccessHandler)
            .failureHandler(authFailureHandler)
            .and()
            .logout()
            .logoutSuccessHandler(restLogoutSuccessHandler)
            .and()
            .sessionManagement()
            .maximumSessions(1).sessionRegistry(sessionRegistry());


    // static content
    http
            .authorizeRequests().and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class).authorizeRequests()
            .antMatchers(HttpMethod.GET, "/", "/styles/**", "/scripts/**", "/assets/**", "/api/metadata/**")
            .permitAll()
            .antMatchers(HttpMethod.POST, "/api/logout/**", "/api/login/**")
            .permitAll();

    http
            .authorizeRequests()

            .antMatchers(HttpMethod.GET, "/api/accounts", "/api/accounts/{\\id+}").hasAuthority(ADMIN) //AccountRestService
            .antMatchers(HttpMethod.GET, "/api/createIssue/**", "/api/showPreparedIssue/**").hasAuthority(ADMIN) //CreateIssueRestService
            .antMatchers(HttpMethod.GET, "/api/questionnaires/completed", "/api/questionnaires/accepted",  "/api/configuration/applicationLink").hasAuthority(ADMIN) //QuestionnaireRestService
            .antMatchers(HttpMethod.GET, "/api/configuration/sync").hasAuthority(ADMIN) //ConfigurationRestService
            .antMatchers(HttpMethod.GET, "/api/events/{\\id+}").hasAuthority(ADMIN) //EventRestService

            .antMatchers(HttpMethod.POST, "/api/accounts", "/api/accounts/postpone", "/api/account/inquireemail", "/api/account/credentials").hasAuthority(ADMIN) //AccountRestService
            .antMatchers(HttpMethod.POST, "/api/questionnaires/exported/**", "/api/questionnaires/accepted/**").hasAuthority(ADMIN) //QuestionnaireRestService
            .antMatchers(HttpMethod.POST, "/api/employers/{\\id+}", "/api/employers/accept/**", "/api/employers/unaccept/**", "/api/employers/accept/**", "/api/employers/unaccept/**").hasAuthority(ADMIN) //EmployerRestService
            .antMatchers(HttpMethod.POST, "/api/events/**", "/api/events").hasAuthority(ADMIN) //EventRestService
            .antMatchers(HttpMethod.POST, "/api/universities", "/api/universitymajors").hasAuthority(ADMIN) //JiraImportRestService
            .antMatchers(HttpMethod.POST, "/api/technologies/accept", "/api/technologies/unaccept", "/api/technologies/accept/**", "/api/technologies/unaccept/**").hasAuthority(ADMIN) //TechnologyRestService
            .antMatchers(HttpMethod.POST, "/api/detachfromevent/**").hasAuthority(ADMIN) //UserRestService

            .antMatchers(HttpMethod.PUT, "/api/accounts/{\\id+}").hasAuthority(ADMIN) //AccountRestService
            .antMatchers(HttpMethod.PUT, "/api/employers/{\\id+}").hasAuthority(ADMIN) //EmployerRestService
            .antMatchers(HttpMethod.PUT, "/api/events/{\\id+}").hasAuthority(ADMIN) //EventRestService
            .antMatchers(HttpMethod.PUT, "/api/universities/{\\id+}", "/api/universitymajors/{\\id+}").hasAuthority(ADMIN) //JiraImportRestService
            .antMatchers(HttpMethod.PUT, "/api/jobtypes/{\\id+}").hasAuthority(ADMIN) //JobTypeRestService
            .antMatchers(HttpMethod.PUT, "/api/technologies/{\\id+}").hasAuthority(ADMIN) //TechnologyRestService
            .antMatchers(HttpMethod.PUT, "/api/configuration/applicationLink").hasAuthority(ADMIN) //ConfigurationRestService

            .antMatchers(HttpMethod.DELETE, "/api/accounts/{\\id+}").hasAuthority(ADMIN) //AccountRestService
            .antMatchers(HttpMethod.DELETE, "/api/employers/{\\id+}").hasAuthority(ADMIN) //EmployerRestService
            .antMatchers(HttpMethod.DELETE, "/api/events/{\\id+}").hasAuthority(ADMIN) //EventRestService
            .antMatchers(HttpMethod.DELETE, "/api/jobtypes/{\\id+}").hasAuthority(ADMIN) //JobTypeRestService
            .antMatchers(HttpMethod.DELETE, "/api/technologies/{\\id+}").hasAuthority(ADMIN) //TechnologyRestService


            .antMatchers(HttpMethod.GET, "/api/accounts/{\\id+}").authenticated() //AccountRestService
            .antMatchers(HttpMethod.GET, "/api/currentQuestionnaire/**", "/api/questionnaires/{\\id+}").authenticated() //QuestionnaireRestService

            .antMatchers(HttpMethod.PUT, "/api/questionnaires/{\\id+}").authenticated() //QuestionnaireRestService


            .antMatchers(HttpMethod.GET, "/api/account/emailexists/**").permitAll() //AccountRestService
            .antMatchers(HttpMethod.GET, "/api/questionnaires/getCreationDate/**").permitAll() //QuestionnaireRestService
            .antMatchers(HttpMethod.GET, "/api/employers", "/api/employers/{\\id+}").permitAll() //EmployerRestService
            .antMatchers(HttpMethod.GET, "/api/positions/**").permitAll() //ParImportRestService
            .antMatchers(HttpMethod.GET, "/api/cities", "/api/universities", "/api/universitymajors").permitAll() //JiraImportRestService
            .antMatchers(HttpMethod.GET, "/api/events").permitAll() //EventRestService
            .antMatchers(HttpMethod.GET, "/api/jobtypes", "/api/jobtypes/{\\id+}").permitAll() //JobTypeRestService
            .antMatchers(HttpMethod.GET, "/api/technologies", "/api/technologies/{\\id+}").permitAll() //TechnologyRestService
            .antMatchers(HttpMethod.GET, "/fonts/**").permitAll()

            .antMatchers(HttpMethod.POST, "/api/account/confirm", "/api/account/inquireemail", "/api/account/credentials", "/api/account/postpone").permitAll() //AccountRestService
            .antMatchers(HttpMethod.POST, "/api/questionnaires","/api/questionnaires/{\\id+}", "/api/questionnaires/incomplete", "/api/uploadCV/**").permitAll() //QuestionnaireRestService
            .antMatchers(HttpMethod.POST, "/api/jobtypes/{\\id+}").permitAll() //JobTypeRestService
            .antMatchers(HttpMethod.POST, "/api/technologies/{\\id+}").permitAll() //TechnologyRestService

            .anyRequest().denyAll();
}

private CsrfTokenRepository csrfTokenRepository() {
    HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    return repository;
}

我仅添加:

@Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
    TomcatEmbeddedServletContainerFactory tomcatContainerFactory  = new TomcatEmbeddedServletContainerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint constraint = new SecurityConstraint();
            constraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            constraint.addCollection(collection);
            context.addConstraint(constraint);
        }
    };
    tomcatContainerFactory.addAdditionalTomcatConnectors(createSslConnector());
    return tomcatContainerFactory;
}

private Connector createSslConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(8080);
    connector.setRedirectPort(8443);
    connector.setSecure(false);
    return connector;
}

启动应用程序时出现此错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:764)
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:357)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)


Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)

Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:115)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:53)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:451)
at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$a6ecae32.CGLIB$defaultServletHandlerMapping$38(<generated>)
at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$a6ecae32$$FastClassBySpringCGLIB$$8a18a9eb.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:355)
at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$a6ecae32.defaultServletHandlerMapping(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)

这是我的SpringBootApplication注释类:

@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.MyApp.recproject.repository")
@EnableScheduling
public class RecprojectApplication {

public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(RecprojectApplication.class);
    springApplication.addListeners( new ApplicationPidFileWriter() );
    springApplication.run(args);
}

}

奇怪的是,当我为此使用单独的类时,一切都很好。

0 个答案:

没有答案