Spring Boot JettyServerCustomizer | HTTPS端口未打开|需要ServletContext来配置默认的servlet处理

时间:2014-06-10 18:14:34

标签: https embedded-jetty spring-boot

我正在尝试使用嵌入式Spring Boot。我希望嵌入式Jetty在443打开HTTPS端口。

在提到here发布的答案后,我想出了这个配置: -

import java.io.FileNotFoundException;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.util.ResourceUtils;

import com.samsoft.expunto.service.UserService;

/**
 * @author Kumar Sambhav Jain
 * 
 */
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests().antMatchers("/", "/resources/**")
                .permitAll().anyRequest().authenticated().and().formLogin()
                .loginPage("/").defaultSuccessUrl("/home", false).and()
                .requiresChannel().anyRequest().requiresSecure().and().logout()
                .invalidateHttpSession(true).logoutUrl("/logout")
                .logoutSuccessUrl("/").and().userDetailsService(userService);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
    }

    @Bean
    public JettyServerCustomizer jettyCutomizer() {
        return new JettyServerCustomizer() {

            @Override
            public void customize(Server server) {
                SslContextFactory sslContextFactory = new SslContextFactory();
                sslContextFactory.setKeyStorePassword("jetty6");
                try {
                    sslContextFactory.setKeyStorePath(ResourceUtils.getFile(
                            "classpath:jetty-ssl.keystore").getAbsolutePath());
                } catch (FileNotFoundException ex) {
                    throw new IllegalStateException("Could not load keystore",
                            ex);
                }
                SslSocketConnector sslConnector = new SslSocketConnector(
                        sslContextFactory);
                sslConnector.setPort(443);
                sslConnector.setMaxIdleTime(60000);
                server.addConnector(sslConnector);
            }
        };
    }
}

尝试使用spring-boot运行应用程序:运行,我可以在日志中看到端口80已打开但没有HTTPS端口: -

  

2014-06-10 23:41:56.932 INFO 196 --- [lication.main()] /
  :初始化Spring FrameworkServlet'dispatcherServlet'2014-06-10   23:41:56.932 INFO 196 --- [lication.main()]   o.s.web.servlet.DispatcherServlet:FrameworkServlet   'dispatcherServlet':初始化开始2014-06-10 23:41:56.960   INFO 196 --- [lication.main()] o.s.web.servlet.DispatcherServlet
  :FrameworkServlet'dispatcherServlet':初始化完成于26   ms 2014-06-10 23:41:57.037 INFO 196 --- [lication.main()]   o.e.jetty.server.AbstractConnector:已开始   SelectChannelConnector@0.0.0.0:80 2014-06-10 23:41:57.043 INFO 196   --- [lication.main()] .s.b.c.e.j.JettyEmbeddedServletContainer:Jetty在端口上启动:80 2014-06-10 23:41:57.045 INFO 196 ---   [lication.main()] c.s.expunto.web.config.Application:已启动   应用程序在7.628秒(JVM运行16.509)

更新


使用此配置: -

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
        implements EmbeddedServletContainerCustomizer {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests().antMatchers("/", "/resources/**")
                .permitAll().anyRequest().authenticated().and().formLogin()
                .loginPage("/").defaultSuccessUrl("/home", false).and()
                .requiresChannel().anyRequest().requiresSecure().and().logout()
                .invalidateHttpSession(true).logoutUrl("/logout")
                .logoutSuccessUrl("/").and().userDetailsService(userService);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
    }

    public JettyServerCustomizer jettyServerCustomizer() {
        return new JettyServerCustomizer() {

            @Override
            public void customize(Server server) {
                SslContextFactory sslContextFactory = new SslContextFactory();
                sslContextFactory.setKeyStorePassword("jetty6");
                try {
                    sslContextFactory.setKeyStorePath(ResourceUtils.getFile(
                            "classpath:jetty-ssl.keystore").getAbsolutePath());
                } catch (FileNotFoundException ex) {
                    throw new IllegalStateException("Could not load keystore",
                            ex);
                }
                SslSocketConnector sslConnector = new SslSocketConnector(
                        sslContextFactory);
                sslConnector.setPort(443);
                sslConnector.setMaxIdleTime(60000);
                server.addConnector(sslConnector);
            }
        };
    }

    public void customizeJetty(
            JettyEmbeddedServletContainerFactory containerFactory) {
        containerFactory.addServerCustomizers(jettyServerCustomizer());
    }

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        if (container instanceof JettyEmbeddedServletContainerFactory) {
            customizeJetty((JettyEmbeddedServletContainerFactory) container);
        }
        container.setContextPath("");
    }
}

我收到此错误: -

: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:346)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7014349.CGLIB$defaultServletHandlerMapping$24(<generated>)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7014349$$FastClassBySpringCGLIB$$ec8be680.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7014349.defaultServletHandlerMapping(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)

1 个答案:

答案 0 :(得分:1)

根据M. Deinum的建议,将定制器移动到使用@EnableAutoConfiguration注释的类可以解决问题。

这对我有用: -

@Configuration

@EnableAutoConfiguration
public class Application implements EmbeddedServletContainerCustomizer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Bean
    public JettyServerCustomizer jettyServerCustomizer() {
        return new JettyServerCustomizer() {

            @Override
            public void customize(Server server) {
                SslContextFactory sslContextFactory = new SslContextFactory();
                sslContextFactory.setKeyStorePassword("jetty6");
                try {
                    sslContextFactory.setKeyStorePath(ResourceUtils.getFile(
                            "classpath:jetty-ssl.keystore").getAbsolutePath());
                } catch (FileNotFoundException ex) {
                    throw new IllegalStateException("Could not load keystore",
                            ex);
                }
                SslSocketConnector sslConnector = new SslSocketConnector(
                        sslContextFactory);
                sslConnector.setPort(443);
                sslConnector.setMaxIdleTime(60000);
                server.addConnector(sslConnector);
            }
        };
    }

    public void customizeJetty(
            JettyEmbeddedServletContainerFactory containerFactory) {
        containerFactory.addServerCustomizers(jettyServerCustomizer());
    }

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        if (container instanceof JettyEmbeddedServletContainerFactory) {
            customizeJetty((JettyEmbeddedServletContainerFactory) container);
        }
    }
}