我正在尝试使用嵌入式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)
答案 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);
}
}
}