【发布时间】:2014-07-31 15:17:46
【问题描述】:
我正在尝试使用嵌入的 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:run 运行应用程序,我可以在日志中看到端口 80 已打开但没有 HTTPS 端口:-
2014-06-10 23:41:56.932 信息 196 --- [lication.main()] /
: 初始化 Spring FrameworkServlet 'dispatcherServlet' 2014-06-10 23:41:56.932 信息 196 --- [lication.main()] os.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet':初始化开始于 2014-06-10 23:41:56.960 信息 196 --- [lication.main()] os.web.servlet.DispatcherServlet
: FrameworkServlet 'dispatcherServlet': 初始化在 26 完成 毫秒 2014-06-10 23:41:57.037 信息 196 --- [lication.main()] o.e.jetty.server.AbstractConnector :已启动 SelectChannelConnector@0.0.0.0:80 2014-06-10 23:41:57.043 信息 196 --- [lication.main()] .s.b.c.e.j.JettyEmbeddedServletContainer:码头在端口开始: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)
【问题讨论】:
-
没有什么可以阻止您使用简单的
@Bean注释方法使其工作。尝试将该方法与内部类放在使用@EnableAutoConfiguration配置的@Configuration 类中。 -
将其移至使用 @EnableAutoConfiguration 注释的类已修复!
标签: https embedded-jetty spring-boot