我有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);
}
}
奇怪的是,当我为此使用单独的类时,一切都很好。